ProcessExpressions.java revision b6887f1479c3ecec38a7989748ef33de1fbcd973
197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar/*
297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar *
497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * you may not use this file except in compliance with the License.
697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * You may obtain a copy of the License at
797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar *
897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar *
1097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Unless required by applicable law or agreed to in writing, software
1197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
1297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * See the License for the specific language governing permissions and
1497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * limitations under the License.
1597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar */
1697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.annotationprocessor;
18e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount
19b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyarimport com.google.common.base.Preconditions;
20b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar
21a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport org.apache.commons.io.FileUtils;
221b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport org.apache.commons.io.IOUtils;
23b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyarimport org.apache.commons.lang3.StringUtils;
241b9940e612fc73202837fbe9db2f9035f307b5d1George Mount
25fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.BindingBuildInfo;
26fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.CompilerChef;
27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.SdkUtil;
28fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.ResourceBundle;
29fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.GenerationalClassUtil;
30fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L;
311b9940e612fc73202837fbe9db2f9035f307b5d1George Mount
3297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarimport java.io.File;
33a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.io.FilenameFilter;
34e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mountimport java.io.IOException;
35a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.io.InputStream;
36a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.io.Serializable;
37a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.HashMap;
38a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.List;
39a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.Map;
40b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyarimport java.util.Set;
41e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount
42a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport javax.annotation.processing.ProcessingEnvironment;
43e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mountimport javax.annotation.processing.RoundEnvironment;
448e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.JAXBContext;
458e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.JAXBException;
468e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.Unmarshaller;
47e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount
48a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarpublic class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
498e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount
50a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    private static final String LAYOUT_INFO_FILE_SUFFIX = "-layoutinfo.bin";
51a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
5261630faa88ee4817834d47294a0e17f19d8e1c51George Mount    private final ProcessBindable mProcessBindable;
5361630faa88ee4817834d47294a0e17f19d8e1c51George Mount
5461630faa88ee4817834d47294a0e17f19d8e1c51George Mount    public ProcessExpressions(ProcessBindable processBindable) {
5561630faa88ee4817834d47294a0e17f19d8e1c51George Mount        mProcessBindable = processBindable;
5661630faa88ee4817834d47294a0e17f19d8e1c51George Mount    }
5761630faa88ee4817834d47294a0e17f19d8e1c51George Mount
5861630faa88ee4817834d47294a0e17f19d8e1c51George Mount
59a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    @Override
60a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    public boolean onHandleStep(RoundEnvironment roundEnvironment,
61a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            ProcessingEnvironment processingEnvironment, BindingBuildInfo buildInfo) {
62a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        ResourceBundle resourceBundle;
63a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        SdkUtil.initialize(buildInfo.minSdk(), new File(buildInfo.sdkRoot()));
64a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        resourceBundle = new ResourceBundle(buildInfo.modulePackage());
65a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        List<Intermediate> intermediateList =
66a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                GenerationalClassUtil.loadObjects(getClass().getClassLoader(),
67a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                        new GenerationalClassUtil.ExtensionFilter(LAYOUT_INFO_FILE_SUFFIX));
68a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        IntermediateV1 mine = createIntermediateFromLayouts(buildInfo.layoutInfoDir());
69a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        if (mine != null) {
70a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            mine.removeOverridden(intermediateList);
71a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            intermediateList.add(mine);
72a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            saveIntermediate(processingEnvironment, buildInfo, mine);
73a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        }
74a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        // generate them here so that bindable parser can read
75a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        try {
76a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            generateBinders(resourceBundle, buildInfo, intermediateList);
77a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        } catch (Throwable t) {
78a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            L.e(t, "cannot generate view binders");
79a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        }
80a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        return true;
81a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    }
82a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
83a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    private void saveIntermediate(ProcessingEnvironment processingEnvironment,
84a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            BindingBuildInfo buildInfo, IntermediateV1 intermediate) {
85a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        GenerationalClassUtil.writeIntermediateFile(processingEnvironment,
86a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                buildInfo.modulePackage(), buildInfo.modulePackage() + LAYOUT_INFO_FILE_SUFFIX,
87a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                intermediate);
88a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    }
89a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
90a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    @Override
91a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    public void onProcessingOver(RoundEnvironment roundEnvironment,
92a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            ProcessingEnvironment processingEnvironment, BindingBuildInfo buildInfo) {
93a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    }
94a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
95a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    private void generateBinders(ResourceBundle resourceBundle, BindingBuildInfo buildInfo,
96a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            List<Intermediate> intermediates)
97a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            throws Throwable {
98a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        for (Intermediate intermediate : intermediates) {
99a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            intermediate.appendTo(resourceBundle);
100a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        }
101b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar        writeResourceBundle(resourceBundle, buildInfo.isLibrary(), buildInfo.minSdk(),
102b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar                buildInfo.exportClassListTo());
103a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    }
104a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
105a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    private IntermediateV1 createIntermediateFromLayouts(String layoutInfoFolderPath) {
106a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        final File layoutInfoFolder = new File(layoutInfoFolderPath);
107a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        if (!layoutInfoFolder.isDirectory()) {
108a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            L.d("layout info folder does not exist, skipping for %s", layoutInfoFolderPath);
109a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            return null;
110a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        }
111a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        IntermediateV1 result = new IntermediateV1();
112a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        for (File layoutFile : layoutInfoFolder.listFiles(new FilenameFilter() {
113a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            @Override
114a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            public boolean accept(File dir, String name) {
115a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                return name.endsWith(".xml");
11600da715547ee7d5d38a3b8576090ca427a94daa5George Mount            }
117a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        })) {
118a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            try {
119a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                result.addEntry(layoutFile.getName(), FileUtils.readFileToString(layoutFile));
120a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            } catch (IOException e) {
121a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                L.e(e, "cannot load layout file information. Try a clean build");
1221b9940e612fc73202837fbe9db2f9035f307b5d1George Mount            }
123a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        }
124a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        return result;
125a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    }
126a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
127e7c2a5e45d7651899790bd347da635875f9c73fbGeorge Mount    private void writeResourceBundle(ResourceBundle resourceBundle, boolean forLibraryModule,
128b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar            int minSdk, String exportClassNamesTo)
129a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            throws JAXBException {
130a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        CompilerChef compilerChef = CompilerChef.createChef(resourceBundle, getWriter());
131a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        if (compilerChef.hasAnythingToGenerate()) {
13261630faa88ee4817834d47294a0e17f19d8e1c51George Mount            compilerChef.addBRVariables(mProcessBindable);
133dea555cf42dc3583604699c8c018d22681f56166George Mount            compilerChef.writeViewBinderInterfaces(forLibraryModule);
134a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            if (!forLibraryModule) {
13596e1c821dd446d1ed78f8ae61131550588f60a24George Mount                compilerChef.writeViewBinders(minSdk);
1361b9940e612fc73202837fbe9db2f9035f307b5d1George Mount            }
1371b9940e612fc73202837fbe9db2f9035f307b5d1George Mount        }
138b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar        if (forLibraryModule && exportClassNamesTo == null) {
139b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar            L.e("When compiling a library module, build info must include exportClassListTo path");
140b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar        }
141b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar        if (forLibraryModule) {
142b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar            Set<String> classNames = compilerChef.getWrittenClassNames();
143b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar            String out = StringUtils.join(classNames, System.getProperty("line.separator"));
144b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar
145b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar            L.d("Writing list of classes to %s . \nList:%s", exportClassNamesTo, out);
146b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar            try {
147b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar                FileUtils.write(new File(exportClassNamesTo),
148b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar                        out);
149b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar            } catch (IOException e) {
150b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar                L.e(e, "Cannot create list of written classes");
151b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar            }
152b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar        } else {
1531bbaf7cdf7f9d93ae09365192abb2288cf0dfb41George Mount            compilerChef.writeDbrFile(minSdk);
1541bbaf7cdf7f9d93ae09365192abb2288cf0dfb41George Mount        }
155a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    }
156e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount
157a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    public static interface Intermediate extends Serializable {
158a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
159a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        Intermediate upgrade();
160a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
161a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        public void appendTo(ResourceBundle resourceBundle) throws Throwable;
1628e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount    }
1638e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount
164a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    public static class IntermediateV1 implements Intermediate {
165a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
166a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        transient Unmarshaller mUnmarshaller;
167a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
168a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        // name to xml content map
169b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar        Map<String, String> mLayoutInfoMap = new HashMap<String, String>();
170a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
171a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        @Override
172a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        public Intermediate upgrade() {
173a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            return this;
174a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        }
175a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
176a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        @Override
177a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        public void appendTo(ResourceBundle resourceBundle) throws JAXBException {
178a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            if (mUnmarshaller == null) {
179a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                JAXBContext context = JAXBContext
180a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                        .newInstance(ResourceBundle.LayoutFileBundle.class);
181a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                mUnmarshaller = context.createUnmarshaller();
1828e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount            }
183a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            for (String content : mLayoutInfoMap.values()) {
184a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                final InputStream is = IOUtils.toInputStream(content);
185a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                try {
186a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                    final ResourceBundle.LayoutFileBundle bundle
187a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                            = (ResourceBundle.LayoutFileBundle) mUnmarshaller.unmarshal(is);
1880390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount                    resourceBundle.addLayoutBundle(bundle);
189a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                    L.d("loaded layout info file %s", bundle);
190a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                } finally {
191a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                    IOUtils.closeQuietly(is);
1921b9940e612fc73202837fbe9db2f9035f307b5d1George Mount                }
1931b9940e612fc73202837fbe9db2f9035f307b5d1George Mount            }
194a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        }
1958e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount
196a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        public void addEntry(String name, String contents) {
197a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            mLayoutInfoMap.put(name, contents);
1981b9940e612fc73202837fbe9db2f9035f307b5d1George Mount        }
1998e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount
200a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        public void removeOverridden(List<Intermediate> existing) {
201a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            // this is the way we get rid of files that are copied from previous modules
202a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            // it is important to do this before saving the intermediate file
203a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            for (Intermediate old : existing) {
204a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                if (old instanceof IntermediateV1) {
205a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                    IntermediateV1 other = (IntermediateV1) old;
206a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                    for (String key : other.mLayoutInfoMap.keySet()) {
207a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                        // TODO we should consider the original file as the key here
208a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                        // but aapt probably cannot provide that information
209a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                        if (mLayoutInfoMap.remove(key) != null) {
210a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                            L.d("removing %s from bundle because it came from another module", key);
211a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                        }
212a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                    }
213a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar                }
214a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar            }
21500da715547ee7d5d38a3b8576090ca427a94daa5George Mount        }
216e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount    }
217e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount}
218