2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com
.intellij
.compiler
.ant
.artifacts
;
18 import com
.intellij
.compiler
.ant
.BuildProperties
;
19 import com
.intellij
.compiler
.ant
.Comment
;
20 import com
.intellij
.compiler
.ant
.GenerationOptions
;
21 import com
.intellij
.compiler
.ant
.Generator
;
22 import com
.intellij
.compiler
.ant
.taskdefs
.*;
23 import com
.intellij
.openapi
.module
.Module
;
24 import com
.intellij
.openapi
.project
.Project
;
25 import com
.intellij
.openapi
.util
.io
.FileUtil
;
26 import com
.intellij
.openapi
.util
.text
.StringUtil
;
27 import com
.intellij
.packaging
.artifacts
.Artifact
;
28 import com
.intellij
.packaging
.artifacts
.ArtifactManager
;
29 import com
.intellij
.packaging
.elements
.ComplexPackagingElement
;
30 import com
.intellij
.packaging
.elements
.CompositePackagingElement
;
31 import com
.intellij
.packaging
.elements
.PackagingElement
;
32 import com
.intellij
.packaging
.elements
.PackagingElementResolvingContext
;
33 import com
.intellij
.packaging
.impl
.artifacts
.ArtifactUtil
;
34 import com
.intellij
.packaging
.impl
.artifacts
.PackagingElementProcessor
;
35 import com
.intellij
.packaging
.impl
.elements
.ArtifactPackagingElement
;
36 import com
.intellij
.packaging
.impl
.elements
.ModuleOutputPackagingElement
;
37 import org
.jetbrains
.annotations
.NonNls
;
38 import org
.jetbrains
.annotations
.NotNull
;
40 import java
.util
.ArrayList
;
41 import java
.util
.List
;
46 public class ArtifactsGenerator
{
47 @NonNls public static final String BUILD_ALL_ARTIFACTS_TARGET
= "build.all.artifacts";
48 @NonNls private static final String INIT_ARTIFACTS_TARGET
= "init.artifacts";
49 private final Project myProject
;
50 private final PackagingElementResolvingContext myResolvingContext
;
51 private ArtifactAntGenerationContextImpl myContext
;
53 public ArtifactsGenerator(Project project
, GenerationOptions genOptions
) {
55 myResolvingContext
= ArtifactManager
.getInstance(myProject
).getResolvingContext();
56 myContext
= new ArtifactAntGenerationContextImpl(project
, genOptions
);
59 public List
<Generator
> generate() {
60 final List
<Generator
> generators
= new ArrayList
<Generator
>();
62 final Target initTarget
= new Target(INIT_ARTIFACTS_TARGET
, null, null, null);
63 generators
.add(initTarget
);
64 initTarget
.add(new Property(ArtifactAntGenerationContextImpl
.ARTIFACTS_TEMP_DIR_PROPERTY
, BuildProperties
.propertyRelativePath(BuildProperties
.getProjectBaseDirProperty(), "artifactsTemp")));
66 final Artifact
[] artifacts
= ArtifactManager
.getInstance(myProject
).getSortedArtifacts();
67 for (Artifact artifact
: artifacts
) {
68 if (!myContext
.shouldBuildIntoTempDirectory(artifact
)) {
69 generators
.add(new CleanArtifactTarget(artifact
, myContext
));
71 final String outputPath
= artifact
.getOutputPath();
72 if (!StringUtil
.isEmpty(outputPath
)) {
73 initTarget
.add(new Property(myContext
.getConfiguredArtifactOutputProperty(artifact
), myContext
.getSubstitutedPath(outputPath
)));
76 initTarget
.add(new Mkdir(BuildProperties
.propertyRef(ArtifactAntGenerationContextImpl
.ARTIFACTS_TEMP_DIR_PROPERTY
)));
78 StringBuilder depends
= new StringBuilder();
79 for (Artifact artifact
: artifacts
) {
80 Target target
= createArtifactTarget(artifact
);
81 generators
.add(target
);
83 if (!StringUtil
.isEmpty(artifact
.getOutputPath())) {
84 if (depends
.length() > 0) depends
.append(", ");
85 depends
.append(myContext
.getTargetName(artifact
));
89 for (Generator generator
: myContext
.getBeforeBuildGenerators()) {
90 initTarget
.add(generator
);
93 Target buildAllArtifacts
= new Target(BUILD_ALL_ARTIFACTS_TARGET
, depends
.toString(), "Build all artifacts", null);
94 for (Artifact artifact
: artifacts
) {
95 final String artifactOutputPath
= artifact
.getOutputPath();
96 if (!StringUtil
.isEmpty(artifactOutputPath
) && myContext
.shouldBuildIntoTempDirectory(artifact
)) {
97 final String outputPath
= BuildProperties
.propertyRef(myContext
.getConfiguredArtifactOutputProperty(artifact
));
98 buildAllArtifacts
.add(new Mkdir(outputPath
));
99 final Copy copy
= new Copy(outputPath
);
100 copy
.add(new FileSet(BuildProperties
.propertyRef(myContext
.getArtifactOutputProperty(artifact
))));
101 buildAllArtifacts
.add(copy
);
105 buildAllArtifacts
.add(new Comment("Delete temporary files"), 1);
106 for (Generator generator
: myContext
.getAfterBuildGenerators()) {
107 buildAllArtifacts
.add(generator
);
109 buildAllArtifacts
.add(new Delete(BuildProperties
.propertyRef(ArtifactAntGenerationContextImpl
.ARTIFACTS_TEMP_DIR_PROPERTY
)));
111 generators
.add(buildAllArtifacts
);
115 private Target
createArtifactTarget(Artifact artifact
) {
116 final StringBuilder depends
= new StringBuilder(INIT_ARTIFACTS_TARGET
);
118 ArtifactUtil
.processPackagingElements(artifact
, null, new PackagingElementProcessor
<PackagingElement
<?
>>() {
120 public boolean shouldProcessSubstitution(ComplexPackagingElement
<?
> element
) {
121 return !(element
instanceof ArtifactPackagingElement
);
125 public boolean process(@NotNull List
<CompositePackagingElement
<?
>> parents
, @NotNull PackagingElement
<?
> packagingElement
) {
126 if (packagingElement
instanceof ArtifactPackagingElement
) {
127 final Artifact included
= ((ArtifactPackagingElement
)packagingElement
).findArtifact(myResolvingContext
);
128 if (included
!= null) {
129 if (depends
.length() > 0) depends
.append(", ");
130 depends
.append(myContext
.getTargetName(included
));
133 else if (packagingElement
instanceof ModuleOutputPackagingElement
) {
134 final Module module
= ((ModuleOutputPackagingElement
)packagingElement
).findModule(myResolvingContext
);
135 if (module
!= null) {
136 if (depends
.length() > 0) depends
.append(", ");
137 depends
.append(BuildProperties
.getCompileTargetName(module
.getName()));
142 }, myResolvingContext
, true);
144 final Target artifactTarget
=
145 new Target(myContext
.getTargetName(artifact
), depends
.toString(), "Build '" + artifact
.getName() + "' artifact", null);
147 if (myContext
.shouldBuildIntoTempDirectory(artifact
)) {
148 final String outputDirectory
= BuildProperties
.propertyRelativePath(ArtifactAntGenerationContextImpl
.ARTIFACTS_TEMP_DIR_PROPERTY
,
149 FileUtil
.sanitizeFileName(artifact
.getName()));
150 artifactTarget
.add(new Property(myContext
.getArtifactOutputProperty(artifact
), outputDirectory
));
153 final String outputPath
= BuildProperties
.propertyRef(myContext
.getArtifactOutputProperty(artifact
));
154 artifactTarget
.add(new Mkdir(outputPath
));
156 final DirectoryAntCopyInstructionCreator creator
= new DirectoryAntCopyInstructionCreator(outputPath
);
158 List
<Generator
> copyInstructions
= new ArrayList
<Generator
>();
159 copyInstructions
.addAll(artifact
.getRootElement().computeAntInstructions(myResolvingContext
, creator
, myContext
, artifact
.getArtifactType()));
161 for (Generator generator
: myContext
.getAndClearBeforeCurrentArtifact()) {
162 artifactTarget
.add(generator
);
164 for (Generator tag
: copyInstructions
) {
165 artifactTarget
.add(tag
);
167 return artifactTarget
;
170 public List
<String
> getCleanTargetNames() {
171 final List
<String
> targets
= new ArrayList
<String
>();
172 for (Artifact artifact
: ArtifactManager
.getInstance(myProject
).getArtifacts()) {
173 if (!myContext
.shouldBuildIntoTempDirectory(artifact
)) {
174 targets
.add(myContext
.getCleanTargetName(artifact
));