All Downloads are FREE. Search and download functionalities are using the official Maven repository.

android.databinding.tool.DataBinder Maven / Gradle / Ivy

Go to download

The annotation processor for Data Binding. Generates binding classes for runtime.

The newest version!
/*
 * 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 android.databinding.tool;

import android.databinding.tool.processing.Scope;
import android.databinding.tool.processing.ScopedException;
import android.databinding.tool.store.ResourceBundle;
import android.databinding.tool.util.L;
import android.databinding.tool.util.StringUtils;
import android.databinding.tool.writer.CallbackWrapperWriter;
import android.databinding.tool.writer.ComponentWriter;
import android.databinding.tool.writer.JavaFileWriter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * The main class that handles parsing files and generating classes.
 */
public class DataBinder {
    List mLayoutBinders = new ArrayList();
    private static final String COMPONENT_CLASS = "android.databinding.DataBindingComponent";

    private JavaFileWriter mFileWriter;

    Set mWrittenClasses = new HashSet();

    public DataBinder(ResourceBundle resourceBundle) {
        L.d("reading resource bundle into data binder");
        for (Map.Entry> entry :
                resourceBundle.getLayoutBundles().entrySet()) {
            for (ResourceBundle.LayoutFileBundle bundle : entry.getValue()) {
                try {
                    mLayoutBinders.add(new LayoutBinder(bundle));
                } catch (ScopedException ex) {
                    Scope.defer(ex);
                }
            }
        }
    }
    public List getLayoutBinders() {
        return mLayoutBinders;
    }

    public void sealModels() {
        for (LayoutBinder layoutBinder : mLayoutBinders) {
            layoutBinder.sealModel();
        }
    }

    public void writerBaseClasses(boolean isLibrary) {
        for (LayoutBinder layoutBinder : mLayoutBinders) {
            try {
                Scope.enter(layoutBinder);
                if (isLibrary || layoutBinder.hasVariations()) {
                    String className = layoutBinder.getClassName();
                    String canonicalName = layoutBinder.getPackage() + "." + className;
                    if (mWrittenClasses.contains(canonicalName)) {
                        continue;
                    }
                    L.d("writing data binder base %s", canonicalName);
                    mFileWriter.writeToFile(canonicalName,
                            layoutBinder.writeViewBinderBaseClass(isLibrary));
                    mWrittenClasses.add(canonicalName);
                }
            } catch (ScopedException ex){
                Scope.defer(ex);
            } finally {
                Scope.exit();
            }
        }
    }

    public void writeBinders(int minSdk) {
        writeCallbackWrappers(minSdk);
        for (LayoutBinder layoutBinder : mLayoutBinders) {
            try {
                Scope.enter(layoutBinder);
                String className = layoutBinder.getImplementationName();
                String canonicalName = layoutBinder.getPackage() + "." + className;
                L.d("writing data binder %s", canonicalName);
                mWrittenClasses.add(canonicalName);
                mFileWriter.writeToFile(canonicalName, layoutBinder.writeViewBinder(minSdk));
            } catch (ScopedException ex) {
                Scope.defer(ex);
            } finally {
                Scope.exit();
            }
        }
    }

    private void writeCallbackWrappers(int minSdk) {
        Map uniqueWrappers = new HashMap();
        Set classNames = new HashSet();
        int callbackCounter = 0;
        for (LayoutBinder binder : mLayoutBinders) {
            for (Map.Entry entry : binder.getModel().getCallbackWrappers()
                    .entrySet()) {
                final CallbackWrapper existing = uniqueWrappers.get(entry.getKey());
                if (existing == null) {
                    // first time seeing this. register
                    final CallbackWrapper wrapper = entry.getValue();
                    uniqueWrappers.put(entry.getKey(), wrapper);
                    String listenerName = makeUnique(classNames, wrapper.klass.getSimpleName());
                    String methodName = makeUnique(classNames,
                            "_internalCallback" + StringUtils.capitalize(wrapper.method.getName()));
                    wrapper.prepare(listenerName, methodName);
                } else {
                    // fill from previous
                    entry.getValue()
                            .prepare(existing.getClassName(), existing.getListenerMethodName());
                }

            }
        }

        // now write the original wrappers
        for (CallbackWrapper wrapper : uniqueWrappers.values()) {
            final String code = new CallbackWrapperWriter(wrapper).write();
            String className = wrapper.getClassName();
            String canonicalName = wrapper.getPackage() + "." + className;
            mFileWriter.writeToFile(canonicalName, code);
            // these will be deleted for library projects.
            mWrittenClasses.add(canonicalName);
        }

    }

    private String makeUnique(Set existing, String wanted) {
        int cnt = 1;
        while (existing.contains(wanted)) {
            wanted = wanted + cnt;
            cnt++;
        }
        existing.add(wanted);
        return wanted;
    }

    public void writeComponent() {
        ComponentWriter componentWriter = new ComponentWriter();

        mWrittenClasses.add(COMPONENT_CLASS);
        mFileWriter.writeToFile(COMPONENT_CLASS, componentWriter.createComponent());
    }

    public Set getWrittenClassNames() {
        return mWrittenClasses;
    }

    public void setFileWriter(JavaFileWriter fileWriter) {
        mFileWriter = fileWriter;
    }

    public JavaFileWriter getFileWriter() {
        return mFileWriter;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy