Loading tools/data-binding/TestApp/build.gradle +2 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,8 @@ android { packagingOptions { exclude 'META-INF/services/javax.annotation.processing.Processor' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' } } Loading tools/data-binding/TestApp/src/androidTest/java/com/android/databinding/testapp/AbsSpinnerBindingAdapterTest.java 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.databinding.testapp; import com.android.databinding.testapp.generated.AbsSpinnerAdapterTestBinder; import com.android.databinding.testapp.vo.AbsSpinnerBindingObject; import android.os.Build; import android.widget.Spinner; import android.widget.SpinnerAdapter; public class AbsSpinnerBindingAdapterTest extends BindingAdapterTestBase<AbsSpinnerAdapterTestBinder, AbsSpinnerBindingObject> { Spinner mView; public AbsSpinnerBindingAdapterTest() { super(AbsSpinnerAdapterTestBinder.class, AbsSpinnerBindingObject.class, R.layout.abs_spinner_adapter_test); } @Override protected void setUp() throws Exception { super.setUp(); mView = mBinder.getView(); } public void testEntries() throws Throwable { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { validateEntries(); changeValues(); validateEntries(); } } private void validateEntries() { assertEquals(mBindingObject.getEntries().length, mView.getAdapter().getCount()); CharSequence[] entries = mBindingObject.getEntries(); SpinnerAdapter adapter = mView.getAdapter(); for (int i = 0; i < entries.length; i++) { assertEquals(adapter.getItem(i), entries[i]); } } } tools/data-binding/annotationprocessor/build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ sourceSets { dependencies { compile project(":baseLibrary") compile project(":compiler") compile 'commons-codec:commons-codec:1.10' } uploadArchives { Loading tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessBindable.java +11 −0 Original line number Diff line number Diff line package com.android.databinding.annotationprocessor; import com.android.databinding.reflection.ModelAnalyzer; import com.android.databinding.reflection.ReflectionAnalyzer; import android.binding.Bindable; import java.io.File; Loading @@ -19,6 +22,7 @@ import java.util.List; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; Loading @@ -27,6 +31,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; Loading @@ -46,6 +51,12 @@ public class ProcessBindable extends AbstractProcessor { public ProcessBindable() { } @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); ReflectionAnalyzer.setProcessingEnvironment(processingEnv); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (mFileGenerated) { Loading tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessExpressions.java +61 −24 Original line number Diff line number Diff line package com.android.databinding.annotationprocessor; import android.binding.Bindable; import com.android.databinding.CompilerChef; import com.android.databinding.writer.AnnotationJavaFileWriter; import java.io.File; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import android.binding.BinderBundle; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.io.Writer; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.tools.Diagnostic; import javax.tools.FileObject; import javax.tools.JavaFileObject; import javax.tools.StandardLocation; public class ProcessExpressions { @SupportedAnnotationTypes({"android.binding.BinderBundle"}) @SupportedSourceVersion(SourceVersion.RELEASE_7) public class ProcessExpressions extends AbstractProcessor { private boolean mGenerationComplete; public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (mGenerationComplete) { return false; } public static boolean process(ProcessingEnvironment processingEnv, Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { String binderBundle64 = null; for (Element element : roundEnv.getElementsAnnotatedWith(BinderBundle.class)) { if (element.getKind() != ElementKind.CLASS) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "BinderBundle associated with wrong type. Should be a class.", element); continue; } TypeElement binderBundleClass = (TypeElement) element; if (!"BinderInfo".equals(binderBundleClass.getQualifiedName().toString())) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Only a generated class may use @BinderBundle attribute.", element); continue; } BinderBundle binderBundle = binderBundleClass.getAnnotation(BinderBundle.class); binderBundle64 = binderBundle.value(); } if (binderBundle64 != null) { ByteArrayInputStream in = null; try { byte[] buf = Base64.decodeBase64(binderBundle64); in = new ByteArrayInputStream(buf); AnnotationJavaFileWriter annotationJavaFileWriter = new AnnotationJavaFileWriter(processingEnv); CompilerChef compilerChef = CompilerChef.createChef(in, annotationJavaFileWriter); if (compilerChef.hasAnythingToGenerate()) { compilerChef.writeViewBinders(); compilerChef.writeDbrFile(); } } catch (IOException e) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not generate Binders from binder data store. " + e.getLocalizedMessage()); } catch (ClassNotFoundException e) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Error generating Binders from binder data store. " + e.getLocalizedMessage()); } finally { if (in != null) { IOUtils.closeQuietly(in); } } } mGenerationComplete = true; return true; } } Loading
tools/data-binding/TestApp/build.gradle +2 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,8 @@ android { packagingOptions { exclude 'META-INF/services/javax.annotation.processing.Processor' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' } } Loading
tools/data-binding/TestApp/src/androidTest/java/com/android/databinding/testapp/AbsSpinnerBindingAdapterTest.java 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.databinding.testapp; import com.android.databinding.testapp.generated.AbsSpinnerAdapterTestBinder; import com.android.databinding.testapp.vo.AbsSpinnerBindingObject; import android.os.Build; import android.widget.Spinner; import android.widget.SpinnerAdapter; public class AbsSpinnerBindingAdapterTest extends BindingAdapterTestBase<AbsSpinnerAdapterTestBinder, AbsSpinnerBindingObject> { Spinner mView; public AbsSpinnerBindingAdapterTest() { super(AbsSpinnerAdapterTestBinder.class, AbsSpinnerBindingObject.class, R.layout.abs_spinner_adapter_test); } @Override protected void setUp() throws Exception { super.setUp(); mView = mBinder.getView(); } public void testEntries() throws Throwable { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { validateEntries(); changeValues(); validateEntries(); } } private void validateEntries() { assertEquals(mBindingObject.getEntries().length, mView.getAdapter().getCount()); CharSequence[] entries = mBindingObject.getEntries(); SpinnerAdapter adapter = mView.getAdapter(); for (int i = 0; i < entries.length; i++) { assertEquals(adapter.getItem(i), entries[i]); } } }
tools/data-binding/annotationprocessor/build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ sourceSets { dependencies { compile project(":baseLibrary") compile project(":compiler") compile 'commons-codec:commons-codec:1.10' } uploadArchives { Loading
tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessBindable.java +11 −0 Original line number Diff line number Diff line package com.android.databinding.annotationprocessor; import com.android.databinding.reflection.ModelAnalyzer; import com.android.databinding.reflection.ReflectionAnalyzer; import android.binding.Bindable; import java.io.File; Loading @@ -19,6 +22,7 @@ import java.util.List; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; Loading @@ -27,6 +31,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; Loading @@ -46,6 +51,12 @@ public class ProcessBindable extends AbstractProcessor { public ProcessBindable() { } @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); ReflectionAnalyzer.setProcessingEnvironment(processingEnv); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (mFileGenerated) { Loading
tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessExpressions.java +61 −24 Original line number Diff line number Diff line package com.android.databinding.annotationprocessor; import android.binding.Bindable; import com.android.databinding.CompilerChef; import com.android.databinding.writer.AnnotationJavaFileWriter; import java.io.File; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import android.binding.BinderBundle; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.io.Writer; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.tools.Diagnostic; import javax.tools.FileObject; import javax.tools.JavaFileObject; import javax.tools.StandardLocation; public class ProcessExpressions { @SupportedAnnotationTypes({"android.binding.BinderBundle"}) @SupportedSourceVersion(SourceVersion.RELEASE_7) public class ProcessExpressions extends AbstractProcessor { private boolean mGenerationComplete; public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (mGenerationComplete) { return false; } public static boolean process(ProcessingEnvironment processingEnv, Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { String binderBundle64 = null; for (Element element : roundEnv.getElementsAnnotatedWith(BinderBundle.class)) { if (element.getKind() != ElementKind.CLASS) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "BinderBundle associated with wrong type. Should be a class.", element); continue; } TypeElement binderBundleClass = (TypeElement) element; if (!"BinderInfo".equals(binderBundleClass.getQualifiedName().toString())) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Only a generated class may use @BinderBundle attribute.", element); continue; } BinderBundle binderBundle = binderBundleClass.getAnnotation(BinderBundle.class); binderBundle64 = binderBundle.value(); } if (binderBundle64 != null) { ByteArrayInputStream in = null; try { byte[] buf = Base64.decodeBase64(binderBundle64); in = new ByteArrayInputStream(buf); AnnotationJavaFileWriter annotationJavaFileWriter = new AnnotationJavaFileWriter(processingEnv); CompilerChef compilerChef = CompilerChef.createChef(in, annotationJavaFileWriter); if (compilerChef.hasAnythingToGenerate()) { compilerChef.writeViewBinders(); compilerChef.writeDbrFile(); } } catch (IOException e) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not generate Binders from binder data store. " + e.getLocalizedMessage()); } catch (ClassNotFoundException e) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Error generating Binders from binder data store. " + e.getLocalizedMessage()); } finally { if (in != null) { IOUtils.closeQuietly(in); } } } mGenerationComplete = true; return true; } }