• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.idegen;
18 
19 import com.google.common.base.Objects;
20 import com.google.common.collect.ImmutableList;
21 import com.google.common.collect.Sets;
22 import com.google.common.io.Files;
23 
24 import java.io.File;
25 import java.io.IOException;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.logging.Logger;
29 
30 /**
31  * Super class for all modules.
32  */
33 public abstract class Module {
34 
35     private static final Logger logger = Logger.getLogger(Module.class.getName());
36 
37     private static final String IML_TEMPLATE_FILE_NAME = "module-template.iml";
38 
39     /**
40      * All possible attributes for the make file.
41      */
42     protected enum Key {
43         LOCAL_STATIC_JAVA_LIBRARIES,
44         LOCAL_JAVA_LIBRARIES,
45         LOCAL_SRC_FILES
46     }
47 
48     ModuleCache moduleCache = ModuleCache.getInstance();
49 
50     private File imlFile;
51 
52     private Set<String> allDependencies = Sets.newHashSet(); // direct + indirect
53 
54     private Set<File> allDependentImlFiles = Sets.newHashSet();
55 
build()56     protected abstract void build() throws IOException;
57 
getName()58     protected abstract String getName();
59 
getDir()60     protected abstract File getDir();
61 
isAndroidModule()62     protected abstract boolean isAndroidModule();
63 
getIntermediatesDirs()64     protected abstract List<File> getIntermediatesDirs();
65 
getDirectDependencies()66     public abstract Set<String> getDirectDependencies();
67 
getSourceDirs()68     protected abstract ImmutableList<File> getSourceDirs();
69 
getExcludeDirs()70     protected abstract ImmutableList<File> getExcludeDirs();
71 
getRepoRoot()72     public abstract File getRepoRoot();
73 
buildImlFile()74     public void buildImlFile() throws IOException {
75         String imlTemplate = Files.toString(
76                 new File(DirectorySearch.findTemplateDir(), IML_TEMPLATE_FILE_NAME),
77                 IntellijProject.CHARSET);
78 
79         String facetXml = "";
80         if (isAndroidModule()) {
81             facetXml = buildAndroidFacet();
82         }
83         imlTemplate = imlTemplate.replace("@FACETS@", facetXml);
84 
85         String moduleDir = getDir().getAbsolutePath();
86 
87         StringBuilder sourceDirectories = new StringBuilder();
88         sourceDirectories.append("    <content url=\"file://$MODULE_DIR$\">\n");
89         ImmutableList<File> srcDirs = getSourceDirs();
90         for (File src : srcDirs) {
91             String relative = src.getAbsolutePath().substring(moduleDir.length());
92             sourceDirectories.append("      <sourceFolder url=\"file://$MODULE_DIR$")
93                     .append(relative).append("\" isTestSource=\"false\" />\n");
94         }
95         ImmutableList<File> excludeDirs = getExcludeDirs();
96         for (File src : excludeDirs) {
97             String relative = src.getAbsolutePath().substring(moduleDir.length());
98             sourceDirectories.append("      <excludeFolder url=\"file://$MODULE_DIR$")
99                     .append(relative).append("\"/>\n");
100         }
101         sourceDirectories.append("    </content>\n");
102 
103         // Intermediates.
104         sourceDirectories.append(buildIntermediates());
105 
106         imlTemplate = imlTemplate.replace("@SOURCES@", sourceDirectories.toString());
107 
108         StringBuilder moduleDependencies = new StringBuilder();
109         for (String dependency : getDirectDependencies()) {
110             moduleDependencies.append("    <orderEntry type=\"module\" module-name=\"")
111                     .append(dependency).append("\" />\n");
112         }
113         imlTemplate = imlTemplate.replace("@MODULE_DEPENDENCIES@", moduleDependencies.toString());
114 
115         imlFile = new File(moduleDir, getName() + ".iml");
116         logger.info("Creating " + imlFile.getAbsolutePath());
117         Files.write(imlTemplate, imlFile, IntellijProject.CHARSET);
118     }
119 
buildIntermediates()120     protected String buildIntermediates() {
121         StringBuilder sb = new StringBuilder();
122         for (File intermediatesDir : getIntermediatesDirs()) {
123             sb.append("    <content url=\"file://").append(intermediatesDir).append("\">\n");
124             sb.append("      <sourceFolder url=\"file://")
125                     .append(intermediatesDir.getAbsolutePath())
126                     .append("\" isTestSource=\"false\" />\n");
127             sb.append("    </content>\n");
128         }
129         return sb.toString();
130     }
131 
buildDependentModules()132     protected void buildDependentModules() throws IOException {
133         Set<String> directDependencies = getDirectDependencies();
134         String[] copy = directDependencies.toArray(new String[directDependencies.size()]);
135         for (String dependency : copy) {
136 
137             Module child = moduleCache.getAndCache(dependency);
138             if (child == null) {
139                 directDependencies.remove(dependency);
140             } else {
141                 addAllDependencies(dependency);
142                 addAllDependencies(child.getAllDependencies());
143                 //logger.info("Adding iml " + child.getName() + " " + child.getImlFile());
144                 allDependentImlFiles.add(child.getImlFile());
145                 allDependentImlFiles.addAll(child.getAllDependentImlFiles());
146             }
147         }
148     }
149 
getImlFile()150     public File getImlFile() {
151         return imlFile;
152     }
153 
getAllDependencies()154     public Set<String> getAllDependencies() {
155         return allDependencies;
156     }
157 
addAllDependencies(String dependency)158     public void addAllDependencies(String dependency) {
159         this.allDependencies.add(dependency);
160     }
161 
addAllDependencies(Set<String> dependencies)162     public void addAllDependencies(Set<String> dependencies) {
163         this.allDependencies.addAll(dependencies);
164     }
165 
getAllDependentImlFiles()166     public Set<File> getAllDependentImlFiles() {
167         return allDependentImlFiles;
168     }
169 
buildAndroidFacet()170     private String buildAndroidFacet() {
171         // Not sure how to handle android facet for multi-module since there could be more than
172         // one intermediates directory.
173         String dir = getIntermediatesDirs().get(0).getAbsolutePath();
174         String xml = ""
175                 + "  <component name=\"FacetManager\">\n"
176                 + "    <facet type=\"android\" name=\"Android\">\n"
177                 + "      <configuration>\n"
178                 + "        <option name=\"GEN_FOLDER_RELATIVE_PATH_APT\" value=\"" + dir + "\" />\n"
179                 + "        <option name=\"GEN_FOLDER_RELATIVE_PATH_AIDL\" value=\"" + dir
180                 + "\" />\n"
181                 + "        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\""
182                 + "/AndroidManifest.xml\" />\n"
183                 + "        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/res\" />\n"
184                 + "        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/assets\" />\n"
185                 + "        <option name=\"LIBS_FOLDER_RELATIVE_PATH\" value=\"/libs\" />\n"
186                 + "        <option name=\"REGENERATE_R_JAVA\" value=\"true\" />\n"
187                 + "        <option name=\"REGENERATE_JAVA_BY_AIDL\" value=\"true\" />\n"
188                 + "        <option name=\"USE_CUSTOM_APK_RESOURCE_FOLDER\" value=\"false\" />\n"
189                 + "        <option name=\"CUSTOM_APK_RESOURCE_FOLDER\" value=\"\" />\n"
190                 + "        <option name=\"USE_CUSTOM_COMPILER_MANIFEST\" value=\"false\" />\n"
191                 + "        <option name=\"CUSTOM_COMPILER_MANIFEST\" value=\"\" />\n"
192                 + "        <option name=\"APK_PATH\" value=\"\" />\n"
193                 + "        <option name=\"LIBRARY_PROJECT\" value=\"false\" />\n"
194                 + "        <option name=\"RUN_PROCESS_RESOURCES_MAVEN_TASK\" value=\"true\" />\n"
195                 + "        <option name=\"GENERATE_UNSIGNED_APK\" value=\"false\" />\n"
196                 + "      </configuration>\n"
197                 + "    </facet>\n"
198                 + "  </component>\n";
199         return xml;
200     }
201 
202     @Override
toString()203     public String toString() {
204         return Objects.toStringHelper(Module.class)
205                 .add("name", getName())
206                 .add("allDependencies", allDependencies)
207                 .add("iml files", allDependentImlFiles)
208                 .add("imlFile", imlFile)
209                 .toString();
210     }
211 }
212 
213