1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.resources; 18 19 20 import java.util.ArrayList; 21 import java.util.Collections; 22 import java.util.HashMap; 23 import java.util.List; 24 import java.util.Map; 25 26 /** 27 * This class gives access to the bidirectional relationship between {@link ResourceType} and 28 * {@link ResourceFolderType}. 29 */ 30 public final class FolderTypeRelationship { 31 32 private final static Map<ResourceType, List<ResourceFolderType>> mTypeToFolderMap = 33 new HashMap<ResourceType, List<ResourceFolderType>>(); 34 35 private final static Map<ResourceFolderType, List<ResourceType>> mFolderToTypeMap = 36 new HashMap<ResourceFolderType, List<ResourceType>>(); 37 38 static { 39 // generate the relationships in a temporary map 40 add(ResourceType.ANIM, ResourceFolderType.ANIM); 41 add(ResourceType.ANIMATOR, ResourceFolderType.ANIMATOR); 42 add(ResourceType.ARRAY, ResourceFolderType.VALUES); 43 add(ResourceType.ATTR, ResourceFolderType.VALUES); 44 add(ResourceType.BOOL, ResourceFolderType.VALUES); 45 add(ResourceType.COLOR, ResourceFolderType.VALUES); 46 add(ResourceType.COLOR, ResourceFolderType.COLOR); 47 add(ResourceType.DECLARE_STYLEABLE, ResourceFolderType.VALUES); 48 add(ResourceType.DIMEN, ResourceFolderType.VALUES); 49 add(ResourceType.DRAWABLE, ResourceFolderType.VALUES); 50 add(ResourceType.DRAWABLE, ResourceFolderType.DRAWABLE); 51 add(ResourceType.FRACTION, ResourceFolderType.VALUES); 52 add(ResourceType.ID, ResourceFolderType.VALUES); 53 add(ResourceType.INTEGER, ResourceFolderType.VALUES); 54 add(ResourceType.INTERPOLATOR, ResourceFolderType.INTERPOLATOR); 55 add(ResourceType.LAYOUT, ResourceFolderType.LAYOUT); 56 add(ResourceType.ID, ResourceFolderType.LAYOUT); 57 add(ResourceType.MENU, ResourceFolderType.MENU); 58 add(ResourceType.ID, ResourceFolderType.MENU); 59 add(ResourceType.MIPMAP, ResourceFolderType.MIPMAP); 60 add(ResourceType.PLURALS, ResourceFolderType.VALUES); 61 add(ResourceType.PUBLIC, ResourceFolderType.VALUES); 62 add(ResourceType.RAW, ResourceFolderType.RAW); 63 add(ResourceType.STRING, ResourceFolderType.VALUES); 64 add(ResourceType.STYLE, ResourceFolderType.VALUES); 65 add(ResourceType.STYLEABLE, ResourceFolderType.VALUES); 66 add(ResourceType.XML, ResourceFolderType.XML); 67 68 makeSafe(); 69 } 70 71 /** 72 * Returns a list of {@link ResourceType}s that can be generated from files inside a folder 73 * of the specified type. 74 * @param folderType The folder type. 75 * @return a list of {@link ResourceType}, possibly empty but never null. 76 */ 77 public static List<ResourceType> getRelatedResourceTypes(ResourceFolderType folderType) { 78 List<ResourceType> list = mFolderToTypeMap.get(folderType); 79 if (list != null) { 80 return list; 81 } 82 83 return Collections.emptyList(); 84 } 85 86 /** 87 * Returns a list of {@link ResourceFolderType} that can contain files generating resources 88 * of the specified type. 89 * @param resType the type of resource. 90 * @return a list of {@link ResourceFolderType}, possibly empty but never null. 91 */ 92 public static List<ResourceFolderType> getRelatedFolders(ResourceType resType) { 93 List<ResourceFolderType> list = mTypeToFolderMap.get(resType); 94 if (list != null) { 95 return list; 96 } 97 98 return Collections.emptyList(); 99 } 100 101 /** 102 * Returns true if the {@link ResourceType} and the {@link ResourceFolderType} values match. 103 * @param resType the resource type. 104 * @param folderType the folder type. 105 * @return true if files inside the folder of the specified {@link ResourceFolderType} 106 * could generate a resource of the specified {@link ResourceType} 107 */ 108 public static boolean match(ResourceType resType, ResourceFolderType folderType) { 109 List<ResourceFolderType> list = mTypeToFolderMap.get(resType); 110 111 if (list != null) { 112 return list.contains(folderType); 113 } 114 115 return false; 116 } 117 118 /** 119 * Adds a {@link ResourceType} - {@link ResourceFolderType} relationship. this indicates that 120 * a file in the folder can generate a resource of the specified type. 121 * @param type The resourceType 122 * @param folder The {@link ResourceFolderType} 123 */ 124 private static void add(ResourceType type, ResourceFolderType folder) { 125 // first we add the folder to the list associated with the type. 126 List<ResourceFolderType> folderList = mTypeToFolderMap.get(type); 127 if (folderList == null) { 128 folderList = new ArrayList<ResourceFolderType>(); 129 mTypeToFolderMap.put(type, folderList); 130 } 131 if (folderList.indexOf(folder) == -1) { 132 folderList.add(folder); 133 } 134 135 // now we add the type to the list associated with the folder. 136 List<ResourceType> typeList = mFolderToTypeMap.get(folder); 137 if (typeList == null) { 138 typeList = new ArrayList<ResourceType>(); 139 mFolderToTypeMap.put(folder, typeList); 140 } 141 if (typeList.indexOf(type) == -1) { 142 typeList.add(type); 143 } 144 } 145 146 /** 147 * Makes the maps safe by replacing the current list values with unmodifiable lists. 148 */ 149 private static void makeSafe() { 150 for (ResourceType type : ResourceType.values()) { 151 List<ResourceFolderType> list = mTypeToFolderMap.get(type); 152 if (list != null) { 153 // replace with a unmodifiable list wrapper around the current list. 154 mTypeToFolderMap.put(type, Collections.unmodifiableList(list)); 155 } 156 } 157 158 for (ResourceFolderType folder : ResourceFolderType.values()) { 159 List<ResourceType> list = mFolderToTypeMap.get(folder); 160 if (list != null) { 161 // replace with a unmodifiable list wrapper around the current list. 162 mFolderToTypeMap.put(folder, Collections.unmodifiableList(list)); 163 } 164 } 165 } 166 } 167