LayoutXmlProcessor.java revision 612997fe2e41366573855f56898b27d4c8787244
1612997fe2e41366573855f56898b27d4c8787244George Mount/*
2612997fe2e41366573855f56898b27d4c8787244George Mount * Copyright (C) 2015 The Android Open Source Project
3612997fe2e41366573855f56898b27d4c8787244George Mount *
4612997fe2e41366573855f56898b27d4c8787244George Mount * Licensed under the Apache License, Version 2.0 (the "License");
5612997fe2e41366573855f56898b27d4c8787244George Mount * you may not use this file except in compliance with the License.
6612997fe2e41366573855f56898b27d4c8787244George Mount * You may obtain a copy of the License at
7612997fe2e41366573855f56898b27d4c8787244George Mount *
8612997fe2e41366573855f56898b27d4c8787244George Mount *      http://www.apache.org/licenses/LICENSE-2.0
9612997fe2e41366573855f56898b27d4c8787244George Mount *
10612997fe2e41366573855f56898b27d4c8787244George Mount * Unless required by applicable law or agreed to in writing, software
11612997fe2e41366573855f56898b27d4c8787244George Mount * distributed under the License is distributed on an "AS IS" BASIS,
12612997fe2e41366573855f56898b27d4c8787244George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13612997fe2e41366573855f56898b27d4c8787244George Mount * See the License for the specific language governing permissions and
14612997fe2e41366573855f56898b27d4c8787244George Mount * limitations under the License.
15612997fe2e41366573855f56898b27d4c8787244George Mount */
16612997fe2e41366573855f56898b27d4c8787244George Mountpackage com.android.databinding.annotationprocessor;
17612997fe2e41366573855f56898b27d4c8787244George Mount
18612997fe2e41366573855f56898b27d4c8787244George Mountimport android.binding.BindingAdapter;
19612997fe2e41366573855f56898b27d4c8787244George Mount
20612997fe2e41366573855f56898b27d4c8787244George Mountimport java.io.File;
21612997fe2e41366573855f56898b27d4c8787244George Mountimport java.io.IOException;
22612997fe2e41366573855f56898b27d4c8787244George Mountimport java.util.HashMap;
23612997fe2e41366573855f56898b27d4c8787244George Mountimport java.util.List;
24612997fe2e41366573855f56898b27d4c8787244George Mountimport java.util.Objects;
25612997fe2e41366573855f56898b27d4c8787244George Mountimport java.util.Set;
26612997fe2e41366573855f56898b27d4c8787244George Mount
27612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.annotation.processing.AbstractProcessor;
28612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.annotation.processing.RoundEnvironment;
29612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.annotation.processing.SupportedAnnotationTypes;
30612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.annotation.processing.SupportedSourceVersion;
31612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.lang.model.SourceVersion;
32612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.lang.model.element.Element;
33612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.lang.model.element.ElementKind;
34612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.lang.model.element.ExecutableElement;
35612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.lang.model.element.Modifier;
36612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.lang.model.element.TypeElement;
37612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.lang.model.element.VariableElement;
38612997fe2e41366573855f56898b27d4c8787244George Mountimport javax.tools.Diagnostic;
39612997fe2e41366573855f56898b27d4c8787244George Mount
40612997fe2e41366573855f56898b27d4c8787244George Mount@SupportedAnnotationTypes({"android.binding.BindingAdapter"})
41612997fe2e41366573855f56898b27d4c8787244George Mount@SupportedSourceVersion(SourceVersion.RELEASE_7)
42612997fe2e41366573855f56898b27d4c8787244George Mountpublic class ProcessBindingAdapters extends AbstractProcessor {
43612997fe2e41366573855f56898b27d4c8787244George Mount    private boolean mProcessed;
44612997fe2e41366573855f56898b27d4c8787244George Mount
45612997fe2e41366573855f56898b27d4c8787244George Mount    public ProcessBindingAdapters() {
46612997fe2e41366573855f56898b27d4c8787244George Mount    }
47612997fe2e41366573855f56898b27d4c8787244George Mount
48612997fe2e41366573855f56898b27d4c8787244George Mount    @Override
49612997fe2e41366573855f56898b27d4c8787244George Mount    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
50612997fe2e41366573855f56898b27d4c8787244George Mount        if (mProcessed) {
51612997fe2e41366573855f56898b27d4c8787244George Mount            return true;
52612997fe2e41366573855f56898b27d4c8787244George Mount        }
53612997fe2e41366573855f56898b27d4c8787244George Mount
54612997fe2e41366573855f56898b27d4c8787244George Mount        BindingAdapterStore store = BindingAdapterStore.get();
55612997fe2e41366573855f56898b27d4c8787244George Mount        for (Element element : roundEnv.getElementsAnnotatedWith(BindingAdapter.class)) {
56612997fe2e41366573855f56898b27d4c8787244George Mount            TypeElement containingClass = (TypeElement) element.getEnclosingElement();
57612997fe2e41366573855f56898b27d4c8787244George Mount            store.clear(containingClass);
58612997fe2e41366573855f56898b27d4c8787244George Mount        }
59612997fe2e41366573855f56898b27d4c8787244George Mount        for (Element element : roundEnv.getElementsAnnotatedWith(BindingAdapter.class)) {
60612997fe2e41366573855f56898b27d4c8787244George Mount            if (element.getKind() != ElementKind.METHOD ||
61612997fe2e41366573855f56898b27d4c8787244George Mount                    !element.getModifiers().contains(Modifier.STATIC)) {
62612997fe2e41366573855f56898b27d4c8787244George Mount                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
63612997fe2e41366573855f56898b27d4c8787244George Mount                        "@BindingAdapter on invalid element: " + element);
64612997fe2e41366573855f56898b27d4c8787244George Mount                continue;
65612997fe2e41366573855f56898b27d4c8787244George Mount            }
66612997fe2e41366573855f56898b27d4c8787244George Mount            BindingAdapter bindingAdapter = element.getAnnotation(BindingAdapter.class);
67612997fe2e41366573855f56898b27d4c8787244George Mount
68612997fe2e41366573855f56898b27d4c8787244George Mount            ExecutableElement executableElement = (ExecutableElement) element;
69612997fe2e41366573855f56898b27d4c8787244George Mount            List<? extends VariableElement> parameters = executableElement.getParameters();
70612997fe2e41366573855f56898b27d4c8787244George Mount            if (parameters.size() != 2) {
71612997fe2e41366573855f56898b27d4c8787244George Mount                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
72612997fe2e41366573855f56898b27d4c8787244George Mount                        "@BindingAdapter does not take two parameters: " + element);
73612997fe2e41366573855f56898b27d4c8787244George Mount                continue;
74612997fe2e41366573855f56898b27d4c8787244George Mount            }
75612997fe2e41366573855f56898b27d4c8787244George Mount            TypeElement containingClass = (TypeElement) executableElement.getEnclosingElement();
76612997fe2e41366573855f56898b27d4c8787244George Mount            try {
77612997fe2e41366573855f56898b27d4c8787244George Mount                store.add(bindingAdapter.attribute(), parameters.get(0).asType(),
78612997fe2e41366573855f56898b27d4c8787244George Mount                        parameters.get(1).asType(), containingClass, executableElement);
79612997fe2e41366573855f56898b27d4c8787244George Mount            } catch (IllegalArgumentException e) {
80612997fe2e41366573855f56898b27d4c8787244George Mount                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
81612997fe2e41366573855f56898b27d4c8787244George Mount                        "@BindingAdapter for duplicate View and parameter type: " + element);
82612997fe2e41366573855f56898b27d4c8787244George Mount            }
83612997fe2e41366573855f56898b27d4c8787244George Mount        }
84612997fe2e41366573855f56898b27d4c8787244George Mount        try {
85612997fe2e41366573855f56898b27d4c8787244George Mount            store.write();
86612997fe2e41366573855f56898b27d4c8787244George Mount        } catch (IOException e) {
87612997fe2e41366573855f56898b27d4c8787244George Mount            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
88612997fe2e41366573855f56898b27d4c8787244George Mount                    "Could not write BindingAdapter intermediate file: " + e.getLocalizedMessage());
89612997fe2e41366573855f56898b27d4c8787244George Mount            e.printStackTrace();
90612997fe2e41366573855f56898b27d4c8787244George Mount        }
91612997fe2e41366573855f56898b27d4c8787244George Mount        mProcessed = true;
92612997fe2e41366573855f56898b27d4c8787244George Mount        return true;
93612997fe2e41366573855f56898b27d4c8787244George Mount    }
94612997fe2e41366573855f56898b27d4c8787244George Mount}
95