external builder: building plugin modules

This commit is contained in:
nik
2012-08-02 09:06:56 +04:00
parent 653b294c03
commit 9f6d7c7f5c
27 changed files with 601 additions and 26 deletions
@@ -21,6 +21,7 @@ import org.jetbrains.jps.idea.IdeaProjectLoader;
import org.jetbrains.jps.idea.SystemOutErrorReporter;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.artifacts.ArtifactSourceTimestampStorage;
import org.jetbrains.jps.incremental.artifacts.JpsBuilderArtifactService;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactRootDescriptor;
import org.jetbrains.jps.incremental.fs.BuildFSState;
import org.jetbrains.jps.incremental.fs.RootDescriptor;
@@ -31,7 +32,6 @@ import org.jetbrains.jps.incremental.storage.Timestamps;
import org.jetbrains.jps.model.JpsElementFactory;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.JpsArtifactService;
import org.jetbrains.jps.model.java.JpsJavaLibraryType;
import org.jetbrains.jps.model.library.JpsLibrary;
import org.jetbrains.jps.model.library.JpsOrderRootType;
@@ -618,10 +618,10 @@ final class BuildSession implements Runnable, CanceledStatus {
final Timestamps timestamps = pd.timestamps.getStorage();
Set<JpsArtifact> artifacts = new HashSet<JpsArtifact>();
if (artifactNames.isEmpty() && buildType == BuildType.PROJECT_REBUILD) {
artifacts.addAll(JpsArtifactService.getInstance().getArtifacts(pd.jpsProject));
artifacts.addAll(JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false));
}
else {
for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(pd.jpsProject)) {
for (JpsArtifact artifact : JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false)) {
if (artifactNames.contains(artifact.getName()) && !StringUtil.isEmpty(artifact.getOutputPath())) {
artifacts.add(artifact);
}
@@ -13,7 +13,6 @@ import org.jetbrains.jps.incremental.artifacts.instructions.*;
import org.jetbrains.jps.incremental.storage.BuildDataManager;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.JpsArtifactService;
import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement;
import java.io.File;
@@ -30,7 +29,7 @@ public class ArtifactRootsIndex {
myRootToDescriptorMap = new MultiMap<File, ArtifactRootDescriptor>();
myInstructions = new HashMap<JpsArtifact, ArtifactInstructionsBuilder>();
ArtifactsBuildData data = manager.getArtifactsBuildData();
for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(model.getProject())) {
for (JpsArtifact artifact : JpsBuilderArtifactService.getInstance().getArtifacts(model, true)) {
int artifactId = data.getArtifactId(artifact);
ArtifactInstructionsBuilderImpl builder = new ArtifactInstructionsBuilderImpl(rootsIndex, project.getIgnoredFilePatterns(), artifactId, artifact.getName());
final JpsCompositePackagingElement rootElement = artifact.getRootElement();
@@ -15,8 +15,8 @@ import org.jetbrains.jps.incremental.fs.BuildFSState;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.JpsArtifactService;
import java.io.File;
import java.io.IOException;
@@ -35,14 +35,17 @@ public class IncArtifactBuilder extends ProjectLevelBuilder {
@Override
public void build(CompileContext context) throws ProjectBuildException {
Set<JpsArtifact> affected = new HashSet<JpsArtifact>();
for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(context.getProjectDescriptor().jpsProject)) {
JpsBuilderArtifactService artifactService = JpsBuilderArtifactService.getInstance();
JpsModel model = context.getProjectDescriptor().jpsModel;
for (JpsArtifact artifact : artifactService.getArtifacts(model, false)) {
if (context.getScope().isAffected(artifact)) {
affected.add(artifact);
}
}
affected.addAll(artifactService.getSyntheticArtifacts(model));
final Set<JpsArtifact> toBuild = ArtifactSorter.addIncludedArtifacts(affected);
final ArtifactSorter sorter = new ArtifactSorter(context.getProjectDescriptor().jpsModel);
final ArtifactSorter sorter = new ArtifactSorter(model);
final Map<JpsArtifact, JpsArtifact> selfIncludingNameMap = sorter.getArtifactToSelfIncludingNameMap();
for (JpsArtifact artifact : sorter.getArtifactsSortedByInclusion()) {
context.checkCanceled();
@@ -0,0 +1,22 @@
package org.jetbrains.jps.incremental.artifacts;
import org.jetbrains.jps.incremental.artifacts.impl.JpsBuilderArtifactServiceImpl;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import java.util.Collection;
/**
* @author nik
*/
public abstract class JpsBuilderArtifactService {
private static JpsBuilderArtifactService ourInstance = new JpsBuilderArtifactServiceImpl();
public static JpsBuilderArtifactService getInstance() {
return ourInstance;
}
public abstract Collection<JpsArtifact> getArtifacts(JpsModel model, boolean includeSynthetic);
public abstract Collection<JpsArtifact> getSyntheticArtifacts(JpsModel model);
}
@@ -0,0 +1,15 @@
package org.jetbrains.jps.incremental.artifacts;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import java.util.List;
/**
* @author nik
*/
public abstract class JpsSyntheticArtifactProvider {
@NotNull
public abstract List<JpsArtifact> createArtifacts(@NotNull JpsModel model);
}
@@ -24,10 +24,9 @@ import com.intellij.util.graph.GraphGenerator;
import gnu.trove.TIntArrayList;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.incremental.artifacts.JpsBuilderArtifactService;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.JpsProject;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.JpsArtifactService;
import org.jetbrains.jps.model.artifact.elements.JpsArtifactOutputPackagingElement;
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
@@ -147,7 +146,7 @@ public class ArtifactSorter {
}
private GraphGenerator<JpsArtifact> createArtifactsGraph() {
return GraphGenerator.create(CachingSemiGraph.create(new ArtifactsGraph(myModel.getProject())));
return GraphGenerator.create(CachingSemiGraph.create(new ArtifactsGraph(myModel)));
}
private static void processIncludedArtifacts(JpsArtifact artifact, final Consumer<JpsArtifact> consumer) {
@@ -169,8 +168,8 @@ public class ArtifactSorter {
private static class ArtifactsGraph implements GraphGenerator.SemiGraph<JpsArtifact> {
private final Set<JpsArtifact> myArtifactNodes;
public ArtifactsGraph(final JpsProject project) {
myArtifactNodes = new LinkedHashSet<JpsArtifact>(JpsArtifactService.getInstance().getArtifacts(project));
public ArtifactsGraph(final JpsModel model) {
myArtifactNodes = new LinkedHashSet<JpsArtifact>(JpsBuilderArtifactService.getInstance().getArtifacts(model, true));
}
@Override
@@ -0,0 +1,52 @@
package org.jetbrains.jps.incremental.artifacts.impl;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.jps.incremental.artifacts.JpsBuilderArtifactService;
import org.jetbrains.jps.incremental.artifacts.JpsSyntheticArtifactProvider;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.JpsArtifactService;
import org.jetbrains.jps.model.artifact.impl.JpsArtifactKind;
import org.jetbrains.jps.model.impl.JpsElementCollectionImpl;
import org.jetbrains.jps.model.impl.JpsElementCollectionKind;
import org.jetbrains.jps.service.JpsServiceManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author nik
*/
public class JpsBuilderArtifactServiceImpl extends JpsBuilderArtifactService {
private static final JpsElementCollectionKind<JpsArtifact> SYNTHETIC_ARTIFACTS = new JpsElementCollectionKind<JpsArtifact>(JpsArtifactKind.INSTANCE);
@Override
public Collection<JpsArtifact> getArtifacts(JpsModel model, boolean includeSynthetic) {
List<JpsArtifact> artifacts = JpsArtifactService.getInstance().getArtifacts(model.getProject());
if (!includeSynthetic) {
return artifacts;
}
return ContainerUtil.concat(artifacts, getSyntheticArtifacts(model));
}
public List<JpsArtifact> getSyntheticArtifacts(final JpsModel model) {
JpsElementCollectionImpl<JpsArtifact> artifactsCollection = model.getProject().getContainer().getChild(SYNTHETIC_ARTIFACTS);
if (artifactsCollection == null) {
List<JpsArtifact> artifactList = computeSyntheticArtifacts(model);
artifactsCollection = model.getProject().getContainer().setChild(SYNTHETIC_ARTIFACTS);
for (JpsArtifact artifact : artifactList) {
artifactsCollection.addChild(artifact);
}
}
return artifactsCollection.getElements();
}
private static List<JpsArtifact> computeSyntheticArtifacts(JpsModel model) {
List<JpsArtifact> artifacts = new ArrayList<JpsArtifact>();
for (JpsSyntheticArtifactProvider provider : JpsServiceManager.getInstance().getExtensions(JpsSyntheticArtifactProvider.class)) {
artifacts.addAll(provider.createArtifacts(model));
}
return artifacts;
}
}
@@ -16,6 +16,8 @@ public abstract class JpsArtifactService {
return JpsServiceManager.getInstance().getService(JpsArtifactService.class);
}
public abstract JpsArtifact createArtifact(String name, JpsCompositePackagingElement rootElement, JpsArtifactType type);
public abstract List<JpsArtifact> getArtifacts(@NotNull JpsProject project);
public abstract JpsArtifact addArtifact(@NotNull JpsProject project,
@@ -10,6 +10,10 @@ import org.jetbrains.jps.service.JpsServiceManager;
* @author nik
*/
public abstract class JpsPackagingElementFactory {
public abstract JpsCompositePackagingElement getOrCreateDirectory(@NotNull JpsCompositePackagingElement root, @NotNull String path);
public abstract JpsCompositePackagingElement getOrCreateArchive(@NotNull JpsCompositePackagingElement root, @NotNull String path);
public static JpsPackagingElementFactory getInstance() {
return JpsServiceManager.getInstance().getService(JpsPackagingElementFactory.class);
}
@@ -0,0 +1,23 @@
package org.jetbrains.jps.model.java;
import org.jetbrains.jps.model.module.JpsDependenciesEnumerator;
/**
* @author nik
*/
public interface JpsJavaDependenciesEnumerator extends JpsDependenciesEnumerator {
JpsJavaDependenciesEnumerator productionOnly();
JpsJavaDependenciesEnumerator compileOnly();
JpsJavaDependenciesEnumerator runtimeOnly();
JpsJavaDependenciesEnumerator exportedOnly();
JpsJavaDependenciesEnumerator withoutLibraries();
JpsJavaDependenciesEnumerator withoutDepModules();
JpsJavaDependenciesEnumerator withoutSdk();
JpsJavaDependenciesEnumerator withoutModuleSourceEntries();
@Override
JpsJavaDependenciesEnumerator recursively();
JpsJavaDependenciesEnumerator includedIn(JpsJavaClasspathKind classpathKind);
}
@@ -25,6 +25,12 @@ public abstract class JpsJavaExtensionService {
return JpsServiceManager.getInstance().getService(JpsJavaExtensionService.class);
}
public static JpsJavaDependenciesEnumerator dependencies(JpsModule module) {
return getInstance().enumerateDependencies(module);
}
protected abstract JpsJavaDependenciesEnumerator enumerateDependencies(JpsModule module);
@NotNull
public abstract JpsJavaProjectExtension getOrCreateProjectExtension(@NotNull JpsProject project);
@@ -0,0 +1,18 @@
package org.jetbrains.jps.model.module;
import org.jetbrains.jps.model.library.JpsLibrary;
import java.util.Set;
/**
* @author nik
*/
public interface JpsDependenciesEnumerator {
JpsDependenciesEnumerator withoutLibraries();
JpsDependenciesEnumerator withoutDepModules();
JpsDependenciesEnumerator withoutSdk();
JpsDependenciesEnumerator withoutModuleSourceEntries();
JpsDependenciesEnumerator recursively();
Set<JpsModule> getModules();
Set<JpsLibrary> getLibraries();
}
@@ -7,4 +7,6 @@ import org.jetbrains.jps.model.JpsCompositeElement;
*/
public interface JpsDependencyElement extends JpsCompositeElement {
void remove();
JpsModule getContainingModule();
}
@@ -64,4 +64,9 @@ public interface JpsModule extends JpsNamedElement, JpsReferenceableElement<JpsM
void delete();
JpsProject getProject();
JpsModuleType<?> getModuleType();
@NotNull
JpsElementProperties getProperties();
}
@@ -25,10 +25,15 @@ public class JpsArtifactServiceImpl extends JpsArtifactService {
@Override
public JpsArtifact addArtifact(@NotNull JpsProject project, @NotNull String name, @NotNull JpsCompositePackagingElement rootElement,
@NotNull JpsArtifactType type) {
JpsArtifact artifact = new JpsArtifactImpl(name, rootElement, type);
JpsArtifact artifact = createArtifact(name, rootElement, type);
return project.getContainer().getOrSetChild(JpsArtifactKind.ARTIFACT_COLLECTION_KIND).addChild(artifact);
}
@Override
public JpsArtifact createArtifact(String name, JpsCompositePackagingElement rootElement, JpsArtifactType type) {
return new JpsArtifactImpl(name, rootElement, type);
}
@Override
public JpsArtifactReference createReference(@NotNull String artifactName) {
return new JpsArtifactReferenceImpl(artifactName);
@@ -35,6 +35,16 @@ public class JpsPackagingElementFactoryImpl extends JpsPackagingElementFactory {
return root;
}
@Override
public JpsCompositePackagingElement getOrCreateDirectory(@NotNull JpsCompositePackagingElement root, @NotNull String path) {
return getOrCreateDirectoryOrArchive(root, path, true);
}
@Override
public JpsCompositePackagingElement getOrCreateArchive(@NotNull JpsCompositePackagingElement root, @NotNull String path) {
return getOrCreateDirectoryOrArchive(root, path, false);
}
@NotNull
private JpsCompositePackagingElement getOrCreateDirectoryOrArchive(@NotNull JpsCompositePackagingElement root,
@NotNull @NonNls String path, final boolean directory) {
@@ -0,0 +1,84 @@
package org.jetbrains.jps.model.java.impl;
import org.jetbrains.jps.model.java.*;
import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.impl.JpsDependenciesEnumeratorBase;
import java.util.Collection;
/**
* @author nik
*/
public class JpsJavaDependenciesEnumeratorImpl extends JpsDependenciesEnumeratorBase<JpsJavaDependenciesEnumeratorImpl> implements JpsJavaDependenciesEnumerator {
private boolean myProductionOnly;
private boolean myRuntimeOnly;
private boolean myCompileOnly;
private boolean myExportedOnly;
private JpsJavaClasspathKind myClasspathKind;
public JpsJavaDependenciesEnumeratorImpl(Collection<JpsModule> rootModules) {
super(rootModules);
}
@Override
public JpsJavaDependenciesEnumerator productionOnly() {
myProductionOnly = true;
return this;
}
@Override
public JpsJavaDependenciesEnumerator compileOnly() {
myCompileOnly = true;
return this;
}
@Override
public JpsJavaDependenciesEnumerator runtimeOnly() {
myRuntimeOnly = true;
return this;
}
@Override
public JpsJavaDependenciesEnumerator exportedOnly() {
myExportedOnly = true;
return this;
}
@Override
public JpsJavaDependenciesEnumerator includedIn(JpsJavaClasspathKind classpathKind) {
myClasspathKind = classpathKind;
return this;
}
@Override
protected JpsJavaDependenciesEnumeratorImpl self() {
return this;
}
@Override
protected boolean shouldProcess(JpsDependencyElement element) {
boolean exported = false;
JpsJavaDependencyExtension extension = JpsJavaExtensionService.getInstance().getDependencyExtension(element);
if (extension != null) {
exported = extension.isExported();
JpsJavaDependencyScope scope = extension.getScope();
if (myCompileOnly && !scope.isIncludedIn(JpsJavaClasspathKind.PRODUCTION_COMPILE) && !scope.isIncludedIn(JpsJavaClasspathKind.TEST_COMPILE)
|| myRuntimeOnly && !scope.isIncludedIn(JpsJavaClasspathKind.PRODUCTION_RUNTIME) && !scope.isIncludedIn(JpsJavaClasspathKind.TEST_RUNTIME)
|| myClasspathKind != null && !scope.isIncludedIn(myClasspathKind)) {
return false;
}
if (myProductionOnly) {
if (!scope.isIncludedIn(JpsJavaClasspathKind.PRODUCTION_COMPILE) && !scope.isIncludedIn(JpsJavaClasspathKind.PRODUCTION_RUNTIME)
|| myCompileOnly && !scope.isIncludedIn(JpsJavaClasspathKind.PRODUCTION_COMPILE)
|| myRuntimeOnly && !scope.isIncludedIn(JpsJavaClasspathKind.PRODUCTION_RUNTIME)) {
return false;
}
}
}
if (!exported) {
if (myExportedOnly) return false;
}
return true;
}
}
@@ -12,6 +12,7 @@ import org.jetbrains.jps.model.module.JpsModuleReference;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -136,4 +137,9 @@ public class JpsJavaExtensionServiceImpl extends JpsJavaExtensionService {
public JpsTestModuleOutputPackagingElement createTestModuleOutput(@NotNull JpsModuleReference moduleReference) {
return new JpsTestModuleOutputPackagingElementImpl(moduleReference);
}
@Override
protected JpsJavaDependenciesEnumerator enumerateDependencies(JpsModule module) {
return new JpsJavaDependenciesEnumeratorImpl(Collections.singletonList(module));
}
}
@@ -0,0 +1,159 @@
package org.jetbrains.jps.model.module.impl;
import com.intellij.util.CollectConsumer;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
import org.jetbrains.jps.model.library.JpsLibrary;
import org.jetbrains.jps.model.module.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* @author nik
*/
public abstract class JpsDependenciesEnumeratorBase<Self extends JpsDependenciesEnumerator> implements JpsDependenciesEnumerator {
private boolean myWithoutSdk;
private boolean myWithoutLibraries;
protected boolean myWithoutDepModules;
private boolean myWithoutModuleSourceEntries;
protected boolean myRecursively;
protected final Collection<JpsModule> myRootModules;
protected JpsDependenciesEnumeratorBase(Collection<JpsModule> rootModules) {
myRootModules = rootModules;
}
@Override
public Self withoutLibraries() {
myWithoutLibraries = true;
return self();
}
@Override
public Self withoutDepModules() {
myWithoutDepModules = true;
return self();
}
@Override
public Self withoutSdk() {
myWithoutSdk = true;
return self();
}
@Override
public Self withoutModuleSourceEntries() {
myWithoutModuleSourceEntries = true;
return self();
}
@Override
public Self recursively() {
myRecursively = true;
return self();
}
protected abstract Self self();
@Override
public Set<JpsModule> getModules() {
Set<JpsModule> result = new HashSet<JpsModule>();
processModules(new CollectConsumer<JpsModule>(result));
return result;
}
public void processModules(final Consumer<JpsModule> consumer) {
processDependencies(new Processor<JpsDependencyElement>() {
@Override
public boolean process(JpsDependencyElement dependencyElement) {
if (myRecursively && dependencyElement instanceof JpsModuleSourceDependency) {
consumer.consume(dependencyElement.getContainingModule());
}
else if (!myRecursively && dependencyElement instanceof JpsModuleDependency) {
JpsModule module = ((JpsModuleDependency)dependencyElement).getModule();
if (module != null) {
consumer.consume(module);
}
}
return true;
}
});
}
private boolean processDependencies(Processor<JpsDependencyElement> processor) {
THashSet<JpsModule> processed = new THashSet<JpsModule>();
for (JpsModule module : myRootModules) {
if (!doProcessDependencies(module, processor, processed)) {
return false;
}
}
return true;
}
private boolean doProcessDependencies(JpsModule module, Processor<JpsDependencyElement> processor, Set<JpsModule> processed) {
if (!processed.add(module)) return true;
for (JpsDependencyElement element : module.getDependenciesList().getDependencies()) {
if (myWithoutSdk && element instanceof JpsSdkDependency
|| myWithoutLibraries && element instanceof JpsLibraryDependency
|| myWithoutModuleSourceEntries && element instanceof JpsModuleSourceDependency) continue;
if (myWithoutDepModules) {
if (!myRecursively && element instanceof JpsModuleDependency) continue;
if (element instanceof JpsModuleSourceDependency && !isEnumerationRootModule(module)) continue;
}
if (shouldProcess(element)) {
}
if (element instanceof JpsModuleDependency) {
if (myRecursively) {
JpsModule depModule = ((JpsModuleDependency)element).getModule();
if (depModule != null) {
doProcessDependencies(module, processor, processed);
continue;
}
}
if (myWithoutDepModules) continue;
}
if (!processor.process(element)) {
return false;
}
}
return true;
}
protected boolean shouldProcess(JpsDependencyElement element) {
return true;
}
private boolean isEnumerationRootModule(JpsModule module) {
return myRootModules.contains(module);
}
@Override
public Set<JpsLibrary> getLibraries() {
Set<JpsLibrary> libraries = new HashSet<JpsLibrary>();
processLibraries(new CollectConsumer<JpsLibrary>(libraries));
return libraries;
}
public void processLibraries(final Consumer<JpsLibrary> consumer) {
processDependencies(new Processor<JpsDependencyElement>() {
@Override
public boolean process(JpsDependencyElement dependencyElement) {
if (dependencyElement instanceof JpsLibraryDependency) {
JpsLibrary library = ((JpsLibraryDependency)dependencyElement).getLibrary();
if (library != null) {
consumer.consume(library);
}
}
return true;
}
});
}
}
@@ -19,4 +19,13 @@ public abstract class JpsDependencyElementBase<Self extends JpsDependencyElement
public void remove() {
((JpsDependenciesListImpl)myParent.getParent()).getContainer().getChild(JpsDependenciesListImpl.DEPENDENCY_COLLECTION_KIND).removeChild(this);
}
public JpsDependenciesListImpl getDependenciesList() {
return (JpsDependenciesListImpl)myParent.getParent();
}
@Override
public JpsModuleImpl getContainingModule() {
return getDependenciesList().getParent();
}
}
@@ -44,6 +44,12 @@ public class JpsModuleImpl extends JpsNamedCompositeElementBase<JpsModuleImpl> i
return new JpsModuleImpl(this);
}
@Override
@NotNull
public JpsElementProperties getProperties() {
return myContainer.getChild(TYPED_DATA_KIND).getProperties();
}
@NotNull
@Override
public JpsUrlList getContentRootsList() {
@@ -168,4 +174,9 @@ public class JpsModuleImpl extends JpsNamedCompositeElementBase<JpsModuleImpl> i
JpsModel model = getModel();
return model != null ? model.getProject() : null;
}
@Override
public JpsModuleType<?> getModuleType() {
return myContainer.getChild(TYPED_DATA_KIND).getType();
}
}
@@ -44,16 +44,11 @@ public class JpsSdkDependencyImpl extends JpsDependencyElementBase<JpsSdkDepende
@Override
@Nullable
public JpsLibraryReference getSdkReference() {
JpsModuleImpl module = getDependenciesList().getParent();
return module.getSdkReference(mySdkType);
return getContainingModule().getSdkReference(mySdkType);
}
@Override
public boolean isInherited() {
return false;
}
public JpsDependenciesListImpl getDependenciesList() {
return (JpsDependenciesListImpl)myParent.getParent();
}
}
@@ -11,6 +11,7 @@
<orderEntry type="module" module-name="jps-model-api" />
<orderEntry type="module" module-name="jps-model-serialization" />
<orderEntry type="module" module-name="jps-builders" />
<orderEntry type="module" module-name="jps-model-impl" />
</component>
</module>
@@ -0,0 +1 @@
org.jetbrains.jps.devkit.builder.JpsPluginSyntheticArtifactProvider
@@ -0,0 +1,142 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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.jetbrains.jps.devkit.builder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.JpsPathUtil;
import org.jetbrains.jps.devkit.model.JpsIdeaSdkProperties;
import org.jetbrains.jps.devkit.model.JpsIdeaSdkType;
import org.jetbrains.jps.devkit.model.JpsPluginModuleProperties;
import org.jetbrains.jps.incremental.artifacts.JpsSyntheticArtifactProvider;
import org.jetbrains.jps.model.JpsElementProperties;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.DirectoryArtifactType;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.JpsArtifactService;
import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement;
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElementFactory;
import org.jetbrains.jps.model.java.JpsJavaClasspathKind;
import org.jetbrains.jps.model.java.JpsJavaDependenciesEnumerator;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.java.JpsJavaModuleType;
import org.jetbrains.jps.model.library.JpsLibrary;
import org.jetbrains.jps.model.library.JpsOrderRootType;
import org.jetbrains.jps.model.library.JpsTypedLibrary;
import org.jetbrains.jps.model.module.JpsModule;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author nik
*/
public class JpsPluginSyntheticArtifactProvider extends JpsSyntheticArtifactProvider {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.devkit.builder.JpsPluginSyntheticArtifactProvider");
@NotNull
@Override
public List<JpsArtifact> createArtifacts(@NotNull JpsModel model) {
List<JpsArtifact> artifacts = new ArrayList<JpsArtifact>();
for (JpsModule module : model.getProject().getModules()) {
JpsElementProperties properties = module.getProperties();
if (properties instanceof JpsPluginModuleProperties) {
artifacts.add(createArtifact(module, (JpsPluginModuleProperties)properties));
}
}
return artifacts;
}
private static JpsArtifact createArtifact(JpsModule module, JpsPluginModuleProperties properties) {
JpsPackagingElementFactory factory = JpsPackagingElementFactory.getInstance();
JpsCompositePackagingElement root = factory.createArtifactRoot();
String pluginXmlUrl = properties.getPluginXmlUrl();
if (pluginXmlUrl != null) {
String pluginXmlPath = JpsPathUtil.urlToPath(pluginXmlUrl);
JpsCompositePackagingElement metaInfDir = factory.getOrCreateDirectory(root, "META-INF");
metaInfDir.addChild(factory.createFileCopy(pluginXmlPath, null));
File pluginXmlFile = JpsPathUtil.urlToFile(pluginXmlUrl);
if (pluginXmlFile.exists()) {
try {
Element rootElement = JDOMUtil.loadDocument(pluginXmlFile).getRootElement();
for (Element dependsElement : JDOMUtil.getChildren(rootElement, "depends")) {
String relativePath = dependsElement.getAttributeValue("config-file");
if (relativePath != null) {
File dependencyFile = new File(pluginXmlFile.getParent(), FileUtil.toSystemDependentName(relativePath));
String dependencyPath = FileUtil.toSystemIndependentName(dependencyFile.getAbsolutePath());
metaInfDir.addChild(factory.createFileCopy(dependencyPath, null));
}
}
}
catch (JDOMException e) {
LOG.info(e);
}
catch (IOException e) {
LOG.info(e);
}
}
}
JpsJavaDependenciesEnumerator enumerator = JpsJavaExtensionService.dependencies(module).recursively().includedIn(
JpsJavaClasspathKind.PRODUCTION_RUNTIME);
JpsCompositePackagingElement classesDir = factory.getOrCreateDirectory(root, "classes");
for (JpsModule depModule : enumerator.getModules()) {
if (depModule.getModuleType().equals(JpsJavaModuleType.INSTANCE)) {
classesDir.addChild(JpsJavaExtensionService.getInstance().createProductionModuleOutput(depModule.createReference()));
}
}
classesDir.addChild(JpsJavaExtensionService.getInstance().createProductionModuleOutput(module.createReference()));
for (JpsLibrary library : enumerator.getLibraries()) {
JpsCompositePackagingElement parent;
if (hasDirsOnly(library)) {
parent = classesDir;
}
else {
parent = factory.getOrCreateDirectory(root, "lib");
}
parent.addChild(factory.createLibraryElement(library.createReference()));
}
String name = module.getName() + ":plugin";
JpsArtifact artifact = JpsArtifactService.getInstance().createArtifact(name, root, DirectoryArtifactType.INSTANCE);
JpsTypedLibrary<JpsIdeaSdkProperties> sdk = module.getSdk(JpsIdeaSdkType.INSTANCE);
if (sdk != null) {
String sandboxHome = sdk.getProperties().getSandboxHome();
if (sandboxHome != null) {
artifact.setOutputPath(sandboxHome + "/plugins/" + module.getName());
}
}
return artifact;
}
private static boolean hasDirsOnly(JpsLibrary library) {
List<File> files = library.getFiles(JpsOrderRootType.COMPILED);
for (File file : files) {
if (!file.isDirectory()) {
return false;
}
}
return true;
}
}
@@ -107,12 +107,14 @@ public class PluginBuildParticipant extends BuildParticipant {
if (domElement instanceof IdeaPlugin) {
for(Dependency dependency: ((IdeaPlugin)domElement).getDependencies()) {
final String file = dependency.getConfigFile().getValue();
final VirtualFile virtualFile = configFile.getVirtualFile();
assert virtualFile != null;
final VirtualFile parent = virtualFile.getParent();
assert parent != null;
final String url = parent.getUrl();
factory.addFileCopy(root, "META-INF/", VfsUtil.urlToPath(url) + "/" + file);
if (file != null) {
final VirtualFile virtualFile = configFile.getVirtualFile();
assert virtualFile != null;
final VirtualFile parent = virtualFile.getParent();
assert parent != null;
final String url = parent.getUrl();
factory.addFileCopy(root, "META-INF/", VfsUtil.urlToPath(url) + "/" + file);
}
}
}
}