View Javadoc
1   /*
2    * (C) Copyright 2006-2015 Nuxeo SA (http://nuxeo.com/) and contributors.
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the GNU Lesser General Public License
6    * (LGPL) version 2.1 which accompanies this distribution, and is available at
7    * http://www.gnu.org/licenses/lgpl-2.1.html
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * Contributors:
15   *     bstefanescu, slacoin, jcarsique
16   */
17  package org.nuxeo.build.ant.artifact;
18  
19  import java.io.File;
20  import java.io.IOException;
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import org.apache.tools.ant.BuildException;
27  import org.apache.tools.ant.Project;
28  import org.apache.tools.ant.types.DataType;
29  import org.apache.tools.ant.types.Reference;
30  import org.apache.tools.ant.types.Resource;
31  import org.apache.tools.ant.types.ResourceCollection;
32  import org.apache.tools.ant.types.resources.FileResource;
33  import org.eclipse.aether.artifact.Artifact;
34  import org.eclipse.aether.resolution.ArtifactResult;
35  import org.eclipse.aether.resolution.DependencyResult;
36  import org.eclipse.aether.util.artifact.JavaScopes;
37  
38  import org.nuxeo.build.ant.AntClient;
39  import org.nuxeo.build.maven.AntBuildMojo;
40  import org.nuxeo.build.maven.filter.AncestorFilter;
41  import org.nuxeo.build.maven.filter.AndFilter;
42  import org.nuxeo.build.maven.filter.ArtifactIdFilter;
43  import org.nuxeo.build.maven.filter.ClassifierFilter;
44  import org.nuxeo.build.maven.filter.CompositeFilter;
45  import org.nuxeo.build.maven.filter.Filter;
46  import org.nuxeo.build.maven.filter.GroupIdFilter;
47  import org.nuxeo.build.maven.filter.IsOptionalFilter;
48  import org.nuxeo.build.maven.filter.NotFilter;
49  import org.nuxeo.build.maven.filter.ScopeFilter;
50  import org.nuxeo.build.maven.filter.TypeFilter;
51  import org.nuxeo.build.maven.filter.VersionFilter;
52  import org.nuxeo.build.maven.graph.DependencyUtils;
53  import org.nuxeo.build.maven.graph.Node;
54  
55  /**
56   * TODO NXBT-258
57   */
58  public class ArtifactSet extends DataType implements ResourceCollection {
59  
60      public AndFilter filter = new AndFilter();
61  
62      public String id;
63  
64      public File src;
65  
66      public Expand expand;
67  
68      public List<ArtifactFile> artifactFiles;
69  
70      public List<ArtifactSet> artifactSets;
71  
72      public Includes includes;
73  
74      public Excludes excludes;
75  
76      protected Collection<Artifact> artifacts;
77  
78      private boolean scopeTest = false;
79  
80      private boolean scopeProvided = false;
81  
82      public void setGroupId(String groupId) {
83          if (isReference()) {
84              throw tooManyAttributes();
85          }
86          filter.addFilter(new GroupIdFilter(groupId));
87      }
88  
89      public void setArtifactId(String artifactId) {
90          if (isReference()) {
91              throw tooManyAttributes();
92          }
93          filter.addFilter(new ArtifactIdFilter(artifactId));
94      }
95  
96      public void setVersion(String version) {
97          if (isReference()) {
98              throw tooManyAttributes();
99          }
100         filter.addFilter(new VersionFilter(version));
101     }
102 
103     public void setClassifier(String classifier) {
104         if (isReference()) {
105             throw tooManyAttributes();
106         }
107         filter.addFilter(new ClassifierFilter(classifier));
108     }
109 
110     public void setType(String type) {
111         if (isReference()) {
112             throw tooManyAttributes();
113         }
114         filter.addFilter(new TypeFilter(type));
115     }
116 
117     public void setScope(String scope) {
118         if (isReference()) {
119             throw tooManyAttributes();
120         }
121         // Exclude test and provided scopes by default
122         scopeTest = JavaScopes.TEST.equals(scope) || "*".equals(scope);
123         scopeProvided = JavaScopes.PROVIDED.equals(scope) || "*".equals(scope);
124         filter.addFilter(new ScopeFilter(scope));
125     }
126 
127     public void setOptional(boolean isOptional) {
128         if (isReference()) {
129             throw tooManyAttributes();
130         }
131         filter.addFilter(new IsOptionalFilter(isOptional));
132     }
133 
134     public void setPattern(String pattern) {
135         if (isReference()) {
136             throw tooManyAttributes();
137         }
138         filter.addFiltersFromPattern(pattern);
139     }
140 
141     public void setAncestor(String ancestor) {
142         if (isReference()) {
143             throw tooManyAttributes();
144         }
145         filter.addFilter(new AncestorFilter(ancestor));
146     }
147 
148     public void setId(String id) {
149         if (isReference()) {
150             throw tooManyAttributes();
151         }
152         this.id = id;
153     }
154 
155     public void setSrc(File importFile) {
156         src = importFile;
157     }
158 
159     public void addExpand(@SuppressWarnings("hiding") Expand expand) {
160         if (isReference()) {
161             throw noChildrenAllowed();
162         }
163         this.expand = expand;
164     }
165 
166     public void addFile(ArtifactFile artifact) {
167         if (isReference()) {
168             throw noChildrenAllowed();
169         }
170         if (artifactFiles == null) {
171             artifactFiles = new ArrayList<>();
172         }
173         artifactFiles.add(artifact);
174     }
175 
176     public void addArtifactSet(ArtifactSet set) {
177         if (isReference()) {
178             throw noChildrenAllowed();
179         }
180         if (artifactSets == null) {
181             artifactSets = new ArrayList<>();
182         }
183         artifactSets.add(set);
184     }
185 
186     public void addIncludes(@SuppressWarnings("hiding") Includes includes) {
187         if (isReference()) {
188             throw noChildrenAllowed();
189         }
190         if (this.includes != null) {
191             throw new BuildException("Found an Includes that is defined more than once in an artifactSet");
192         }
193         this.includes = includes;
194     }
195 
196     public void addExcludes(@SuppressWarnings("hiding") Excludes excludes) {
197         if (isReference()) {
198             throw noChildrenAllowed();
199         }
200         if (this.excludes != null) {
201             throw new BuildException("Found an Excludes that is defined more than once in an artifactSet");
202         }
203         this.excludes = excludes;
204     }
205 
206     @Override
207     public void setRefid(Reference ref) {
208         super.setRefid(ref);
209     }
210 
211     protected ArtifactSet getRef(Project p) {
212         return (ArtifactSet) getCheckedRef(p);
213     }
214 
215     protected Filter buildFilter() {
216         AndFilter f = new AndFilter();
217         if (!filter.isEmpty()) {
218             if (!scopeTest) {
219                 filter.addFilter(new NotFilter(new ScopeFilter(JavaScopes.TEST)));
220             }
221             if (!scopeProvided) {
222                 filter.addFilter(new NotFilter(new ScopeFilter(JavaScopes.PROVIDED)));
223             }
224             f.addFilters(filter.getFilters());
225         }
226         if (includes != null) {
227             f.addFilter(includes.getFilter());
228         }
229         if (excludes != null) {
230             f.addFilter(excludes.getFilter());
231         }
232         return f.isEmpty() ? Filter.ANY : CompositeFilter.compact(f);
233     }
234 
235     protected Collection<Artifact> computeNodes() {
236         Collection<Artifact> resultArtifacts = new ArrayList<>();
237         Collection<Node> roots = new ArrayList<>();
238         if (src != null) {
239             collectImportedNodes(roots);
240         }
241         if (artifactFiles != null) {
242             for (ArtifactFile arti : artifactFiles) {
243                 roots.add(arti.getNode());
244             }
245         }
246         if (artifactSets != null) {
247             for (ArtifactSet arti : artifactSets) {
248                 resultArtifacts.addAll(arti.getArtifacts());
249             }
250         }
251         Filter finalFilter = buildFilter();
252         int depth = Integer.MAX_VALUE;
253         if (expand != null) {
254             expand.filter.addFilter(finalFilter);
255             finalFilter = CompositeFilter.compact(expand.filter);
256             depth = expand.depth;
257         }
258         roots.addAll(AntBuildMojo.getInstance().getGraph().getRoots());
259         for (Node node : roots) {
260             DependencyResult result = DependencyUtils.resolveDependencies(node, finalFilter, depth);
261             for (ArtifactResult artifactResult : result.getArtifactResults()) {
262                 resultArtifacts.add(artifactResult.getArtifact());
263             }
264             // root artifact is always kept; filter it out if not acceptable
265             if (!finalFilter.accept(result.getRoot(), null)) {
266                 Artifact root = result.getRoot().getArtifact();
267                 resultArtifacts.remove(root);
268             }
269         }
270         return resultArtifacts;
271     }
272 
273     public Collection<Artifact> getArtifacts() {
274         if (isReference()) {
275             return getRef(getProject()).getArtifacts();
276         }
277         if (artifacts == null) {
278             artifacts = computeNodes();
279         }
280         AntClient.getInstance().log("ArtifactSet.getArtifacts() " + artifacts, new Error(), Project.MSG_DEBUG);
281         if (id != null) { // avoid caching if artifactSet is referencable
282             Collection<Artifact> copy = artifacts;
283             artifacts = null;
284             return copy;
285         }
286         return artifacts;
287     }
288 
289     @Override
290     public Iterator<Resource> iterator() {
291         return createIterator(getArtifacts());
292     }
293 
294     public static Iterator<Resource> createIterator(Collection<Artifact> collection) {
295         List<Resource> files = new ArrayList<>();
296         for (Artifact artifact : collection) {
297             File file = artifact.getFile();
298             if (file != null) {
299                 FileResource fr = new FileResource(file);
300                 fr.setBaseDir(file.getParentFile());
301                 files.add(fr);
302             }
303         }
304         return files.iterator();
305     }
306 
307     @Override
308     public int size() {
309         return getArtifacts().size();
310     }
311 
312     @Override
313     public boolean isFilesystemOnly() {
314         return true;
315     }
316 
317     public void collectImportedNodes(Collection<Node> nodesCollection) {
318         try {
319             ArtifactSetParser parser = new ArtifactSetParser(getProject());
320             parser.parse(src, nodesCollection);
321         } catch (IOException e) {
322             throw new BuildException("Failed to import artifacts file: " + src, e);
323         }
324     }
325 
326 }