1 package org.andromda.maven.plugin.andromdapp.eclipse;
2
3 import java.io.File;
4 import java.io.FileWriter;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.Iterator;
8 import java.util.LinkedHashSet;
9 import java.util.List;
10 import java.util.Set;
11 import org.andromda.core.common.ResourceUtils;
12 import org.apache.commons.lang.StringUtils;
13 import org.apache.maven.artifact.Artifact;
14 import org.apache.maven.artifact.factory.ArtifactFactory;
15 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
16 import org.apache.maven.artifact.repository.ArtifactRepository;
17 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
18 import org.apache.maven.artifact.resolver.ArtifactResolver;
19 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
20 import org.apache.maven.plugin.logging.Log;
21 import org.apache.maven.project.MavenProject;
22 import org.codehaus.plexus.util.IOUtil;
23 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
24 import org.codehaus.plexus.util.xml.XMLWriter;
25
26
27
28
29
30
31 public class ClasspathWriter
32 extends EclipseWriter
33 {
34
35
36
37
38 public ClasspathWriter(
39 final MavenProject project,
40 final Log logger)
41 {
42 super(project, logger);
43 }
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public void write(
62 final List<MavenProject> projects,
63 final String repositoryVariableName,
64 final ArtifactFactory artifactFactory,
65 final ArtifactResolver artifactResolver,
66 final ArtifactRepository localRepository,
67 final ArtifactMetadataSource artifactMetadataSource,
68 final Set<String> classpathArtifactTypes,
69 final List<ArtifactRepository> remoteRepositories,
70 final boolean resolveTransitiveDependencies,
71 final Variable[] variables,
72 final String merge)
73 throws Exception
74 {
75 final String rootDirectory = ResourceUtils.normalizePath(this.project.getBasedir().toString());
76 final File classpathFile = new File(rootDirectory, ".classpath");
77 final FileWriter fileWriter = new FileWriter(classpathFile);
78 final XMLWriter writer = new PrettyPrintXMLWriter(fileWriter);
79
80 writer.startElement("classpath");
81
82 final Set<String> projectArtifactIds = new LinkedHashSet<String>();
83 for (final MavenProject project : projects)
84 {
85 final Artifact projectArtifact =
86 artifactFactory.createArtifact(
87 project.getGroupId(),
88 project.getArtifactId(),
89 project.getVersion(),
90 null,
91 project.getPackaging());
92 projectArtifactIds.add(projectArtifact.getId());
93 }
94
95
96 this.writeSourceRoots(this.project, rootDirectory, writer);
97
98 final Set<Artifact> allArtifacts = new LinkedHashSet<Artifact>(this.project.createArtifacts(
99 artifactFactory,
100 null,
101 null));
102 for (final MavenProject project : projects)
103 {
104 this.writeSourceRoots(project, rootDirectory, writer);
105 final Set<Artifact> artifacts = project.createArtifacts(
106 artifactFactory,
107 null,
108 null);
109
110
111 for (final Artifact artifact : artifacts)
112 {
113
114
115
116 if (!projectArtifactIds.contains(artifact.getId()) &&
117 !project.getGroupId().equals(artifact.getGroupId()))
118 {
119 artifactResolver.resolve(
120 artifact,
121 project.getRemoteArtifactRepositories(),
122 localRepository);
123 allArtifacts.add(artifact);
124 }
125 else
126 {
127 allArtifacts.add(artifact);
128 }
129 }
130 }
131
132
133 for (final MavenProject project : projects)
134 {
135 final Artifact projectArtifact = project.getArtifact();
136 if (projectArtifact != null)
137 {
138 for (final Iterator<Artifact> artifactIterator = allArtifacts.iterator(); artifactIterator.hasNext();)
139 {
140 final Artifact artifact = artifactIterator.next();
141 final String projectId = projectArtifact.getArtifactId();
142 final String projectGroupId = projectArtifact.getGroupId();
143 final String artifactId = artifact.getArtifactId();
144 final String groupId = artifact.getGroupId();
145 if (artifactId.equals(projectId) && groupId.equals(projectGroupId))
146 {
147 artifactIterator.remove();
148 }
149 }
150 }
151 }
152
153
154 if (resolveTransitiveDependencies)
155 {
156 final Artifact rootProjectArtifact =
157 artifactFactory.createArtifact(
158 this.project.getGroupId(),
159 this.project.getArtifactId(),
160 this.project.getVersion(),
161 null,
162 this.project.getPackaging());
163
164 final OrArtifactFilter filter = new OrArtifactFilter();
165 filter.add(new ScopeArtifactFilter(Artifact.SCOPE_COMPILE));
166 filter.add(new ScopeArtifactFilter(Artifact.SCOPE_PROVIDED));
167 filter.add(new ScopeArtifactFilter(Artifact.SCOPE_TEST));
168 final ArtifactResolutionResult result =
169 artifactResolver.resolveTransitively(
170 allArtifacts,
171 rootProjectArtifact,
172 localRepository,
173 remoteRepositories,
174 artifactMetadataSource,
175 filter);
176
177 allArtifacts.clear();
178 allArtifacts.addAll(result.getArtifacts());
179 }
180
181 final List<String> artifactPathList = new ArrayList<String>();
182 for (final Artifact artifact : allArtifacts)
183 {
184 if (classpathArtifactTypes.contains(artifact.getType()))
185 {
186 final File artifactFile = artifact.getFile();
187 final String artifactPath = ResourceUtils.normalizePath(artifactFile.toString());
188 String path =
189 StringUtils.replace(
190 artifactPath,
191 ResourceUtils.normalizePath(localRepository.getBasedir()),
192 VAR_PREFIX + repositoryVariableName);
193 if (path.equals(artifactPath))
194 {
195
196 if (variables != null)
197 {
198 for (final Variable variable : variables)
199 {
200 final String name = StringUtils.trimToEmpty(variable.getName());
201 final String value = StringUtils.trimToEmpty(variable.getValue());
202 path = StringUtils.replace(path, value, VAR_PREFIX + name);
203 }
204 }
205 }
206 artifactPathList.add(path);
207 }
208 }
209
210
211 Collections.sort(artifactPathList);
212
213
214 final Set<String> artifactPaths = new LinkedHashSet<String>(artifactPathList);
215
216 for (String path : artifactPaths)
217 {
218 if (path.startsWith(VAR_PREFIX))
219 {
220 this.writeClasspathEntry(
221 writer,
222 "var",
223 path.split(VAR_PREFIX)[1]);
224 }
225 else
226 {
227 if (path.startsWith(rootDirectory))
228 {
229 path = StringUtils.replace(path, rootDirectory + '/', "");
230 }
231 this.writeClasspathEntry(
232 writer,
233 "lib",
234 path);
235 }
236 }
237
238 this.writeClasspathEntry(
239 writer,
240 "con",
241 "org.eclipse.jdt.launching.JRE_CONTAINER");
242
243 String outputPath =
244 StringUtils.replace(
245 ResourceUtils.normalizePath(this.project.getBuild().getOutputDirectory()),
246 rootDirectory,
247 "");
248 if (outputPath.startsWith("/"))
249 {
250 outputPath = outputPath.substring(
251 1,
252 outputPath.length());
253 }
254 this.writeClasspathEntry(
255 writer,
256 "output",
257 outputPath);
258
259 if (StringUtils.isNotBlank(merge))
260 {
261 writer.writeMarkup(merge);
262 }
263 writer.endElement();
264
265 logger.info("Classpath file written --> '" + classpathFile + '\'');
266 IOUtil.close(fileWriter);
267 }
268
269 private static final String VAR_PREFIX = "var:";
270
271 private static final String DRIVE_PATTERN = ".*:";
272
273
274
275
276
277
278
279
280 private void writeSourceRoots(final MavenProject project, String rootDirectory, final XMLWriter writer)
281 {
282
283 rootDirectory = rootDirectory.replaceFirst(DRIVE_PATTERN, "");
284 for (final Iterator<String> sourceIterator = project.getCompileSourceRoots().iterator(); sourceIterator.hasNext();)
285 {
286 final String sourceRoot = ResourceUtils.normalizePath(sourceIterator.next()).replaceFirst(DRIVE_PATTERN, "");
287 if (new File(sourceRoot).isDirectory())
288 {
289 String sourceRootPath = StringUtils.replace(
290 sourceRoot,
291 rootDirectory,
292 "");
293 if (sourceRootPath.startsWith("/"))
294 {
295 sourceRootPath = sourceRootPath.substring(
296 1,
297 sourceRootPath.length());
298 this.writeClasspathEntry(
299 writer,
300 "src",
301 sourceRootPath);
302 }
303 }
304 }
305 }
306
307
308
309
310
311
312
313
314 private void writeClasspathEntry(
315 final XMLWriter writer,
316 final String kind,
317 final String path)
318 {
319 writer.startElement("classpathentry");
320 writer.addAttribute(
321 "kind",
322 kind);
323 writer.addAttribute(
324 "path",
325 path);
326 writer.endElement();
327 }
328 }