/** * Returns the list of source files for a given resource. Optionally, if a {@link * FolderConfiguration} is given, then only the best match for this config is returned. * * @param type the type of the resource. * @param name the name of the resource. * @param referenceConfig an optional config for which only the best match will be returned. * @return a list of files generating this resource or null if it was not found. */ @Nullable public List<ResourceFile> getSourceFiles( @NonNull ResourceType type, @NonNull String name, @Nullable FolderConfiguration referenceConfig) { ensureInitialized(); Collection<ResourceItem> items = getResourceItemsOfType(type); for (ResourceItem item : items) { if (name.equals(item.getName())) { if (referenceConfig != null) { Configurable match = referenceConfig.findMatchingConfigurable(item.getSourceFileList()); if (match instanceof ResourceFile) { return Collections.singletonList((ResourceFile) match); } return null; } return item.getSourceFileList(); } } return null; }
@Override public void valueChanged(@Nullable TreeSelectionEvent e) { Component selectedComponent = myContentPanel.getSelectedComponent(); if (selectedComponent == myColorPickerPanel) { Color color = myColorPicker.getColor(); myNewResourceAction.setEnabled(false); myResultResourceName = ResourceHelper.colorToString(color); updateResourceNameStatus(); } else { boolean isProjectPanel = selectedComponent == myProjectPanel.myComponent; ResourcePanel panel = isProjectPanel ? myProjectPanel : mySystemPanel; ResourceItem element = getSelectedElement(panel.myTreeBuilder, ResourceItem.class); setOKActionEnabled(element != null); myNewResourceAction.setEnabled( isProjectPanel && !panel.myTreeBuilder.getSelectedElements().isEmpty()); if (element == null) { myResultResourceName = null; } else { String prefix = panel == myProjectPanel ? "@" : ANDROID; myResultResourceName = prefix + element.getName(); } panel.showPreview(element); } notifyResourcePickerListeners(myResultResourceName); }
protected void removeFile(@NonNull ResourceType type, @NonNull ResourceFile file) { Map<String, ResourceItem> map = mResourceMap.get(type); if (map != null) { Collection<ResourceItem> values = map.values(); List<ResourceItem> toDelete = null; for (ResourceItem item : values) { item.removeFile(file); if (item.hasNoSourceFile()) { if (toDelete == null) { toDelete = new ArrayList<ResourceItem>(values.size()); } toDelete.add(item); } } if (toDelete != null) { for (ResourceItem item : toDelete) { map.remove(item.getName()); } } } }
/** * Returns a map of (resource name, resource value) for the given {@link ResourceType}. * * <p>The values returned are taken from the resource files best matching a given {@link * FolderConfiguration}. * * @param type the type of the resources. * @param referenceConfig the configuration to best match. */ @NonNull private Map<String, ResourceValue> getConfiguredResource( @NonNull ResourceType type, @NonNull FolderConfiguration referenceConfig) { // get the resource item for the given type Map<String, ResourceItem> items = mResourceMap.get(type); if (items == null) { return new HashMap<String, ResourceValue>(); } // create the map HashMap<String, ResourceValue> map = new HashMap<String, ResourceValue>(items.size()); for (ResourceItem item : items.values()) { ResourceValue value = item.getResourceValue(type, referenceConfig, isFrameworkRepository()); if (value != null) { map.put(item.getName(), value); } } return map; }
/** * Returns a {@link ResourceItem} matching the given {@link ResourceType} and name. If none exist, * it creates one. * * @param type the resource type * @param name the name of the resource. * @return A resource item matching the type and name. */ @NonNull public ResourceItem getResourceItem(@NonNull ResourceType type, @NonNull String name) { ensureInitialized(); // looking for an existing ResourceItem with this type and name ResourceItem item = findDeclaredResourceItem(type, name); // create one if there isn't one already, or if the existing one is inlined, since // clearly we need a non inlined one (the inline one is removed too) if (item == null || item.isDeclaredInline()) { ResourceItem oldItem = item != null && item.isDeclaredInline() ? item : null; item = createResourceItem(name); Map<String, ResourceItem> map = mResourceMap.get(type); if (map == null) { if (isFrameworkRepository()) { // Pick initial size for the maps. Also change the load factor to 1.0 // to avoid rehashing the whole table when we (as expected) get near // the known rough size of each resource type map. int size; switch (type) { // Based on counts in API 16. Going back to API 10, the counts // are roughly 25-50% smaller (e.g. compared to the top 5 types below // the fractions are 1107 vs 1734, 831 vs 1508, 895 vs 1255, // 733 vs 1064 and 171 vs 783. case PUBLIC: size = 1734; break; case DRAWABLE: size = 1508; break; case STRING: size = 1255; break; case ATTR: size = 1064; break; case STYLE: size = 783; break; case ID: size = 347; break; case DECLARE_STYLEABLE: size = 210; break; case LAYOUT: size = 187; break; case COLOR: size = 120; break; case ANIM: size = 95; break; case DIMEN: size = 81; break; case BOOL: size = 54; break; case INTEGER: size = 52; break; case ARRAY: size = 51; break; case PLURALS: size = 20; break; case XML: size = 14; break; case INTERPOLATOR: size = 13; break; case ANIMATOR: size = 8; break; case RAW: size = 4; break; case MENU: size = 2; break; case MIPMAP: size = 2; break; case FRACTION: size = 1; break; default: size = 2; } map = new HashMap<String, ResourceItem>(size, 1.0f); } else { map = new HashMap<String, ResourceItem>(); } mResourceMap.put(type, map); } map.put(item.getName(), item); if (oldItem != null) { map.remove(oldItem.getName()); } } return item; }