169362b5b63875987b050354b6852db76cb799d8cGeorge Mount/* 269362b5b63875987b050354b6852db76cb799d8cGeorge Mount * Copyright (C) 2015 The Android Open Source Project 369362b5b63875987b050354b6852db76cb799d8cGeorge Mount * 469362b5b63875987b050354b6852db76cb799d8cGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License"); 569362b5b63875987b050354b6852db76cb799d8cGeorge Mount * you may not use this file except in compliance with the License. 669362b5b63875987b050354b6852db76cb799d8cGeorge Mount * You may obtain a copy of the License at 769362b5b63875987b050354b6852db76cb799d8cGeorge Mount * 869362b5b63875987b050354b6852db76cb799d8cGeorge Mount * http://www.apache.org/licenses/LICENSE-2.0 969362b5b63875987b050354b6852db76cb799d8cGeorge Mount * 1069362b5b63875987b050354b6852db76cb799d8cGeorge Mount * Unless required by applicable law or agreed to in writing, software 1169362b5b63875987b050354b6852db76cb799d8cGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS, 1269362b5b63875987b050354b6852db76cb799d8cGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1369362b5b63875987b050354b6852db76cb799d8cGeorge Mount * See the License for the specific language governing permissions and 1469362b5b63875987b050354b6852db76cb799d8cGeorge Mount * limitations under the License. 1569362b5b63875987b050354b6852db76cb799d8cGeorge Mount */ 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool; 1769362b5b63875987b050354b6852db76cb799d8cGeorge Mount 1869362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport org.apache.commons.io.FileUtils; 1969362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport org.apache.commons.io.IOUtils; 2069362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport org.w3c.dom.Document; 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount 2230cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mountimport android.databinding.tool.store.ResourceBundle.LayoutFileBundle; 2330cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mountimport android.databinding.tool.util.GenerationalClassUtil; 24fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.writer.JavaFileWriter; 2569362b5b63875987b050354b6852db76cb799d8cGeorge Mount 2669362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport java.io.File; 2769362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport java.io.FileWriter; 2869362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport java.io.FilenameFilter; 2969362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport java.io.IOException; 3069362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport java.util.ArrayList; 3130cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mountimport java.util.HashMap; 3230cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mountimport java.util.List; 3330cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mountimport java.util.Map; 3469362b5b63875987b050354b6852db76cb799d8cGeorge Mount 3569362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport javax.xml.parsers.DocumentBuilder; 3669362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport javax.xml.parsers.DocumentBuilderFactory; 3769362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport javax.xml.xpath.XPath; 3869362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport javax.xml.xpath.XPathConstants; 3969362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport javax.xml.xpath.XPathExpressionException; 4069362b5b63875987b050354b6852db76cb799d8cGeorge Mountimport javax.xml.xpath.XPathFactory; 4169362b5b63875987b050354b6852db76cb799d8cGeorge Mount 4269362b5b63875987b050354b6852db76cb799d8cGeorge Mount/** 4369362b5b63875987b050354b6852db76cb799d8cGeorge Mount * This class is used by make to copy resources to an intermediate directory and start processing 4469362b5b63875987b050354b6852db76cb799d8cGeorge Mount * them. When aapt takes over, this can be easily extracted to a short script. 4569362b5b63875987b050354b6852db76cb799d8cGeorge Mount */ 4669362b5b63875987b050354b6852db76cb799d8cGeorge Mountpublic class MakeCopy { 4769362b5b63875987b050354b6852db76cb799d8cGeorge Mount private static final int MANIFEST_INDEX = 0; 48ee7586713d68806b556a425cbebf007a56261ff3Yigit Boyar private static final int SRC_INDEX = 1; 49ee7586713d68806b556a425cbebf007a56261ff3Yigit Boyar private static final int XML_INDEX = 2; 50ee7586713d68806b556a425cbebf007a56261ff3Yigit Boyar private static final int RES_OUT_INDEX = 3; 51ee7586713d68806b556a425cbebf007a56261ff3Yigit Boyar private static final int RES_IN_INDEX = 4; 5269362b5b63875987b050354b6852db76cb799d8cGeorge Mount 53fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount private static final String APP_SUBPATH = LayoutXmlProcessor.RESOURCE_BUNDLE_PACKAGE 5469362b5b63875987b050354b6852db76cb799d8cGeorge Mount .replace('.', File.separatorChar); 5569362b5b63875987b050354b6852db76cb799d8cGeorge Mount private static final FilenameFilter LAYOUT_DIR_FILTER = new FilenameFilter() { 5669362b5b63875987b050354b6852db76cb799d8cGeorge Mount @Override 5769362b5b63875987b050354b6852db76cb799d8cGeorge Mount public boolean accept(File dir, String name) { 5869362b5b63875987b050354b6852db76cb799d8cGeorge Mount return name.toLowerCase().startsWith("layout"); 5969362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 6069362b5b63875987b050354b6852db76cb799d8cGeorge Mount }; 6169362b5b63875987b050354b6852db76cb799d8cGeorge Mount 6269362b5b63875987b050354b6852db76cb799d8cGeorge Mount private static final FilenameFilter XML_FILENAME_FILTER = new FilenameFilter() { 6369362b5b63875987b050354b6852db76cb799d8cGeorge Mount @Override 6469362b5b63875987b050354b6852db76cb799d8cGeorge Mount public boolean accept(File dir, String name) { 6569362b5b63875987b050354b6852db76cb799d8cGeorge Mount return name.toLowerCase().endsWith(".xml"); 6669362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 6769362b5b63875987b050354b6852db76cb799d8cGeorge Mount }; 6869362b5b63875987b050354b6852db76cb799d8cGeorge Mount 6969362b5b63875987b050354b6852db76cb799d8cGeorge Mount public static void main(String[] args) { 70ee7586713d68806b556a425cbebf007a56261ff3Yigit Boyar if (args.length < 5) { 7130cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount System.out.println("required parameters: [-l] manifest adk-dir src-out-dir xml-out-dir " + 7269362b5b63875987b050354b6852db76cb799d8cGeorge Mount "res-out-dir res-in-dir..."); 7369362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("Creates an android data binding class and copies resources from"); 7469362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("res-source to res-target and modifies binding layout files"); 7569362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("in res-target. Binding data is extracted into XML files"); 7669362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("and placed in xml-out-dir."); 7730cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount System.out.println(" -l indicates that this is a library"); 7869362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println(" manifest path to AndroidManifest.xml file"); 7969362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println(" src-out-dir path to where generated source goes"); 8069362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println(" xml-out-dir path to where generated binding XML goes"); 8169362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println(" res-out-dir path to the where modified resources should go"); 8269362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println(" res-in-dir path to source resources \"res\" directory. One" + 8369362b5b63875987b050354b6852db76cb799d8cGeorge Mount " or more are allowed."); 8469362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(1); 8569362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 8630cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount final boolean isLibrary = args[0].equals("-l"); 8730cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount final int indexOffset = isLibrary ? 1 : 0; 8869362b5b63875987b050354b6852db76cb799d8cGeorge Mount final String applicationPackage; 8969362b5b63875987b050354b6852db76cb799d8cGeorge Mount final int minSdk; 9030cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount final Document androidManifest = readAndroidManifest( 9130cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount new File(args[MANIFEST_INDEX + indexOffset])); 9269362b5b63875987b050354b6852db76cb799d8cGeorge Mount try { 9369362b5b63875987b050354b6852db76cb799d8cGeorge Mount final XPathFactory xPathFactory = XPathFactory.newInstance(); 9469362b5b63875987b050354b6852db76cb799d8cGeorge Mount final XPath xPath = xPathFactory.newXPath(); 9569362b5b63875987b050354b6852db76cb799d8cGeorge Mount applicationPackage = xPath.evaluate("string(/manifest/@package)", androidManifest); 9669362b5b63875987b050354b6852db76cb799d8cGeorge Mount final Double minSdkNumber = (Double) xPath.evaluate( 9769362b5b63875987b050354b6852db76cb799d8cGeorge Mount "number(/manifest/uses-sdk/@android:minSdkVersion)", androidManifest, 9869362b5b63875987b050354b6852db76cb799d8cGeorge Mount XPathConstants.NUMBER); 9969362b5b63875987b050354b6852db76cb799d8cGeorge Mount minSdk = minSdkNumber == null ? 1 : minSdkNumber.intValue(); 10069362b5b63875987b050354b6852db76cb799d8cGeorge Mount } catch (XPathExpressionException e) { 10169362b5b63875987b050354b6852db76cb799d8cGeorge Mount e.printStackTrace(); 10269362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(6); 10369362b5b63875987b050354b6852db76cb799d8cGeorge Mount return; 10469362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 10530cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount final File srcDir = new File(args[SRC_INDEX + indexOffset], APP_SUBPATH); 10669362b5b63875987b050354b6852db76cb799d8cGeorge Mount if (!makeTargetDir(srcDir)) { 10769362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("Could not create source directory " + srcDir); 10869362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(2); 10969362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 11030cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount final File resTarget = new File(args[RES_OUT_INDEX + indexOffset]); 11169362b5b63875987b050354b6852db76cb799d8cGeorge Mount if (!makeTargetDir(resTarget)) { 11269362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("Could not create resource directory: " + resTarget); 11369362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(4); 11469362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 11530cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount final File xmlDir = new File(args[XML_INDEX + indexOffset]); 11669362b5b63875987b050354b6852db76cb799d8cGeorge Mount if (!makeTargetDir(xmlDir)) { 11769362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("Could not create xml output directory: " + xmlDir); 11869362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(5); 11969362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 12069362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("Application Package: " + applicationPackage); 12169362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("Minimum SDK: " + minSdk); 12269362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("Target Resources: " + resTarget.getAbsolutePath()); 12369362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("Target Source Dir: " + srcDir.getAbsolutePath()); 12469362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("Target XML Dir: " + xmlDir.getAbsolutePath()); 12530cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount System.out.println("Library? " + isLibrary); 12669362b5b63875987b050354b6852db76cb799d8cGeorge Mount 12769362b5b63875987b050354b6852db76cb799d8cGeorge Mount boolean foundSomeResources = false; 12830cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount for (int i = RES_IN_INDEX + indexOffset; i < args.length; i++) { 12969362b5b63875987b050354b6852db76cb799d8cGeorge Mount final File resDir = new File(args[i]); 13069362b5b63875987b050354b6852db76cb799d8cGeorge Mount if (!resDir.exists()) { 13130cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount System.out.println("Could not find resource directory: " + resDir); 13269362b5b63875987b050354b6852db76cb799d8cGeorge Mount } else { 13369362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.out.println("Source Resources: " + resDir.getAbsolutePath()); 13469362b5b63875987b050354b6852db76cb799d8cGeorge Mount try { 13569362b5b63875987b050354b6852db76cb799d8cGeorge Mount FileUtils.copyDirectory(resDir, resTarget); 13669362b5b63875987b050354b6852db76cb799d8cGeorge Mount addFromFile(resDir, resTarget); 13769362b5b63875987b050354b6852db76cb799d8cGeorge Mount foundSomeResources = true; 13869362b5b63875987b050354b6852db76cb799d8cGeorge Mount } catch (IOException e) { 13969362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("Could not copy resources from " + resDir + " to " + resTarget + 14069362b5b63875987b050354b6852db76cb799d8cGeorge Mount ": " + e.getLocalizedMessage()); 14169362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(3); 14269362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 14369362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 14469362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 14569362b5b63875987b050354b6852db76cb799d8cGeorge Mount 14669362b5b63875987b050354b6852db76cb799d8cGeorge Mount if (!foundSomeResources) { 14769362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("No resource directories were found."); 14869362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(7); 14969362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 150ee7586713d68806b556a425cbebf007a56261ff3Yigit Boyar processLayoutFiles(applicationPackage, resTarget, srcDir, xmlDir, minSdk, 15169362b5b63875987b050354b6852db76cb799d8cGeorge Mount isLibrary); 15269362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 15369362b5b63875987b050354b6852db76cb799d8cGeorge Mount 15469362b5b63875987b050354b6852db76cb799d8cGeorge Mount private static Document readAndroidManifest(File manifest) { 15569362b5b63875987b050354b6852db76cb799d8cGeorge Mount try { 15669362b5b63875987b050354b6852db76cb799d8cGeorge Mount DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 15769362b5b63875987b050354b6852db76cb799d8cGeorge Mount DocumentBuilder documentBuilder = dbf.newDocumentBuilder(); 15869362b5b63875987b050354b6852db76cb799d8cGeorge Mount return documentBuilder.parse(manifest); 15969362b5b63875987b050354b6852db76cb799d8cGeorge Mount } catch (Exception e) { 16069362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("Could not load Android Manifest from " + 16169362b5b63875987b050354b6852db76cb799d8cGeorge Mount manifest.getAbsolutePath() + ": " + e.getLocalizedMessage()); 16269362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(8); 16369362b5b63875987b050354b6852db76cb799d8cGeorge Mount return null; 16469362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 16569362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 16669362b5b63875987b050354b6852db76cb799d8cGeorge Mount 16769362b5b63875987b050354b6852db76cb799d8cGeorge Mount private static void processLayoutFiles(String applicationPackage, File resTarget, File srcDir, 168ee7586713d68806b556a425cbebf007a56261ff3Yigit Boyar File xmlDir, int minSdk, boolean isLibrary) { 16969362b5b63875987b050354b6852db76cb799d8cGeorge Mount ArrayList<File> resourceFolders = new ArrayList<File>(); 17069362b5b63875987b050354b6852db76cb799d8cGeorge Mount resourceFolders.add(resTarget); 17169362b5b63875987b050354b6852db76cb799d8cGeorge Mount MakeFileWriter makeFileWriter = new MakeFileWriter(srcDir); 17269362b5b63875987b050354b6852db76cb799d8cGeorge Mount LayoutXmlProcessor xmlProcessor = new LayoutXmlProcessor(applicationPackage, 17369362b5b63875987b050354b6852db76cb799d8cGeorge Mount resourceFolders, makeFileWriter, minSdk, isLibrary); 17469362b5b63875987b050354b6852db76cb799d8cGeorge Mount try { 1754d4979490e1fa374c0d7f3599fed0a9e83a579d0George Mount xmlProcessor.processResources(minSdk); 176be83770af82294c1841eef414513653646b88dc6Yigit Boyar xmlProcessor.writeLayoutInfoFiles(xmlDir); 177b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar // TODO Looks like make does not support excluding from libs ? 178b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar xmlProcessor.writeInfoClass(null, xmlDir, null); 17930cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount Map<String, List<LayoutFileBundle>> bundles = 18030cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount xmlProcessor.getResourceBundle().getLayoutBundles(); 18130cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount if (isLibrary) { 18230cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount for (String name : bundles.keySet()) { 18330cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount LayoutFileBundle layoutFileBundle = bundles.get(name).get(0); 18430cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount String pkgName = layoutFileBundle.getBindingClassPackage().replace('.', '/'); 18530cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount System.err.println(pkgName + '/' + layoutFileBundle.getBindingClassName() + 18630cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount ".class"); 18730cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount } 18830cc484507f3dfd7a3c56e5f785c4783e3e0da9dGeorge Mount } 18969362b5b63875987b050354b6852db76cb799d8cGeorge Mount if (makeFileWriter.getErrorCount() > 0) { 19069362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(9); 19169362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 19269362b5b63875987b050354b6852db76cb799d8cGeorge Mount } catch (Exception e) { 19369362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("Error processing layout files: " + e.getLocalizedMessage()); 19469362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.exit(10); 19569362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 19669362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 19769362b5b63875987b050354b6852db76cb799d8cGeorge Mount 19869362b5b63875987b050354b6852db76cb799d8cGeorge Mount private static void addFromFile(File resDir, File resTarget) { 19969362b5b63875987b050354b6852db76cb799d8cGeorge Mount for (File layoutDir : resDir.listFiles(LAYOUT_DIR_FILTER)) { 20069362b5b63875987b050354b6852db76cb799d8cGeorge Mount if (layoutDir.isDirectory()) { 20169362b5b63875987b050354b6852db76cb799d8cGeorge Mount File targetDir = new File(resTarget, layoutDir.getName()); 20269362b5b63875987b050354b6852db76cb799d8cGeorge Mount for (File layoutFile : layoutDir.listFiles(XML_FILENAME_FILTER)) { 20369362b5b63875987b050354b6852db76cb799d8cGeorge Mount File targetFile = new File(targetDir, layoutFile.getName()); 20469362b5b63875987b050354b6852db76cb799d8cGeorge Mount FileWriter appender = null; 20569362b5b63875987b050354b6852db76cb799d8cGeorge Mount try { 20669362b5b63875987b050354b6852db76cb799d8cGeorge Mount appender = new FileWriter(targetFile, true); 20769362b5b63875987b050354b6852db76cb799d8cGeorge Mount appender.write("<!-- From: " + layoutFile.toURI().toString() + " -->\n"); 20869362b5b63875987b050354b6852db76cb799d8cGeorge Mount } catch (IOException e) { 20969362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("Could not update " + layoutFile + ": " + 21069362b5b63875987b050354b6852db76cb799d8cGeorge Mount e.getLocalizedMessage()); 21169362b5b63875987b050354b6852db76cb799d8cGeorge Mount } finally { 21269362b5b63875987b050354b6852db76cb799d8cGeorge Mount IOUtils.closeQuietly(appender); 21369362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 21469362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 21569362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 21669362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 21769362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 21869362b5b63875987b050354b6852db76cb799d8cGeorge Mount 21969362b5b63875987b050354b6852db76cb799d8cGeorge Mount private static boolean makeTargetDir(File dir) { 22069362b5b63875987b050354b6852db76cb799d8cGeorge Mount if (dir.exists()) { 22169362b5b63875987b050354b6852db76cb799d8cGeorge Mount return dir.isDirectory(); 22269362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 22369362b5b63875987b050354b6852db76cb799d8cGeorge Mount 22469362b5b63875987b050354b6852db76cb799d8cGeorge Mount return dir.mkdirs(); 22569362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 22669362b5b63875987b050354b6852db76cb799d8cGeorge Mount 22769362b5b63875987b050354b6852db76cb799d8cGeorge Mount private static class MakeFileWriter extends JavaFileWriter { 22869362b5b63875987b050354b6852db76cb799d8cGeorge Mount private final File mSourceRoot; 22969362b5b63875987b050354b6852db76cb799d8cGeorge Mount private int mErrorCount; 23069362b5b63875987b050354b6852db76cb799d8cGeorge Mount 23169362b5b63875987b050354b6852db76cb799d8cGeorge Mount public MakeFileWriter(File sourceRoot) { 23269362b5b63875987b050354b6852db76cb799d8cGeorge Mount mSourceRoot = sourceRoot; 23369362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 23469362b5b63875987b050354b6852db76cb799d8cGeorge Mount 23569362b5b63875987b050354b6852db76cb799d8cGeorge Mount @Override 23669362b5b63875987b050354b6852db76cb799d8cGeorge Mount public void writeToFile(String canonicalName, String contents) { 23769362b5b63875987b050354b6852db76cb799d8cGeorge Mount String fileName = canonicalName.replace('.', File.separatorChar) + ".java"; 23869362b5b63875987b050354b6852db76cb799d8cGeorge Mount File sourceFile = new File(mSourceRoot, fileName); 23969362b5b63875987b050354b6852db76cb799d8cGeorge Mount FileWriter writer = null; 24069362b5b63875987b050354b6852db76cb799d8cGeorge Mount try { 24169362b5b63875987b050354b6852db76cb799d8cGeorge Mount sourceFile.getParentFile().mkdirs(); 24269362b5b63875987b050354b6852db76cb799d8cGeorge Mount writer = new FileWriter(sourceFile); 24369362b5b63875987b050354b6852db76cb799d8cGeorge Mount writer.write(contents); 24469362b5b63875987b050354b6852db76cb799d8cGeorge Mount } catch (IOException e) { 24569362b5b63875987b050354b6852db76cb799d8cGeorge Mount System.err.println("Could not write to " + sourceFile + ": " + 24669362b5b63875987b050354b6852db76cb799d8cGeorge Mount e.getLocalizedMessage()); 24769362b5b63875987b050354b6852db76cb799d8cGeorge Mount mErrorCount++; 24869362b5b63875987b050354b6852db76cb799d8cGeorge Mount } finally { 24969362b5b63875987b050354b6852db76cb799d8cGeorge Mount IOUtils.closeQuietly(writer); 25069362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 25169362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 25269362b5b63875987b050354b6852db76cb799d8cGeorge Mount 25369362b5b63875987b050354b6852db76cb799d8cGeorge Mount public int getErrorCount() { 25469362b5b63875987b050354b6852db76cb799d8cGeorge Mount return mErrorCount; 25569362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 25669362b5b63875987b050354b6852db76cb799d8cGeorge Mount } 25769362b5b63875987b050354b6852db76cb799d8cGeorge Mount} 258