LayoutXmlProcessor.java revision 4ba16229a40e9758db86d4fb1df5119fdcb8aa2a
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 164ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Guptaimport com.google.common.escape.Escaper; 174ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Gupta 189784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyarimport org.apache.commons.io.FileUtils; 198e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport org.xml.sax.SAXException; 208e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.BindingBuildInfo; 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.LayoutFileParser; 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.ResourceBundle; 249784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyarimport android.databinding.tool.util.Preconditions; 254ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Guptaimport android.databinding.tool.util.SourceCodeEscapers; 26fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.writer.JavaFileWriter; 27a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 288e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.io.File; 298e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.io.FilenameFilter; 308e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.io.IOException; 319784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyarimport java.net.URI; 32a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.ArrayList; 338e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.util.List; 348e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport java.util.UUID; 358e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 368e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.JAXBException; 378e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.parsers.ParserConfigurationException; 388e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.xpath.XPathExpressionException; 398e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 408e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount/** 418e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * Processes the layout XML, stripping the binding attributes and elements 428e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * and writes the information into an annotated class file for the annotation 438e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount * processor to work with. 448e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount */ 458e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountpublic class LayoutXmlProcessor { 46a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // hardcoded in baseAdapters 47fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount public static final String RESOURCE_BUNDLE_PACKAGE = "android.databinding.layouts"; 48a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public static final String CLASS_NAME = "DataBindingInfo"; 498e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private final JavaFileWriter mFileWriter; 508e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private final ResourceBundle mResourceBundle; 5197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar private final int mMinSdk; 5297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 538e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private boolean mProcessingComplete; 548e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private boolean mWritten; 55a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private final boolean mIsLibrary; 568e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount private final String mBuildId = UUID.randomUUID().toString(); 579784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private final OriginalFileLookup mOriginalFileLookup; 588e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 599784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public LayoutXmlProcessor(String applicationPackage, 609784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar JavaFileWriter fileWriter, int minSdk, boolean isLibrary, 619784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar OriginalFileLookup originalFileLookup) { 628e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount mFileWriter = fileWriter; 638e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount mResourceBundle = new ResourceBundle(applicationPackage); 6497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar mMinSdk = minSdk; 65a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mIsLibrary = isLibrary; 669784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mOriginalFileLookup = originalFileLookup; 67a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 68a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 699784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private static void processIncrementalInputFiles(ResourceInput input, 709784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar ProcessFileCallback callback) 719784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar throws IOException, ParserConfigurationException, XPathExpressionException, 729784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar SAXException { 739784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar processExistingIncrementalFiles(input.getRootInputFolder(), input.getAdded(), callback); 749784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar processExistingIncrementalFiles(input.getRootInputFolder(), input.getChanged(), callback); 759784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar processRemovedIncrementalFiles(input.getRootInputFolder(), input.getRemoved(), callback); 76890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar } 77890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar 789784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private static void processExistingIncrementalFiles(File inputRoot, List<File> files, 799784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar ProcessFileCallback callback) 809784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar throws IOException, XPathExpressionException, SAXException, 819784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar ParserConfigurationException { 829784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar for (File file : files) { 839784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar File parent = file.getParentFile(); 849784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (inputRoot.equals(parent)) { 859784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processOtherRootFile(file); 869784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else if (layoutFolderFilter.accept(parent, parent.getName())) { 879784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processLayoutFile(file); 889784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else { 899784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processOtherFile(parent, file); 900c2ed0cbaee2f206e926bfc780b05e9f1e52b551Yigit Boyar } 919784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 929784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 939784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 949784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private static void processRemovedIncrementalFiles(File inputRoot, List<File> files, 959784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar ProcessFileCallback callback) 969784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar throws IOException { 979784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar for (File file : files) { 989784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar File parent = file.getParentFile(); 999784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (inputRoot.equals(parent)) { 1009784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processRemovedOtherRootFile(file); 1019784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else if (layoutFolderFilter.accept(parent, parent.getName())) { 1029784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processRemovedLayoutFile(file); 1039784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else { 1049784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processRemovedOtherFile(parent, file); 1059784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1069784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1079784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 108a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 1099784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private static void processAllInputFiles(ResourceInput input, ProcessFileCallback callback) 1109784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar throws IOException, XPathExpressionException, SAXException, 1119784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar ParserConfigurationException { 1129784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar FileUtils.deleteDirectory(input.getRootOutputFolder()); 1139784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar Preconditions.check(input.getRootOutputFolder().mkdirs(), "out dir should be re-created"); 1149784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar Preconditions.check(input.getRootInputFolder().isDirectory(), "it must be a directory"); 1159784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar for (File firstLevel : input.getRootInputFolder().listFiles()) { 1169784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (firstLevel.isDirectory()) { 1179784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (layoutFolderFilter.accept(firstLevel, firstLevel.getName())) { 1189784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processLayoutFolder(firstLevel); 1199784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar for (File xmlFile : firstLevel.listFiles(xmlFileFilter)) { 1209784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processLayoutFile(xmlFile); 1219784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1229784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else { 1239784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processOtherFolder(firstLevel); 1249784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar for (File file : firstLevel.listFiles()) { 1259784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processOtherFile(firstLevel, file); 1269784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 127a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 1289784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else { 1299784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar callback.processOtherRootFile(firstLevel); 130a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 1319784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 132a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 133a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 134a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 135a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar /** 136a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * used by the studio plugin 137a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar */ 138a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public ResourceBundle getResourceBundle() { 139a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return mResourceBundle; 1408e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1418e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 1429784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public boolean processResources(final ResourceInput input) 1438e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount throws ParserConfigurationException, SAXException, XPathExpressionException, 1448e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount IOException { 1458e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (mProcessingComplete) { 1468e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return false; 1478e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1489784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar final LayoutFileParser layoutFileParser = new LayoutFileParser(); 1499784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar final URI inputRootUri = input.getRootInputFolder().toURI(); 1509784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar ProcessFileCallback callback = new ProcessFileCallback() { 1519784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private File convertToOutFile(File file) { 1529784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar final String subPath = toSystemDependentPath(inputRootUri 1539784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar .relativize(file.toURI()).getPath()); 1549784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return new File(input.getRootOutputFolder(), subPath); 1559784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1569784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar @Override 1579784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void processLayoutFile(File file) 1589784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar throws ParserConfigurationException, SAXException, XPathExpressionException, 1599784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar IOException { 1609784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar File output = convertToOutFile(file); 1619784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar final ResourceBundle.LayoutFileBundle bindingLayout = layoutFileParser 1629784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar .parseXml(file, output, mResourceBundle.getAppPackage(), mOriginalFileLookup); 1639784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (bindingLayout != null && !bindingLayout.isEmpty()) { 1649784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mResourceBundle.addLayoutBundle(bindingLayout); 1659784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1669784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1679784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 1689784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar @Override 1699784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void processOtherFile(File parentFolder, File file) throws IOException { 1709784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar File outParent = convertToOutFile(parentFolder); 1719784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar FileUtils.copyFile(file, new File(outParent, file.getName())); 1729784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1739784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 1749784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar @Override 1759784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void processRemovedLayoutFile(File file) { 1769784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mResourceBundle.addRemovedFile(file); 1778e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1789784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 1799784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar @Override 1809784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void processRemovedOtherFile(File parentFolder, File file) throws IOException { 1819784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar File outParent = convertToOutFile(parentFolder); 1829784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar FileUtils.forceDelete(new File(outParent, file.getName())); 1839784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1849784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 1859784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar @Override 1869784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void processOtherFolder(File folder) { 1879784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar //noinspection ResultOfMethodCallIgnored 1889784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar convertToOutFile(folder).mkdirs(); 1899784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1909784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 1919784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar @Override 1929784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void processLayoutFolder(File folder) { 1939784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar //noinspection ResultOfMethodCallIgnored 1949784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar convertToOutFile(folder).mkdirs(); 1959784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 1969784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 1979784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar @Override 1989784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void processOtherRootFile(File file) throws IOException { 1999784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar File outFile = convertToOutFile(file); 2009784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (file.isDirectory()) { 2019784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar FileUtils.copyDirectory(file, outFile); 2029784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else { 2039784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar FileUtils.copyFile(file, outFile); 2049784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2059784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2069784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 2079784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar @Override 2089784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void processRemovedOtherRootFile(File file) throws IOException { 2099784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar final File outFile = convertToOutFile(file); 2109784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (file.isDirectory()) { 2119784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar FileUtils.deleteDirectory(outFile); 2129784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else { 2139784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar FileUtils.deleteQuietly(outFile); 2149784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2159784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2169784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar }; 2179784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (input.isIncremental()) { 2189784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar processIncrementalInputFiles(input, callback); 2199784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } else { 2209784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar processAllInputFiles(input, callback); 2218e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2228e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount mProcessingComplete = true; 2238e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return true; 2248e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2258e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 2269784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public static String toSystemDependentPath(String path) { 2279784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar if (File.separatorChar != '/') { 2289784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar path = path.replace('/', File.separatorChar); 2299784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2309784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return path; 2319784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2329784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 233be83770af82294c1841eef414513653646b88dc6Yigit Boyar public void writeLayoutInfoFiles(File xmlOutDir) throws JAXBException { 2348e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (mWritten) { 2358e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return; 2368e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2378e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount for (List<ResourceBundle.LayoutFileBundle> layouts : mResourceBundle.getLayoutBundles() 2388e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount .values()) { 2398e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount for (ResourceBundle.LayoutFileBundle layout : layouts) { 24028e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar writeXmlFile(xmlOutDir, layout); 2418e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2428e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2439784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar for (File file : mResourceBundle.getRemovedFiles()) { 2449784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar String exportFileName = generateExportFileName(file); 2459784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar FileUtils.deleteQuietly(new File(xmlOutDir, exportFileName)); 2469784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2478e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount mWritten = true; 2488e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2498e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 25028e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar private void writeXmlFile(File xmlOutDir, ResourceBundle.LayoutFileBundle layout) 25128e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar throws JAXBException { 2529784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar String filename = generateExportFileName(layout); 25328e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar mFileWriter.writeToFile(new File(xmlOutDir, filename), layout.toXML()); 254a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 255a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 256a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public String getInfoClassFullName() { 257a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return RESOURCE_BUNDLE_PACKAGE + "." + CLASS_NAME; 258a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 259a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 260a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar /** 261a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * Generates a string identifier that can uniquely identify the given layout bundle. 262a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * This identifier can be used when we need to export data about this layout bundle. 263a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar */ 2649784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private static String generateExportFileName(ResourceBundle.LayoutFileBundle layout) { 2659784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return generateExportFileName(layout.getFileName(), layout.getDirectory()); 2669784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2679784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 2689784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private static String generateExportFileName(File file) { 2699784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar final String fileName = file.getName(); 2709784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return generateExportFileName(fileName.substring(0, fileName.lastIndexOf('.')), 2719784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar file.getParentFile().getName()); 2729784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2739784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 2749784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public static String generateExportFileName(String fileName, String dirName) { 27528e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar return fileName + '-' + dirName + ".xml"; 27628e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar } 27728e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar 27828e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar public static String exportLayoutNameFromInfoFileName(String infoFileName) { 27928e7064d455e2ef9da31c817dfc05ec7405c60dfYigit Boyar return infoFileName.substring(0, infoFileName.indexOf('-')); 2808e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 2818e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 282b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar public void writeInfoClass(/*Nullable*/ File sdkDir, File xmlOutDir, 283b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar /*Nullable*/ File exportClassListTo) { 28408119ea342cb47910ca80ff646d746f00e4663ceYigit Boyar writeInfoClass(sdkDir, xmlOutDir, exportClassListTo, false, false); 285b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar } 286b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar 2879784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public String getPackage() { 2889784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return mResourceBundle.getAppPackage(); 2899784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 2909784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 291b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar public void writeInfoClass(/*Nullable*/ File sdkDir, File xmlOutDir, File exportClassListTo, 29208119ea342cb47910ca80ff646d746f00e4663ceYigit Boyar boolean enableDebugLogs, boolean printEncodedErrorLogs) { 2934ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Gupta Escaper javaEscaper = SourceCodeEscapers.javaCharEscaper(); 2944ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Gupta final String sdkPath = sdkDir == null ? null : javaEscaper.escape(sdkDir.getAbsolutePath()); 295a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar final Class annotation = BindingBuildInfo.class; 2964ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Gupta final String layoutInfoPath = javaEscaper.escape(xmlOutDir.getAbsolutePath()); 297b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar final String exportClassListToPath = exportClassListTo == null ? "" : 2984ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Gupta javaEscaper.escape(exportClassListTo.getAbsolutePath()); 299a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar String classString = "package " + RESOURCE_BUNDLE_PACKAGE + ";\n\n" + 300a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "import " + annotation.getCanonicalName() + ";\n\n" + 301a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "@" + annotation.getSimpleName() + "(buildId=\"" + mBuildId + "\", " + 302a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "modulePackage=\"" + mResourceBundle.getAppPackage() + "\", " + 303ae161289a90f6ac69ffe6411ac8c09653c81d04dYigit Boyar "sdkRoot=" + "\"" + (sdkPath == null ? "" : sdkPath) + "\"," + 304a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "layoutInfoDir=\"" + layoutInfoPath + "\"," + 305b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar "exportClassListTo=\"" + exportClassListToPath + "\"," + 306a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "isLibrary=" + mIsLibrary + "," + 307b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar "minSdk=" + mMinSdk + "," + 30808119ea342cb47910ca80ff646d746f00e4663ceYigit Boyar "enableDebugLogs=" + enableDebugLogs + "," + 30908119ea342cb47910ca80ff646d746f00e4663ceYigit Boyar "printEncodedError=" + printEncodedErrorLogs + ")\n" + 310a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar "public class " + CLASS_NAME + " {}\n"; 311fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount mFileWriter.writeToFile(RESOURCE_BUNDLE_PACKAGE + "." + CLASS_NAME, classString); 3128e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 3138e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 314a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private static final FilenameFilter layoutFolderFilter = new FilenameFilter() { 3158e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount @Override 3168e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount public boolean accept(File dir, String name) { 3178e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return name.startsWith("layout"); 3188e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 3198e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount }; 3208e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 321a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private static final FilenameFilter xmlFileFilter = new FilenameFilter() { 3228e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount @Override 3238e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount public boolean accept(File dir, String name) { 3248e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount return name.toLowerCase().endsWith(".xml"); 3258e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 3268e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount }; 327890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar 328890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar /** 329890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar * Helper interface that can find the original copy of a resource XML. 330890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar */ 331890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar public interface OriginalFileLookup { 332890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar 333890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar /** 334890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar * @param file The intermediate build file 335890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar * @return The original file or null if original File cannot be found. 336890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar */ 337890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar File getOriginalFileFor(File file); 338890b4850c628f04eb75397e427ba7074e4f9c386Yigit Boyar } 3399784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3409784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar /** 3419784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar * API agnostic class to get resource changes incrementally. 3429784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar */ 3439784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public static class ResourceInput { 3449784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private final boolean mIncremental; 3459784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private final File mRootInputFolder; 3469784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private final File mRootOutputFolder; 3479784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3489784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private List<File> mAdded = new ArrayList<File>(); 3499784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private List<File> mRemoved = new ArrayList<File>(); 3509784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private List<File> mChanged = new ArrayList<File>(); 3519784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3529784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public ResourceInput(boolean incremental, File rootInputFolder, File rootOutputFolder) { 3539784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mIncremental = incremental; 3549784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mRootInputFolder = rootInputFolder; 3559784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mRootOutputFolder = rootOutputFolder; 3569784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3579784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3589784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void added(File file) { 3599784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mAdded.add(file); 3609784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3619784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void removed(File file) { 3629784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mRemoved.add(file); 3639784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3649784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public void changed(File file) { 3659784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mChanged.add(file); 3669784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3679784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3689784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public boolean shouldCopy() { 3699784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return !mRootInputFolder.equals(mRootOutputFolder); 3709784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3719784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3729784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar List<File> getAdded() { 3739784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return mAdded; 3749784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3759784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3769784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar List<File> getRemoved() { 3779784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return mRemoved; 3789784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3799784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3809784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar List<File> getChanged() { 3819784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return mChanged; 3829784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3839784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3849784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar File getRootInputFolder() { 3859784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return mRootInputFolder; 3869784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3879784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3889784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar File getRootOutputFolder() { 3899784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return mRootOutputFolder; 3909784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3919784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3929784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar public boolean isIncremental() { 3939784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar return mIncremental; 3949784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3959784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 3969784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 3979784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar private interface ProcessFileCallback { 3989784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar void processLayoutFile(File file) 3999784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar throws ParserConfigurationException, SAXException, XPathExpressionException, 4009784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar IOException; 4019784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar void processOtherFile(File parentFolder, File file) throws IOException; 4029784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar void processRemovedLayoutFile(File file); 4039784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar void processRemovedOtherFile(File parentFolder, File file) throws IOException; 4049784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 4059784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar void processOtherFolder(File folder); 4069784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 4079784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar void processLayoutFolder(File folder); 4089784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 4099784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar void processOtherRootFile(File file) throws IOException; 4109784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar 4119784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar void processRemovedOtherRootFile(File file) throws IOException; 4129784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar } 4138e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount} 414