org.gradle.plugins.ide.idea.model.Module Maven / Gradle / Ivy
/*
* Copyright 2011 the original author or authors.
*
* 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 org.gradle.plugins.ide.idea.model;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import groovy.util.Node;
import org.gradle.api.Nullable;
import org.gradle.internal.xml.XmlTransformer;
import org.gradle.plugins.ide.internal.generator.XmlPersistableConfigurationObject;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Strings.isNullOrEmpty;
/**
* Represents the customizable elements of an iml (via XML hooks everything of the iml is customizable).
*/
public class Module extends XmlPersistableConfigurationObject {
public static final String INHERITED = "inherited";
private Path contentPath;
private Set sourceFolders = Sets.newLinkedHashSet();
private Set testSourceFolders = Sets.newLinkedHashSet();
private Set generatedSourceFolders = Sets.newLinkedHashSet();
private Set excludeFolders = Sets.newLinkedHashSet();
private boolean inheritOutputDirs;
private Path outputDir;
private Path testOutputDir;
private Set dependencies = Sets.newLinkedHashSet();
private String jdkName;
private final PathFactory pathFactory;
private String languageLevel;
public Module(XmlTransformer withXmlActions, PathFactory pathFactory) {
super(withXmlActions);
this.pathFactory = pathFactory;
}
/**
* The directory for the content root of the module.
* Defaults to the project directory.
* If null, the directory containing the output file will be used.
*/
public Path getContentPath() {
return contentPath;
}
public void setContentPath(Path contentPath) {
this.contentPath = contentPath;
}
/**
* The directories containing the production sources.
* Must not be null.
*/
public Set getSourceFolders() {
return sourceFolders;
}
public void setSourceFolders(Set sourceFolders) {
this.sourceFolders = sourceFolders;
}
/**
* The directories containing the test sources.
* Must not be null.
*/
public Set getTestSourceFolders() {
return testSourceFolders;
}
public void setTestSourceFolders(Set testSourceFolders) {
this.testSourceFolders = testSourceFolders;
}
/**
* The directories containing generated the production sources.
* Must not be null.
*/
public Set getGeneratedSourceFolders() {
return generatedSourceFolders;
}
public void setGeneratedSourceFolders(Set generatedSourceFolders) {
this.generatedSourceFolders = generatedSourceFolders;
}
/**
* The directories to be excluded.
* Must not be null.
*/
public Set getExcludeFolders() {
return excludeFolders;
}
public void setExcludeFolders(Set excludeFolders) {
this.excludeFolders = excludeFolders;
}
/**
* If true, output directories for this module will be located below the output directory for the project;
* otherwise, {@link #outputDir} and {@link #testOutputDir} will take effect.
*/
public boolean isInheritOutputDirs() {
return inheritOutputDirs;
}
public boolean getInheritOutputDirs() {
return inheritOutputDirs;
}
public void setInheritOutputDirs(boolean inheritOutputDirs) {
this.inheritOutputDirs = inheritOutputDirs;
}
/**
* The output directory for production classes.
* If {@code null}, no entry will be created.
*/
public Path getOutputDir() {
return outputDir;
}
public void setOutputDir(Path outputDir) {
this.outputDir = outputDir;
}
/**
* The output directory for test classes.
* If {@code null}, no entry will be created.
*/
public Path getTestOutputDir() {
return testOutputDir;
}
public void setTestOutputDir(Path testOutputDir) {
this.testOutputDir = testOutputDir;
}
/**
* The dependencies of this module.
* Must not be null.
*/
public Set getDependencies() {
return dependencies;
}
public void setDependencies(Set dependencies) {
this.dependencies = dependencies;
}
public String getJdkName() {
return jdkName;
}
public void setJdkName(String jdkName) {
this.jdkName = jdkName;
}
@Override
protected String getDefaultResourceName() {
return "defaultModule.xml";
}
protected Object configure(Path contentPath,
Set sourceFolders, Set testSourceFolders, Set generatedSourceFolders, Set excludeFolders,
Boolean inheritOutputDirs, Path outputDir, Path testOutputDir,
Set dependencies, String jdkName, String languageLevel) {
this.languageLevel = languageLevel;
this.contentPath = contentPath;
this.sourceFolders.addAll(sourceFolders);
this.excludeFolders.addAll(excludeFolders);
this.testSourceFolders.addAll(testSourceFolders);
this.generatedSourceFolders.addAll(generatedSourceFolders);
if (inheritOutputDirs != null) {
this.inheritOutputDirs = inheritOutputDirs;
}
if (outputDir != null) {
this.outputDir = outputDir;
}
if (testOutputDir != null) {
this.testOutputDir = testOutputDir;
}
this.dependencies = dependencies; // overwrite rather than append dependencies
if (!isNullOrEmpty(jdkName)) {
this.jdkName = jdkName;
} else {
this.jdkName = Module.INHERITED;
}
return this.jdkName;
}
@Override
protected void load(Node xml) {
readJdkFromXml();
readSourceAndExcludeFolderFromXml();
readInheritOutputDirsFromXml();
readOutputDirsFromXml();
readDependenciesFromXml();
}
@Override
protected void store(Node xml) {
addJdkToXml();
setContentURL();
removeSourceAndExcludeFolderFromXml();
addSourceAndExcludeFolderToXml();
writeInheritOutputDirsToXml();
writeSourceLanguageLevel();
addOutputDirsToXml();
removeDependenciesFromXml();
addDependenciesToXml();
}
private void readJdkFromXml() {
Node jdk = findFirstWithAttributeValue(findOrderEntries(), "type", "jdk");
jdkName = jdk != null ? (String) jdk.attribute("jdkName") : INHERITED;
}
private void readSourceAndExcludeFolderFromXml() {
for (Node sourceFolder : findSourceFolder()) {
String url = (String) sourceFolder.attribute("url");
if ("false".equals(sourceFolder.attribute("isTestSource"))) {
sourceFolders.add(pathFactory.path(url));
} else {
testSourceFolders.add(pathFactory.path(url));
}
if ("true".equals(sourceFolder.attribute("generated"))) {
generatedSourceFolders.add(pathFactory.path(url));
}
}
for (Node excludeFolder : findExcludeFolder()) {
excludeFolders.add(pathFactory.path((String) excludeFolder.attribute("url")));
}
}
private boolean readInheritOutputDirsFromXml() {
return inheritOutputDirs = "true".equals(getNewModuleRootManager().attribute("inherit-compiler-output"));
}
private Path readOutputDirsFromXml() {
Node outputDirNode = findOutputDir();
Node testOutputDirNode = findTestOutputDir();
String outputDirUrl = outputDirNode != null ? (String) outputDirNode.attribute("url") : null;
String testOutputDirUrl = testOutputDirNode != null ? (String) testOutputDirNode.attribute("url") : null;
outputDir = outputDirUrl != null ? pathFactory.path(outputDirUrl) : null;
return testOutputDir = testOutputDirUrl != null ? pathFactory.path(testOutputDirUrl) : null;
}
private void readDependenciesFromXml() {
for (Node orderEntry : findOrderEntries()) {
Object orderEntryType = orderEntry.attribute("type");
if ("module-library".equals(orderEntryType)) {
Set classes = Sets.newLinkedHashSet();
Set javadoc = Sets.newLinkedHashSet();
Set sources = Sets.newLinkedHashSet();
Set jarDirectories = Sets.newLinkedHashSet();
for (Node library : getChildren(orderEntry, "library")) {
for (Node classesNode : getChildren(library, "CLASSES")) {
readDependenciesPathsFromXml(classes, classesNode);
}
for (Node javadocNode : getChildren(library, "JAVADOC")) {
readDependenciesPathsFromXml(javadoc, javadocNode);
}
for (Node sourcesNode : getChildren(library, "SOURCES")) {
readDependenciesPathsFromXml(sources, sourcesNode);
}
for (Node jarDirNode : getChildren(library, "jarDirectory")) {
jarDirectories.add(new JarDirectory(pathFactory.path((String) jarDirNode.attribute("url")), Boolean.parseBoolean((String) jarDirNode.attribute("recursive"))));
}
}
ModuleLibrary moduleLibrary = new ModuleLibrary(classes, javadoc, sources, jarDirectories, (String) orderEntry.attribute("scope"));
dependencies.add(moduleLibrary);
} else if ("module".equals(orderEntryType)) {
dependencies.add(new ModuleDependency((String) orderEntry.attribute("module-name"), (String) orderEntry.attribute("scope")));
}
}
}
private void readDependenciesPathsFromXml(Set paths, Node node) {
for (Node classesRoot : getChildren(node, "root")) {
paths.add(pathFactory.path((String) classesRoot.attribute("url")));
}
}
private void addJdkToXml() {
Preconditions.checkNotNull(jdkName);
List orderEntries = findOrderEntries();
Node moduleJdk = findFirstWithAttributeValue(orderEntries, "type", "jdk");
Node moduleRootManager = getNewModuleRootManager();
if (!jdkName.equals(INHERITED)) {
Node inheritedJdk = findFirstWithAttributeValue(orderEntries, "type", "inheritedJdk");
if (inheritedJdk != null) {
inheritedJdk.parent().remove(inheritedJdk);
}
if (moduleJdk != null) {
moduleRootManager.remove(moduleJdk);
}
Map attributes = Maps.newHashMapWithExpectedSize(3);
attributes.put("type", "jdk");
attributes.put("jdkName", jdkName);
attributes.put("jdkType", "JavaSDK");
moduleRootManager.appendNode("orderEntry", attributes);
} else if (findFirstWithAttributeValue(orderEntries, "type", "inheritedJdk") == null) {
if (moduleJdk != null) {
moduleRootManager.remove(moduleJdk);
}
Map attributes = Maps.newHashMapWithExpectedSize(1);
attributes.put("type", "inheritedJdk");
moduleRootManager.appendNode("orderEntry", attributes);
}
}
private void setContentURL() {
if (contentPath != null) {
getContentNode().attributes().put("url", contentPath.getUrl());
}
}
private void removeSourceAndExcludeFolderFromXml() {
Node content = getContentNode();
for (Node sourceFolder : findSourceFolder()) {
content.remove(sourceFolder);
}
for (Node excludeFolder : findExcludeFolder()) {
content.remove(excludeFolder);
}
}
private void addSourceAndExcludeFolderToXml() {
Node content = getContentNode();
for (Path path : sourceFolders) {
Map attributes = Maps.newHashMapWithExpectedSize(3);
attributes.put("url", path.getUrl());
attributes.put("isTestSource", "false");
if (generatedSourceFolders.contains(path)) {
attributes.put("generated", "true");
}
content.appendNode("sourceFolder", attributes);
}
for (Path path : testSourceFolders) {
Map attributes = Maps.newHashMapWithExpectedSize(3);
attributes.put("url", path.getUrl());
attributes.put("isTestSource", "true");
if (generatedSourceFolders.contains(path)) {
attributes.put("generated", "true");
}
content.appendNode("sourceFolder", attributes);
}
for (Path path : excludeFolders) {
Map attributes = Maps.newHashMapWithExpectedSize(1);
attributes.put("url", path.getUrl());
content.appendNode("excludeFolder", attributes);
}
}
private void writeInheritOutputDirsToXml() {
getNewModuleRootManager().attributes().put("inherit-compiler-output", inheritOutputDirs);
}
private void writeSourceLanguageLevel() {
if (languageLevel != null) {
getNewModuleRootManager().attributes().put("LANGUAGE_LEVEL", languageLevel);
}
}
private void addOutputDirsToXml() {
if (outputDir != null) {
findOrCreateOutputDir().attributes().put("url", outputDir.getUrl());
}
if (testOutputDir != null) {
findOrCreateTestOutputDir().attributes().put("url", testOutputDir.getUrl());
}
}
private void removeDependenciesFromXml() {
Node moduleRoot = getNewModuleRootManager();
for (Node orderEntry : findOrderEntries()) {
if (isDependencyOrderEntry(orderEntry)) {
moduleRoot.remove(orderEntry);
}
}
}
protected boolean isDependencyOrderEntry(Object orderEntry) {
return Arrays.asList("module-library", "module").contains(((Node)orderEntry).attribute("type"));
}
private void addDependenciesToXml() {
Node moduleRoot = getNewModuleRootManager();
for (Dependency dependency : dependencies) {
dependency.addToNode(moduleRoot);
}
}
private Node getNewModuleRootManager() {
Node newModuleRootManager = findFirstWithAttributeValue(getChildren(getXml(), "component"), "name", "NewModuleRootManager");
Preconditions.checkNotNull(newModuleRootManager);
return newModuleRootManager;
}
private Node findOrCreateOutputDir() {
Node outputDirNode = findOutputDir();
if (outputDirNode != null) {
return outputDirNode;
}
return getNewModuleRootManager().appendNode("output");
}
private Node findOrCreateTestOutputDir() {
Node testOutputDirNode = findTestOutputDir();
if (testOutputDirNode != null) {
return testOutputDirNode;
}
return getNewModuleRootManager().appendNode("output-test");
}
private Node getContentNode() {
Node contentNode = findFirstChildNamed(getNewModuleRootManager(), "content");
Preconditions.checkNotNull(contentNode);
return contentNode;
}
private List findSourceFolder() {
return getChildren(getContentNode(), "sourceFolder");
}
private List findExcludeFolder() {
return getChildren(getContentNode(), "excludeFolder");
}
@Nullable
private Node findOutputDir() {
return findFirstChildNamed(getNewModuleRootManager(), "output");
}
@Nullable
private Node findTestOutputDir() {
return findFirstChildNamed(getNewModuleRootManager(), "output-test");
}
private List findOrderEntries() {
return getChildren(getNewModuleRootManager(), "orderEntry");
}
@Override
public String toString() {
return "Module{"
+ "dependencies=" + dependencies
+ ", sourceFolders=" + sourceFolders
+ ", testSourceFolders=" + testSourceFolders
+ ", generatedSourceFolders=" + generatedSourceFolders
+ ", excludeFolders=" + excludeFolders
+ ", inheritOutputDirs=" + inheritOutputDirs
+ ", jdkName=" + jdkName
+ ", outputDir=" + outputDir
+ ", testOutputDir=" + testOutputDir + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!getClass().equals(o.getClass())) {
return false;
}
Module module = (Module) o;
return Objects.equal(dependencies, module.dependencies)
&& Objects.equal(excludeFolders, module.excludeFolders)
&& Objects.equal(outputDir, module.outputDir)
&& Objects.equal(sourceFolders, module.sourceFolders)
&& Objects.equal(generatedSourceFolders, module.generatedSourceFolders)
&& Objects.equal(jdkName, module.jdkName)
&& Objects.equal(testOutputDir, module.testOutputDir)
&& Objects.equal(testSourceFolders, module.testSourceFolders);
}
@Override
public int hashCode() {
return Objects.hashCode(sourceFolders, generatedSourceFolders, testSourceFolders, excludeFolders, inheritOutputDirs, jdkName, outputDir, testOutputDir, dependencies);
}
public static String getINHERITED() {
return INHERITED;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy