1 /* 2 * Copyright (C) 2022 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 package com.android.ide.common.resources.deprecated; 17 18 import com.android.ide.common.rendering.api.DensityBasedResourceValueImpl; 19 import com.android.ide.common.rendering.api.ResourceNamespace; 20 import com.android.ide.common.rendering.api.ResourceReference; 21 import com.android.ide.common.rendering.api.ResourceValue; 22 import com.android.ide.common.rendering.api.ResourceValueImpl; 23 import com.android.ide.common.resources.configuration.DensityQualifier; 24 import com.android.ide.common.resources.configuration.ResourceQualifier; 25 import com.android.io.IAbstractFile; 26 import com.android.resources.FolderTypeRelationship; 27 import com.android.resources.ResourceType; 28 import com.android.utils.SdkUtils; 29 30 import java.util.List; 31 32 33 import static com.android.SdkConstants.DOT_XML; 34 35 /** 36 * @deprecated This class is part of an obsolete resource repository system that is no longer used 37 * in production code. The class is preserved temporarily for LayoutLib tests. 38 */ 39 @Deprecated 40 public class SingleResourceFile extends ResourceFile { 41 private final String mResourceName; 42 private final ResourceType mType; 43 private final ResourceValue mValue; 44 SingleResourceFile(TestFileWrapper file, ResourceFolder folder)45 public SingleResourceFile(TestFileWrapper file, ResourceFolder folder) { 46 super(file, folder); 47 48 // we need to infer the type of the resource from the folder type. 49 // This is easy since this is a single Resource file. 50 List<ResourceType> types = FolderTypeRelationship.getRelatedResourceTypes(folder.getType()); 51 mType = types.get(0); 52 53 // compute the resource name 54 mResourceName = getResourceName(); 55 56 // test if there's a density qualifier associated with the resource 57 DensityQualifier qualifier = folder.getConfiguration().getDensityQualifier(); 58 59 if (!ResourceQualifier.isValid(qualifier)) { 60 mValue = 61 new ResourceValueImpl( 62 new ResourceReference( 63 ResourceNamespace.fromBoolean(isFramework()), 64 mType, 65 getResourceName()), 66 file.getOsLocation()); 67 } else { 68 mValue = 69 new DensityBasedResourceValueImpl( 70 new ResourceReference( 71 ResourceNamespace.fromBoolean(isFramework()), 72 mType, 73 getResourceName()), 74 file.getOsLocation(), 75 qualifier.getValue()); 76 } 77 } 78 79 @Override load(ScanningContext context)80 protected void load(ScanningContext context) { 81 // get a resource item matching the given type and name 82 ResourceItem item = getRepository().getResourceItem(mType, mResourceName); 83 84 // add this file to the list of files generating this resource item. 85 item.add(this); 86 87 // Ask for an ID refresh since we're adding an item that will generate an ID 88 context.requestFullAapt(); 89 } 90 91 @Override update(ScanningContext context)92 protected void update(ScanningContext context) { 93 // when this happens, nothing needs to be done since the file only generates 94 // a single resources that doesn't actually change (its content is the file path) 95 96 // However, we should check for newly introduced errors 97 // Parse the file and look for @+id/ entries 98 validateAttributes(context); 99 } 100 101 /* 102 * (non-Javadoc) 103 * @see com.android.ide.eclipse.editors.resources.manager.ResourceFile#getValue(com.android.ide.eclipse.common.resources.ResourceType, java.lang.String) 104 * 105 * This particular implementation does not care about the type or name since a 106 * SingleResourceFile represents a file generating only one resource. 107 * The value returned is the full absolute path of the file in OS form. 108 */ 109 @Override getValue(ResourceType type, String name)110 public ResourceValue getValue(ResourceType type, String name) { 111 return mValue; 112 } 113 114 /** 115 * Returns the name of the resources. 116 */ getResourceName()117 private String getResourceName() { 118 // get the name from the filename. 119 String name = getFile().getName(); 120 121 int pos = name.indexOf('.'); 122 if (pos != -1) { 123 name = name.substring(0, pos); 124 } 125 126 return name; 127 } 128 129 /** 130 * Validates the associated resource file to make sure the attribute references are valid 131 * 132 * @return true if parsing succeeds and false if it fails 133 */ validateAttributes(ScanningContext context)134 private boolean validateAttributes(ScanningContext context) { 135 // We only need to check if it's a non-framework file (and an XML file; skip .png's) 136 if (!isFramework() && SdkUtils.endsWith(getFile().getName(), DOT_XML)) { 137 ValidatingResourceParser parser = new ValidatingResourceParser(context, false); 138 try { 139 IAbstractFile file = getFile(); 140 return parser.parse(file.getContents()); 141 } catch (Exception e) { 142 context.needsFullAapt(); 143 } 144 145 return false; 146 } 147 148 return true; 149 } 150 } 151