ProcessBindable.java revision 1b9940e612fc73202837fbe9db2f9035f307b5d1
1b617e5da04aa910be70204afb886b1ebebb80618George Mountpackage com.android.databinding.annotationprocessor; 2b617e5da04aa910be70204afb886b1ebebb80618George Mount 31b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport com.android.databinding.reflection.ModelAnalyzer; 41b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport com.android.databinding.reflection.ReflectionAnalyzer; 51b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 6b617e5da04aa910be70204afb886b1ebebb80618George Mountimport android.binding.Bindable; 7b617e5da04aa910be70204afb886b1ebebb80618George Mount 8612997fe2e41366573855f56898b27d4c8787244George Mountimport java.io.File; 9b617e5da04aa910be70204afb886b1ebebb80618George Mountimport java.io.IOException; 10846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mountimport java.io.InputStream; 11612997fe2e41366573855f56898b27d4c8787244George Mountimport java.io.ObjectInputStream; 12612997fe2e41366573855f56898b27d4c8787244George Mountimport java.io.ObjectOutputStream; 13846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mountimport java.io.Serializable; 14b617e5da04aa910be70204afb886b1ebebb80618George Mountimport java.io.Writer; 15846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mountimport java.net.URL; 16b617e5da04aa910be70204afb886b1ebebb80618George Mountimport java.util.ArrayList; 17b617e5da04aa910be70204afb886b1ebebb80618George Mountimport java.util.Collections; 18846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mountimport java.util.Enumeration; 19846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mountimport java.util.HashMap; 20b617e5da04aa910be70204afb886b1ebebb80618George Mountimport java.util.HashSet; 21e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mountimport java.util.List; 22b617e5da04aa910be70204afb886b1ebebb80618George Mountimport java.util.Set; 23b617e5da04aa910be70204afb886b1ebebb80618George Mount 24b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.annotation.processing.AbstractProcessor; 251b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport javax.annotation.processing.ProcessingEnvironment; 26b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.annotation.processing.RoundEnvironment; 27b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.annotation.processing.SupportedAnnotationTypes; 28b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.annotation.processing.SupportedSourceVersion; 29b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.SourceVersion; 30b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.Element; 31e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mountimport javax.lang.model.element.ElementKind; 32b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.ExecutableElement; 33b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.Name; 341b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport javax.lang.model.element.PackageElement; 35b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.TypeElement; 36b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.VariableElement; 37b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.type.TypeKind; 38e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mountimport javax.lang.model.util.Elements; 39e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mountimport javax.lang.model.util.Types; 40b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.tools.Diagnostic; 413561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.tools.FileObject; 42b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.tools.JavaFileObject; 433561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.tools.StandardLocation; 44b617e5da04aa910be70204afb886b1ebebb80618George Mount 45b617e5da04aa910be70204afb886b1ebebb80618George Mount@SupportedAnnotationTypes({"android.binding.Bindable"}) 46b617e5da04aa910be70204afb886b1ebebb80618George Mount@SupportedSourceVersion(SourceVersion.RELEASE_7) 47b617e5da04aa910be70204afb886b1ebebb80618George Mountpublic class ProcessBindable extends AbstractProcessor { 48b617e5da04aa910be70204afb886b1ebebb80618George Mount 49b617e5da04aa910be70204afb886b1ebebb80618George Mount private boolean mFileGenerated; 50b617e5da04aa910be70204afb886b1ebebb80618George Mount 51b617e5da04aa910be70204afb886b1ebebb80618George Mount public ProcessBindable() { 52b617e5da04aa910be70204afb886b1ebebb80618George Mount } 53b617e5da04aa910be70204afb886b1ebebb80618George Mount 54b617e5da04aa910be70204afb886b1ebebb80618George Mount @Override 551b9940e612fc73202837fbe9db2f9035f307b5d1George Mount public synchronized void init(ProcessingEnvironment processingEnv) { 561b9940e612fc73202837fbe9db2f9035f307b5d1George Mount super.init(processingEnv); 571b9940e612fc73202837fbe9db2f9035f307b5d1George Mount ReflectionAnalyzer.setProcessingEnvironment(processingEnv); 581b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 591b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 601b9940e612fc73202837fbe9db2f9035f307b5d1George Mount @Override 61b617e5da04aa910be70204afb886b1ebebb80618George Mount public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 62b617e5da04aa910be70204afb886b1ebebb80618George Mount if (mFileGenerated) { 63b617e5da04aa910be70204afb886b1ebebb80618George Mount return false; 64b617e5da04aa910be70204afb886b1ebebb80618George Mount } 65846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount Intermediate properties = readIntermediateFile(); 66b617e5da04aa910be70204afb886b1ebebb80618George Mount for (Element element : roundEnv.getElementsAnnotatedWith(Bindable.class)) { 67846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount TypeElement enclosing = (TypeElement) element.getEnclosingElement(); 68846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties.cleanProperties(enclosing.getQualifiedName().toString()); 69846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 70846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount for (Element element : roundEnv.getElementsAnnotatedWith(Bindable.class)) { 71846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount TypeElement enclosing = (TypeElement) element.getEnclosingElement(); 72b617e5da04aa910be70204afb886b1ebebb80618George Mount String name = getPropertyName(element); 73b617e5da04aa910be70204afb886b1ebebb80618George Mount if (name != null) { 74846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties.addProperty(enclosing.getQualifiedName().toString(), name); 75b617e5da04aa910be70204afb886b1ebebb80618George Mount } 76b617e5da04aa910be70204afb886b1ebebb80618George Mount } 77612997fe2e41366573855f56898b27d4c8787244George Mount writeIntermediateFile(properties); 78b617e5da04aa910be70204afb886b1ebebb80618George Mount generateBR(properties); 79b617e5da04aa910be70204afb886b1ebebb80618George Mount mFileGenerated = true; 80b617e5da04aa910be70204afb886b1ebebb80618George Mount return true; 81b617e5da04aa910be70204afb886b1ebebb80618George Mount } 82b617e5da04aa910be70204afb886b1ebebb80618George Mount 83846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private void generateBR(Intermediate intermediate) { 84b617e5da04aa910be70204afb886b1ebebb80618George Mount processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, 85b617e5da04aa910be70204afb886b1ebebb80618George Mount "************* Generating BR file from Bindable attributes"); 86846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount HashSet<String> properties = new HashSet<>(); 87846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount intermediate.captureProperties(properties); 88846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount mergeClassPathResources(properties); 89b617e5da04aa910be70204afb886b1ebebb80618George Mount try { 90b617e5da04aa910be70204afb886b1ebebb80618George Mount ArrayList<String> sortedProperties = new ArrayList<String>(); 91b617e5da04aa910be70204afb886b1ebebb80618George Mount sortedProperties.addAll(properties); 92b617e5da04aa910be70204afb886b1ebebb80618George Mount Collections.sort(sortedProperties); 93b617e5da04aa910be70204afb886b1ebebb80618George Mount 94b617e5da04aa910be70204afb886b1ebebb80618George Mount JavaFileObject fileObject = processingEnv.getFiler() 95b617e5da04aa910be70204afb886b1ebebb80618George Mount .createSourceFile("android.binding.BR"); 96b617e5da04aa910be70204afb886b1ebebb80618George Mount Writer writer = fileObject.openWriter(); 97b617e5da04aa910be70204afb886b1ebebb80618George Mount writer.write("package android.binding;\n\n" + 98b617e5da04aa910be70204afb886b1ebebb80618George Mount "public final class BR {\n" + 99b617e5da04aa910be70204afb886b1ebebb80618George Mount " public static final int _all = 0;\n" 100b617e5da04aa910be70204afb886b1ebebb80618George Mount ); 101b617e5da04aa910be70204afb886b1ebebb80618George Mount int id = 0; 102b617e5da04aa910be70204afb886b1ebebb80618George Mount for (String property : sortedProperties) { 103b617e5da04aa910be70204afb886b1ebebb80618George Mount id++; 104b617e5da04aa910be70204afb886b1ebebb80618George Mount writer.write(" public static final int " + property + " = " + id + ";\n"); 105b617e5da04aa910be70204afb886b1ebebb80618George Mount } 10643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar writer.write(" public static int getId(String key) {\n"); 10743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar writer.write(" switch(key) {\n"); 10843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar id = 0; 10943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar for (String property : sortedProperties) { 11043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar id++; 11143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar writer.write(" case \"" + property + "\": return " + id + ";\n"); 11243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 11343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar writer.write(" }\n"); 11443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar writer.write(" return -1;\n"); 11543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar writer.write(" }"); 116b617e5da04aa910be70204afb886b1ebebb80618George Mount writer.write("}\n"); 11743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 118b617e5da04aa910be70204afb886b1ebebb80618George Mount writer.close(); 119b617e5da04aa910be70204afb886b1ebebb80618George Mount } catch (IOException e) { 120b617e5da04aa910be70204afb886b1ebebb80618George Mount processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 121b617e5da04aa910be70204afb886b1ebebb80618George Mount "Could not generate BR file " + e.getLocalizedMessage()); 122b617e5da04aa910be70204afb886b1ebebb80618George Mount } 123b617e5da04aa910be70204afb886b1ebebb80618George Mount } 124b617e5da04aa910be70204afb886b1ebebb80618George Mount 125b617e5da04aa910be70204afb886b1ebebb80618George Mount private String getPropertyName(Element element) { 126b617e5da04aa910be70204afb886b1ebebb80618George Mount switch (element.getKind()) { 127b617e5da04aa910be70204afb886b1ebebb80618George Mount case FIELD: 128b617e5da04aa910be70204afb886b1ebebb80618George Mount return stripPrefixFromField((VariableElement) element); 129b617e5da04aa910be70204afb886b1ebebb80618George Mount case METHOD: 130b617e5da04aa910be70204afb886b1ebebb80618George Mount return stripPrefixFromMethod((ExecutableElement) element); 131b617e5da04aa910be70204afb886b1ebebb80618George Mount default: 132b617e5da04aa910be70204afb886b1ebebb80618George Mount processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 133b617e5da04aa910be70204afb886b1ebebb80618George Mount "@Bindable is not allowed on " + element.getKind(), element); 134b617e5da04aa910be70204afb886b1ebebb80618George Mount return null; 135b617e5da04aa910be70204afb886b1ebebb80618George Mount } 136b617e5da04aa910be70204afb886b1ebebb80618George Mount } 137b617e5da04aa910be70204afb886b1ebebb80618George Mount 138b617e5da04aa910be70204afb886b1ebebb80618George Mount private static String stripPrefixFromField(VariableElement element) { 139b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 140b617e5da04aa910be70204afb886b1ebebb80618George Mount if (name.length() >= 2) { 141b617e5da04aa910be70204afb886b1ebebb80618George Mount char firstChar = name.charAt(0); 142b617e5da04aa910be70204afb886b1ebebb80618George Mount char secondChar = name.charAt(1); 1437201118b5554426cea3fcd07e4fd96e999d3eea9George Mount if (name.length() > 2 && firstChar == 'm' && secondChar == '_') { 1447201118b5554426cea3fcd07e4fd96e999d3eea9George Mount char thirdChar = name.charAt(2); 1457201118b5554426cea3fcd07e4fd96e999d3eea9George Mount if (Character.isJavaIdentifierStart(thirdChar)) { 1467201118b5554426cea3fcd07e4fd96e999d3eea9George Mount return "" + Character.toLowerCase(thirdChar) + 1477201118b5554426cea3fcd07e4fd96e999d3eea9George Mount name.subSequence(3, name.length()); 1487201118b5554426cea3fcd07e4fd96e999d3eea9George Mount } 1497201118b5554426cea3fcd07e4fd96e999d3eea9George Mount } else if ((firstChar == 'm' && Character.isUpperCase(secondChar)) || 150b617e5da04aa910be70204afb886b1ebebb80618George Mount (firstChar == '_' && Character.isJavaIdentifierStart(secondChar))) { 151b617e5da04aa910be70204afb886b1ebebb80618George Mount return "" + Character.toLowerCase(secondChar) + name.subSequence(2, name.length()); 152b617e5da04aa910be70204afb886b1ebebb80618George Mount } 153b617e5da04aa910be70204afb886b1ebebb80618George Mount } 154b617e5da04aa910be70204afb886b1ebebb80618George Mount return name.toString(); 155b617e5da04aa910be70204afb886b1ebebb80618George Mount } 156b617e5da04aa910be70204afb886b1ebebb80618George Mount 157b617e5da04aa910be70204afb886b1ebebb80618George Mount private String stripPrefixFromMethod(ExecutableElement element) { 158b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 159b617e5da04aa910be70204afb886b1ebebb80618George Mount CharSequence propertyName; 160b617e5da04aa910be70204afb886b1ebebb80618George Mount if (isGetter(element) || isSetter(element)) { 161b617e5da04aa910be70204afb886b1ebebb80618George Mount propertyName = name.subSequence(3, name.length()); 162b617e5da04aa910be70204afb886b1ebebb80618George Mount } else if (isBooleanGetter(element)) { 163b617e5da04aa910be70204afb886b1ebebb80618George Mount propertyName = name.subSequence(2, name.length()); 164b617e5da04aa910be70204afb886b1ebebb80618George Mount } else { 165b617e5da04aa910be70204afb886b1ebebb80618George Mount processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 166b617e5da04aa910be70204afb886b1ebebb80618George Mount "@Bindable associated with method must follow JavaBeans convention", element); 167b617e5da04aa910be70204afb886b1ebebb80618George Mount return null; 168b617e5da04aa910be70204afb886b1ebebb80618George Mount } 169b617e5da04aa910be70204afb886b1ebebb80618George Mount char firstChar = propertyName.charAt(0); 170b617e5da04aa910be70204afb886b1ebebb80618George Mount return "" + Character.toLowerCase(firstChar) + 171b617e5da04aa910be70204afb886b1ebebb80618George Mount propertyName.subSequence(1, propertyName.length()); 172b617e5da04aa910be70204afb886b1ebebb80618George Mount } 173b617e5da04aa910be70204afb886b1ebebb80618George Mount 174b617e5da04aa910be70204afb886b1ebebb80618George Mount private static boolean prefixes(CharSequence sequence, String prefix) { 175b617e5da04aa910be70204afb886b1ebebb80618George Mount boolean prefixes = false; 176b617e5da04aa910be70204afb886b1ebebb80618George Mount if (sequence.length() > prefix.length()) { 177b617e5da04aa910be70204afb886b1ebebb80618George Mount int count = prefix.length(); 178b617e5da04aa910be70204afb886b1ebebb80618George Mount prefixes = true; 179b617e5da04aa910be70204afb886b1ebebb80618George Mount for (int i = 0; i < count; i++) { 180b617e5da04aa910be70204afb886b1ebebb80618George Mount if (sequence.charAt(i) != prefix.charAt(i)) { 181b617e5da04aa910be70204afb886b1ebebb80618George Mount prefixes = false; 182b617e5da04aa910be70204afb886b1ebebb80618George Mount break; 183b617e5da04aa910be70204afb886b1ebebb80618George Mount } 184b617e5da04aa910be70204afb886b1ebebb80618George Mount } 185b617e5da04aa910be70204afb886b1ebebb80618George Mount } 186b617e5da04aa910be70204afb886b1ebebb80618George Mount return prefixes; 187b617e5da04aa910be70204afb886b1ebebb80618George Mount } 188b617e5da04aa910be70204afb886b1ebebb80618George Mount 189b617e5da04aa910be70204afb886b1ebebb80618George Mount private static boolean isGetter(ExecutableElement element) { 190b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 191b617e5da04aa910be70204afb886b1ebebb80618George Mount return prefixes(name, "get") && 192b617e5da04aa910be70204afb886b1ebebb80618George Mount Character.isJavaIdentifierStart(name.charAt(3)) && 193b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getParameters().isEmpty() && 194b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getReturnType().getKind() != TypeKind.VOID; 195b617e5da04aa910be70204afb886b1ebebb80618George Mount } 196b617e5da04aa910be70204afb886b1ebebb80618George Mount 197b617e5da04aa910be70204afb886b1ebebb80618George Mount private static boolean isSetter(ExecutableElement element) { 198b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 199b617e5da04aa910be70204afb886b1ebebb80618George Mount return prefixes(name, "set") && 200b617e5da04aa910be70204afb886b1ebebb80618George Mount Character.isJavaIdentifierStart(name.charAt(3)) && 201b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getParameters().size() == 1 && 202b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getReturnType().getKind() == TypeKind.VOID; 203b617e5da04aa910be70204afb886b1ebebb80618George Mount } 204b617e5da04aa910be70204afb886b1ebebb80618George Mount 205b617e5da04aa910be70204afb886b1ebebb80618George Mount private static boolean isBooleanGetter(ExecutableElement element) { 206b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 207b617e5da04aa910be70204afb886b1ebebb80618George Mount return prefixes(name, "is") && 208b617e5da04aa910be70204afb886b1ebebb80618George Mount Character.isJavaIdentifierStart(name.charAt(2)) && 209b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getParameters().isEmpty() && 210b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getReturnType().getKind() == TypeKind.BOOLEAN; 211b617e5da04aa910be70204afb886b1ebebb80618George Mount } 212612997fe2e41366573855f56898b27d4c8787244George Mount 213846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private Intermediate readIntermediateFile() { 214846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount Intermediate properties = null; 2153561e3e665698843b1c664385a842e779198960bGeorge Mount ObjectInputStream in = null; 2163561e3e665698843b1c664385a842e779198960bGeorge Mount try { 2173561e3e665698843b1c664385a842e779198960bGeorge Mount FileObject intermediate = processingEnv.getFiler() 2183561e3e665698843b1c664385a842e779198960bGeorge Mount .getResource(StandardLocation.CLASS_OUTPUT, 2193561e3e665698843b1c664385a842e779198960bGeorge Mount ProcessBindable.class.getPackage().getName(), "binding_properties.bin"); 2203561e3e665698843b1c664385a842e779198960bGeorge Mount if (new File(intermediate.getName()).exists()) { 2213561e3e665698843b1c664385a842e779198960bGeorge Mount in = new ObjectInputStream(intermediate.openInputStream()); 222846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties = (Intermediate) in.readObject(); 2233561e3e665698843b1c664385a842e779198960bGeorge Mount } 2243561e3e665698843b1c664385a842e779198960bGeorge Mount } catch (IOException e) { 2253561e3e665698843b1c664385a842e779198960bGeorge Mount System.err.println("Could not read Binding properties intermediate file: " + 2263561e3e665698843b1c664385a842e779198960bGeorge Mount e.getLocalizedMessage()); 2273561e3e665698843b1c664385a842e779198960bGeorge Mount } catch (ClassNotFoundException e) { 2283561e3e665698843b1c664385a842e779198960bGeorge Mount System.err.println("Could not read Binding properties intermediate file: " + 2293561e3e665698843b1c664385a842e779198960bGeorge Mount e.getLocalizedMessage()); 2303561e3e665698843b1c664385a842e779198960bGeorge Mount } finally { 2313561e3e665698843b1c664385a842e779198960bGeorge Mount try { 2323561e3e665698843b1c664385a842e779198960bGeorge Mount if (in != null) { 2333561e3e665698843b1c664385a842e779198960bGeorge Mount in.close(); 2343561e3e665698843b1c664385a842e779198960bGeorge Mount } 235612997fe2e41366573855f56898b27d4c8787244George Mount } catch (IOException e) { 2363561e3e665698843b1c664385a842e779198960bGeorge Mount e.printStackTrace(); 237612997fe2e41366573855f56898b27d4c8787244George Mount } 238612997fe2e41366573855f56898b27d4c8787244George Mount } 239612997fe2e41366573855f56898b27d4c8787244George Mount if (properties == null) { 240846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties = new IntermediateV1(); 241612997fe2e41366573855f56898b27d4c8787244George Mount } 242612997fe2e41366573855f56898b27d4c8787244George Mount return properties; 243612997fe2e41366573855f56898b27d4c8787244George Mount } 244612997fe2e41366573855f56898b27d4c8787244George Mount 245846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private void mergeClassPathResources(HashSet<String> intermediateProperties) { 246846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount try { 247846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount String resourcePath = ProcessBindable.class.getPackage().getName() 248846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount .replace('.', '/') + "/binding_properties.bin"; 249846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount Enumeration<URL> resources = getClass().getClassLoader() 250846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount .getResources(resourcePath); 251846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount while (resources.hasMoreElements()) { 252846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount URL url = resources.nextElement(); 253846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount System.out.println("Merging binding adapters from " + url); 254846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount InputStream inputStream = null; 255846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount try { 256846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount inputStream = url.openStream(); 257846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount ObjectInputStream in = new ObjectInputStream(inputStream); 258846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount Intermediate properties = (Intermediate) in.readObject(); 259846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount if (properties != null) { 260846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties.captureProperties(intermediateProperties); 261846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 262846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } catch (IOException e) { 263846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount System.err.println("Could not merge in Bindables from " + url + ": " + 264846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount e.getLocalizedMessage()); 265846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } catch (ClassNotFoundException e) { 266846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount System.err.println("Could not read Binding properties intermediate file: " + 267846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount e.getLocalizedMessage()); 268846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } finally { 269846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount try { 270846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount inputStream.close(); 271846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } catch (IOException e2) { 272846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount System.err.println("Error closing intermediate Bindables store: " + 273846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount e2.getLocalizedMessage()); 274846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 275846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 276846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 277846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } catch (IOException e) { 278846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount System.err.println("Could not read Binding properties intermediate file: " + 279846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount e.getLocalizedMessage()); 280846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 281846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 282846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 283846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private void writeIntermediateFile(Intermediate properties) { 284612997fe2e41366573855f56898b27d4c8787244George Mount try { 2853561e3e665698843b1c664385a842e779198960bGeorge Mount FileObject intermediate = processingEnv.getFiler().createResource( 2863561e3e665698843b1c664385a842e779198960bGeorge Mount StandardLocation.CLASS_OUTPUT, ProcessBindable.class.getPackage().getName(), 2873561e3e665698843b1c664385a842e779198960bGeorge Mount "binding_properties.bin"); 2883561e3e665698843b1c664385a842e779198960bGeorge Mount ObjectOutputStream out = new ObjectOutputStream(intermediate.openOutputStream()); 289612997fe2e41366573855f56898b27d4c8787244George Mount out.writeObject(properties); 290612997fe2e41366573855f56898b27d4c8787244George Mount out.close(); 291612997fe2e41366573855f56898b27d4c8787244George Mount } catch (IOException e) { 292612997fe2e41366573855f56898b27d4c8787244George Mount processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 293612997fe2e41366573855f56898b27d4c8787244George Mount "Could not write to intermediate file: " + e.getLocalizedMessage()); 294612997fe2e41366573855f56898b27d4c8787244George Mount } 295612997fe2e41366573855f56898b27d4c8787244George Mount } 296846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 297846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private interface Intermediate { 298846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount void captureProperties(Set<String> properties); 299846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 300846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount void cleanProperties(String className); 301846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 302846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount void addProperty(String className, String propertyName); 303846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 304846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 305846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private static class IntermediateV1 implements Serializable, Intermediate { 306846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private static final long serialVersionUID = 1L; 307846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 308846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private final HashMap<String, HashSet<String>> mProperties = new HashMap<>(); 309846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 310846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount @Override 311846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount public void captureProperties(Set<String> properties) { 312846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount for (HashSet<String> propertySet : mProperties.values()) { 313846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties.addAll(propertySet); 314846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 315846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 316846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 317846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount @Override 318846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount public void cleanProperties(String className) { 319846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount mProperties.remove(className); 320846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 321846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 322846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount @Override 323846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount public void addProperty(String className, String propertyName) { 324846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount HashSet<String> properties = mProperties.get(className); 325846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount if (properties == null) { 326846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties = new HashSet<>(); 327846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount mProperties.put(className, properties); 328846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 329846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties.add(propertyName); 330846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 331846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 332b617e5da04aa910be70204afb886b1ebebb80618George Mount} 333