LayoutXmlProcessor.java revision 890b4850c628f04eb75397e427ba7074e4f9c386
18e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount/* 28e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * Copyright (C) 2015 The Android Open Source Project 38e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 48e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * you may not use this file except in compliance with the License. 58e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * You may obtain a copy of the License at 68e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * http://www.apache.org/licenses/LICENSE-2.0 78e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * Unless required by applicable law or agreed to in writing, software 88e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * distributed under the License is distributed on an "AS IS" BASIS, 98e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 108e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * See the License for the specific language governing permissions and 118e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * limitations under the License. 128e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount */ 138e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 14fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool; 158e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 1697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarimport org.apache.commons.lang3.StringEscapeUtils; 178e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport org.xml.sax.SAXException; 188e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.BindingBuildInfo; 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.LayoutFileParser; 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.ResourceBundle; 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.writer.JavaFileWriter; 23a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 248e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.io.File; 258e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.io.FilenameFilter; 268e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.io.IOException; 278e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.io.StringWriter; 28a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.ArrayList; 298e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.util.List; 308e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.util.UUID; 318e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 328e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.JAXBContext; 338e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.JAXBException; 348e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.Marshaller; 358e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.parsers.ParserConfigurationException; 368e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.xpath.XPathExpressionException; 378e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 388e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount/** 398e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * Processes the layout XML, stripping the binding attributes and elements 408e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * and writes the information into an annotated class file for the annotation 418e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * processor to work with. 428e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount */ 438e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountpublic class LayoutXmlProcessor { 44a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // hardcoded in baseAdapters 45fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount public static final String RESOURCE_BUNDLE_PACKAGE = "android.databinding.layouts"; 46a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public static final String CLASS_NAME = "DataBindingInfo"; 478e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private final JavaFileWriter mFileWriter; 488e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private final ResourceBundle mResourceBundle; 4997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar private final int mMinSdk; 5097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 518e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private boolean mProcessingComplete; 528e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private boolean mWritten; 53a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private final boolean mIsLibrary; 548e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private final String mBuildId = UUID.randomUUID().toString(); 55a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // can be a list of xml files or folders that contain XML files 56a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private final List<File> mResources; 57890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar private OriginalFileLookup mOriginalFileLookup; 588e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 59a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public LayoutXmlProcessor(String applicationPackage, List<File> resources, 60a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar JavaFileWriter fileWriter, int minSdk, boolean isLibrary) { 618e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount mFileWriter = fileWriter; 628e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount mResourceBundle = new ResourceBundle(applicationPackage); 63a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mResources = resources; 6497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar mMinSdk = minSdk; 65a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mIsLibrary = isLibrary; 66a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 67a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 68890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar public void setOriginalFileLookup(OriginalFileLookup originalFileLookup) { 69890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar mOriginalFileLookup = originalFileLookup; 70890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar } 71890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar 72a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public static List<File> getLayoutFiles(List<File> resources) { 73a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar List<File> result = new ArrayList<File>(); 740c2ed0cbaee2f206e926bfc780b05e9f1e52b551Yigit Boyar for (File resource : resources) { 750c2ed0cbaee2f206e926bfc780b05e9f1e52b551Yigit Boyar if (!resource.exists() || !resource.canRead()) { 760c2ed0cbaee2f206e926bfc780b05e9f1e52b551Yigit Boyar continue; 770c2ed0cbaee2f206e926bfc780b05e9f1e52b551Yigit Boyar } 78a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (resource.isDirectory()) { 79a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (File layoutFolder : resource.listFiles(layoutFolderFilter)) { 80a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (File xmlFile : layoutFolder.listFiles(xmlFileFilter)) { 81a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar result.add(xmlFile); 82a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 83a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 84a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 85a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } else if (xmlFileFilter.accept(resource.getParentFile(), resource.getName())) { 86a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar result.add(resource); 87a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 88a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 89a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return result; 90a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 91a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 92a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar /** 93a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * used by the studio plugin 94a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar */ 95a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public ResourceBundle getResourceBundle() { 96a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return mResourceBundle; 978e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 988e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 994d4979490e1fa374c0d7f3599fed0a9e83a579d0George Mount public boolean processResources(int minSdk) 1008e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount throws ParserConfigurationException, SAXException, XPathExpressionException, 1018e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount IOException { 1028e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (mProcessingComplete) { 1038e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return false; 1048e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1058e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount LayoutFileParser layoutFileParser = new LayoutFileParser(); 106a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (File xmlFile : getLayoutFiles(mResources)) { 107a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar final ResourceBundle.LayoutFileBundle bindingLayout = layoutFileParser 108890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar .parseXml(xmlFile, mResourceBundle.getAppPackage(), mOriginalFileLookup); 109a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (bindingLayout != null && !bindingLayout.isEmpty()) { 1100390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount mResourceBundle.addLayoutBundle(bindingLayout); 1118e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1128e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1138e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount mProcessingComplete = true; 1148e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return true; 1158e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1168e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 117be83770af82294c1841eef414513653646b88dc6Yigit Boyar public void writeLayoutInfoFiles(File xmlOutDir) throws JAXBException { 1188e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (mWritten) { 1198e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return; 1208e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1218e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount JAXBContext context = JAXBContext.newInstance(ResourceBundle.LayoutFileBundle.class); 1228e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount Marshaller marshaller = context.createMarshaller(); 123be83770af82294c1841eef414513653646b88dc6Yigit Boyar 1248e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount for (List<ResourceBundle.LayoutFileBundle> layouts : mResourceBundle.getLayoutBundles() 1258e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount .values()) { 1268e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount for (ResourceBundle.LayoutFileBundle layout : layouts) { 127a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar writeXmlFile(xmlOutDir, layout, marshaller); 1288e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1298e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1308e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount mWritten = true; 1318e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1328e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 133a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private void writeXmlFile(File xmlOutDir, ResourceBundle.LayoutFileBundle layout, 134a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar Marshaller marshaller) throws JAXBException { 135a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar String filename = generateExportFileName(layout) + ".xml"; 136a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar String xml = toXML(layout, marshaller); 137a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mFileWriter.writeToFile(new File(xmlOutDir, filename), xml); 138a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 139a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 140a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public String getInfoClassFullName() { 141a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return RESOURCE_BUNDLE_PACKAGE + "." + CLASS_NAME; 142a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 143a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 144a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private String toXML(ResourceBundle.LayoutFileBundle layout, Marshaller marshaller) 1458e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount throws JAXBException { 146a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar StringWriter writer = new StringWriter(); 147a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar marshaller.marshal(layout, writer); 148a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return writer.getBuffer().toString(); 149a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 150a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 151a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar /** 152a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * Generates a string identifier that can uniquely identify the given layout bundle. 153a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * This identifier can be used when we need to export data about this layout bundle. 154a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar */ 15530cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount public String generateExportFileName(ResourceBundle.LayoutFileBundle layout) { 156a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar StringBuilder name = new StringBuilder(layout.getFileName()); 157a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar name.append('-').append(layout.getDirectory()); 158a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (int i = name.length() - 1; i >= 0; i--) { 159a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar char c = name.charAt(i); 1608e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (c == '-') { 161a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar name.deleteCharAt(i); 162a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar c = Character.toUpperCase(name.charAt(i)); 163a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar name.setCharAt(i, c); 1648e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1658e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 166a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return name.toString(); 1678e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1688e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 169b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar public void writeInfoClass(/*Nullable*/ File sdkDir, File xmlOutDir, 170b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar /*Nullable*/ File exportClassListTo) { 17108119ea342cb47910ca80ff646d746f00e4663ceYigit Boyar writeInfoClass(sdkDir, xmlOutDir, exportClassListTo, false, false); 172b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar } 173b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar 174b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar public void writeInfoClass(/*Nullable*/ File sdkDir, File xmlOutDir, File exportClassListTo, 17508119ea342cb47910ca80ff646d746f00e4663ceYigit Boyar boolean enableDebugLogs, boolean printEncodedErrorLogs) { 176ee7586713d68806b556a425cbebf007a56261ff3Yigit Boyar final String sdkPath = sdkDir == null ? null : StringEscapeUtils.escapeJava(sdkDir.getAbsolutePath()); 177a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar final Class annotation = BindingBuildInfo.class; 178a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar final String layoutInfoPath = StringEscapeUtils.escapeJava(xmlOutDir.getAbsolutePath()); 179b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar final String exportClassListToPath = exportClassListTo == null ? "" : 180b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar StringEscapeUtils.escapeJava(exportClassListTo.getAbsolutePath()); 181a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar String classString = "package " + RESOURCE_BUNDLE_PACKAGE + ";\n\n" + 182a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "import " + annotation.getCanonicalName() + ";\n\n" + 183a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "@" + annotation.getSimpleName() + "(buildId=\"" + mBuildId + "\", " + 184a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "modulePackage=\"" + mResourceBundle.getAppPackage() + "\", " + 185ae161289a90f6ac69ffe6411ac8c09653c81d04dYigit Boyar "sdkRoot=" + "\"" + (sdkPath == null ? "" : sdkPath) + "\"," + 186a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "layoutInfoDir=\"" + layoutInfoPath + "\"," + 187b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar "exportClassListTo=\"" + exportClassListToPath + "\"," + 188a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "isLibrary=" + mIsLibrary + "," + 189b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar "minSdk=" + mMinSdk + "," + 19008119ea342cb47910ca80ff646d746f00e4663ceYigit Boyar "enableDebugLogs=" + enableDebugLogs + "," + 19108119ea342cb47910ca80ff646d746f00e4663ceYigit Boyar "printEncodedError=" + printEncodedErrorLogs + ")\n" + 192a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "public class " + CLASS_NAME + " {}\n"; 193fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount mFileWriter.writeToFile(RESOURCE_BUNDLE_PACKAGE + "." + CLASS_NAME, classString); 1948e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1958e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 196a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private static final FilenameFilter layoutFolderFilter = new FilenameFilter() { 1978e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount @Override 1988e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount public boolean accept(File dir, String name) { 1998e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return name.startsWith("layout"); 2008e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2018e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount }; 2028e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 203a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private static final FilenameFilter xmlFileFilter = new FilenameFilter() { 2048e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount @Override 2058e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount public boolean accept(File dir, String name) { 2068e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return name.toLowerCase().endsWith(".xml"); 2078e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2088e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount }; 209890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar 210890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar /** 211890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar * Helper interface that can find the original copy of a resource XML. 212890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar */ 213890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar public interface OriginalFileLookup { 214890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar 215890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar /** 216890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar * @param file The intermediate build file 217890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar * @return The original file or null if original File cannot be found. 218890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar */ 219890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar File getOriginalFileFor(File file); 220890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar } 2218e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount} 222