Maven: correctly set sources/javadoc urls for artifacts with classifiers
[fedora-idea.git] / plugins / maven / src / main / java / org / jetbrains / idea / maven / project / MavenProject.java
blobc5bcb1a3e88a80f6e3cc0e3ed314b4ba727fb7fe
1 /*
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 org.jetbrains.idea.maven.project;
18 import com.intellij.openapi.util.Comparing;
19 import com.intellij.openapi.util.Condition;
20 import com.intellij.openapi.util.Pair;
21 import com.intellij.openapi.util.io.FileUtil;
22 import com.intellij.openapi.util.text.StringUtil;
23 import com.intellij.openapi.vfs.LocalFileSystem;
24 import com.intellij.openapi.vfs.VirtualFile;
25 import com.intellij.util.containers.ContainerUtil;
26 import gnu.trove.THashMap;
27 import gnu.trove.THashSet;
28 import org.apache.maven.artifact.Artifact;
29 import org.apache.maven.model.*;
30 import org.jdom.Element;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33 import org.jetbrains.idea.maven.embedder.MavenConsole;
34 import org.jetbrains.idea.maven.embedder.MavenEmbedderWrapper;
35 import org.jetbrains.idea.maven.importing.MavenImporter;
36 import org.jetbrains.idea.maven.utils.*;
38 import java.io.*;
39 import java.util.*;
41 public class MavenProject {
42 private final VirtualFile myFile;
43 private volatile State myState = new State();
45 public static MavenProject read(DataInputStream in) throws IOException {
46 String path = in.readUTF();
47 int length = in.readInt();
48 byte[] bytes = new byte[length];
49 in.readFully(bytes);
51 // should read full byte content first!!!
53 VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path);
54 if (file == null) return null;
56 ByteArrayInputStream bs = new ByteArrayInputStream(bytes);
57 ObjectInputStream os = new ObjectInputStream(bs);
58 try {
59 try {
60 MavenProject result = new MavenProject(file);
61 result.myState = (State)os.readObject();
62 return result;
64 catch (ClassNotFoundException e) {
65 IOException ioException = new IOException();
66 ioException.initCause(e);
67 throw ioException;
70 finally {
71 os.close();
72 bs.close();
76 public void write(DataOutputStream out) throws IOException {
77 out.writeUTF(getPath());
79 ByteArrayOutputStream bs = new ByteArrayOutputStream();
80 ObjectOutputStream os = new ObjectOutputStream(bs);
81 try {
82 os.writeObject(myState);
84 byte[] bytes = bs.toByteArray();
85 out.writeInt(bytes.length);
86 out.write(bytes);
88 finally {
89 os.close();
90 bs.close();
94 public MavenProject(VirtualFile file) {
95 myFile = file;
98 private MavenProjectChanges set(MavenProjectReaderResult readerResult,
99 boolean updateLastReadStamp,
100 boolean resetArtifacts,
101 boolean resetProfiles) {
102 State newState = myState.clone();
104 if (updateLastReadStamp) newState.myLastReadStamp++;
106 org.apache.maven.project.MavenProject nativeMavenProject = readerResult.nativeMavenProject;
108 newState.myReadingProblems = readerResult.readingProblems;
109 newState.myLocalRepository = readerResult.localRepository;
111 Collection<Profile> activeProfiles = collectActivateProfiles(nativeMavenProject);
113 newState.myActiveProfilesIds = collectProfilesIds(activeProfiles);
115 Model model = nativeMavenProject.getModel();
117 newState.myMavenId = new MavenId(model.getGroupId(),
118 model.getArtifactId(),
119 model.getVersion());
121 Parent parent = model.getParent();
122 newState.myParentId = parent != null
123 ? new MavenId(parent.getGroupId(), parent.getArtifactId(), parent.getVersion())
124 : null;
126 newState.myPackaging = model.getPackaging();
127 newState.myName = model.getName();
129 Build build = model.getBuild();
131 newState.myFinalName = build.getFinalName();
132 newState.myDefaultGoal = build.getDefaultGoal();
134 newState.myBuildDirectory = build.getDirectory();
135 newState.myOutputDirectory = build.getOutputDirectory();
136 newState.myTestOutputDirectory = build.getTestOutputDirectory();
138 doSetFolders(newState, readerResult);
140 newState.myFilters = build.getFilters() == null ? Collections.EMPTY_LIST : build.getFilters();
141 newState.myProperties = model.getProperties() != null ? model.getProperties() : new Properties();
143 doSetResolvedAttributes(newState, readerResult, resetArtifacts);
145 newState.myModulesPathsAndNames = collectModulePathsAndNames(model, getDirectory(), activeProfiles);
146 Collection<String> newProfiles = collectProfilesIds(model.getProfiles());
147 if (resetProfiles || newState.myProfilesIds == null) {
148 newState.myProfilesIds = newProfiles;
150 else {
151 Set<String> mergedProfiles = new THashSet<String>(newState.myProfilesIds);
152 mergedProfiles.addAll(newProfiles);
153 newState.myProfilesIds = new ArrayList<String>(mergedProfiles);
156 newState.myStrippedMavenModel = MavenUtil.cloneObject(model);
157 MavenUtil.stripDown(newState.myStrippedMavenModel);
159 return setState(newState);
162 private MavenProjectChanges setState(State newState) {
163 MavenProjectChanges changes = myState.getChanges(newState);
164 myState = newState;
165 return changes;
168 private static void doSetResolvedAttributes(State state, MavenProjectReaderResult readerResult, boolean reset) {
169 org.apache.maven.project.MavenProject nativeMavenProject = readerResult.nativeMavenProject;
170 Model model = nativeMavenProject.getModel();
172 Set<MavenId> newUnresolvedArtifacts = new THashSet<MavenId>();
173 LinkedHashSet<MavenRemoteRepository> newRepositories = new LinkedHashSet<MavenRemoteRepository>();
174 LinkedHashSet<MavenArtifact> newDependencies = new LinkedHashSet<MavenArtifact>();
175 LinkedHashSet<MavenPlugin> newPlugins = new LinkedHashSet<MavenPlugin>();
176 LinkedHashSet<MavenArtifact> newExtensions = new LinkedHashSet<MavenArtifact>();
178 if (!reset) {
179 if (state.myUnresolvedArtifactIds != null) newUnresolvedArtifacts.addAll(state.myUnresolvedArtifactIds);
180 if (state.myRemoteRepositories != null) newRepositories.addAll(state.myRemoteRepositories);
181 if (state.myDependencies != null) newDependencies.addAll(state.myDependencies);
182 if (state.myPlugins != null) newPlugins.addAll(state.myPlugins);
183 if (state.myExtensions != null) newExtensions.addAll(state.myExtensions);
186 newUnresolvedArtifacts.addAll(readerResult.unresolvedArtifactIds);
187 newRepositories.addAll(convertRepositories(model.getRepositories()));
188 newDependencies.addAll(convertArtifacts(nativeMavenProject.getArtifacts(), state.myLocalRepository));
189 newPlugins.addAll(collectPlugins(readerResult.settings, model));
190 newExtensions.addAll(convertArtifacts(nativeMavenProject.getExtensionArtifacts(), state.myLocalRepository));
192 state.myUnresolvedArtifactIds = newUnresolvedArtifacts;
193 state.myRemoteRepositories = new ArrayList<MavenRemoteRepository>(newRepositories);
194 state.myDependencies = new ArrayList<MavenArtifact>(newDependencies);
195 state.myPlugins = new ArrayList<MavenPlugin>(newPlugins);
196 state.myExtensions = new ArrayList<MavenArtifact>(newExtensions);
199 private MavenProjectChanges setFolders(MavenProjectReaderResult readerResult) {
200 State newState = myState.clone();
201 doSetFolders(newState, readerResult);
202 return setState(newState);
205 private static void doSetFolders(State newState, MavenProjectReaderResult readerResult) {
206 org.apache.maven.project.MavenProject nativeMavenProject = readerResult.nativeMavenProject;
208 newState.mySources = new ArrayList<String>(nativeMavenProject.getCompileSourceRoots());
209 newState.myTestSources = new ArrayList<String>(nativeMavenProject.getTestCompileSourceRoots());
211 newState.myResources = convertResources(nativeMavenProject.getResources());
212 newState.myTestResources = convertResources(nativeMavenProject.getTestResources());
215 private static List<MavenResource> convertResources(List<Resource> resources) {
216 if (resources == null) return new ArrayList<MavenResource>();
218 List<MavenResource> result = new ArrayList<MavenResource>(resources.size());
219 for (Resource each : resources) {
220 result.add(new MavenResource(each));
222 return result;
225 private static List<MavenRemoteRepository> convertRepositories(List<Repository> repositories) {
226 if (repositories == null) return new ArrayList<MavenRemoteRepository>();
228 List<MavenRemoteRepository> result = new ArrayList<MavenRemoteRepository>(repositories.size());
229 for (Repository each : repositories) {
230 result.add(new MavenRemoteRepository(each));
232 return result;
235 private static List<MavenArtifact> convertArtifacts(Collection<Artifact> artifacts, File localRepository) {
236 if (artifacts == null) return new ArrayList<MavenArtifact>();
238 List<MavenArtifact> result = new ArrayList<MavenArtifact>(artifacts.size());
239 for (Artifact each : artifacts) {
240 result.add(new MavenArtifact(each, localRepository));
242 return result;
245 private static List<MavenPlugin> collectPlugins(MavenGeneralSettings settings, Model mavenModel) {
246 List<MavenPlugin> result = new ArrayList<MavenPlugin>();
247 Set<String> pluginKeys = new THashSet<String>();
248 Build build = mavenModel.getBuild();
249 doCollectPlugins(settings, build, false, result, pluginKeys);
250 if (build != null) doCollectPlugins(settings, build.getPluginManagement(), true, result, pluginKeys);
251 return result;
254 private static void doCollectPlugins(MavenGeneralSettings settings,
255 PluginContainer container,
256 boolean management,
257 List<MavenPlugin> result,
258 Set<String> pluginKeys) {
259 if (container == null) return;
261 List<Plugin> plugins = container.getPlugins();
262 if (plugins == null) return;
264 for (Plugin each : plugins) {
265 String key = each.getGroupId() + ":" + each.getArtifactId();
266 if (management && (!isDefaultPlugin(settings, each) || pluginKeys.contains(key))) continue;
267 result.add(new MavenPlugin(each, management));
268 pluginKeys.add(key);
272 private static boolean isDefaultPlugin(MavenGeneralSettings settings, Plugin plugin) {
273 return settings.isDefaultPlugin(plugin.getGroupId(), plugin.getArtifactId());
276 private static Map<String, String> collectModulePathsAndNames(Model mavenModel, String baseDir, Collection<Profile> activeProfiles) {
277 String basePath = baseDir + "/";
278 Map<String, String> result = new LinkedHashMap<String, String>();
279 for (Map.Entry<String, String> each : collectModulesRelativePathsAndNames(mavenModel, activeProfiles).entrySet()) {
280 result.put(new Path(basePath + each.getKey()).getPath(), each.getValue());
282 return result;
285 private static Map<String, String> collectModulesRelativePathsAndNames(Model mavenModel, Collection<Profile> activeProfiles) {
286 LinkedHashMap<String, String> result = new LinkedHashMap<String, String>();
287 addModulesToList(mavenModel.getModules(), result);
288 for (Profile profile : activeProfiles) {
289 addModulesToList(profile.getModules(), result);
291 return result;
294 private static void addModulesToList(List moduleNames, LinkedHashMap<String, String> result) {
295 for (String name : (List<String>)moduleNames) {
296 if (name.trim().length() == 0) continue;
298 String originalName = name;
299 // module name can be relative and contain either / of \\ separators
301 name = FileUtil.toSystemIndependentName(name);
302 if (!name.endsWith("/")) name += "/";
303 name += MavenConstants.POM_XML;
305 result.put(name, originalName);
309 private static Collection<Profile> collectActivateProfiles(org.apache.maven.project.MavenProject nativeMavenProject) {
310 Collection<Profile> activatedProfiles = nativeMavenProject.getActiveProfiles();
311 return activatedProfiles == null ? Collections.<Profile>emptySet() : activatedProfiles;
314 private static Collection<String> collectProfilesIds(Collection<Profile> profiles) {
315 if (profiles == null) return Collections.emptyList();
317 Set<String> result = new THashSet<String>(profiles.size());
318 for (Profile each : profiles) {
319 String id = each.getId();
320 if (id != null) result.add(id);
322 return result;
325 public long getLastReadStamp() {
326 return myState.myLastReadStamp;
329 public VirtualFile getFile() {
330 return myFile;
333 @NotNull
334 public String getPath() {
335 return myFile.getPath();
338 public String getDirectory() {
339 return myFile.getParent().getPath();
342 public VirtualFile getDirectoryFile() {
343 return myFile.getParent();
346 public VirtualFile getProfilesXmlFile() {
347 return MavenUtil.findProfilesXmlFile(myFile);
350 public File getProfilesXmlIoFile() {
351 return MavenUtil.getProfilesXmlIoFile(myFile);
354 public boolean hasReadingProblems() {
355 return !myState.myReadingProblems.isEmpty();
358 public Collection<String> getActiveProfilesIds() {
359 return myState.myActiveProfilesIds;
362 public String getName() {
363 return myState.myName;
366 public String getDisplayName() {
367 State state = myState;
368 if (StringUtil.isEmptyOrSpaces(state.myName)) return state.myMavenId.getArtifactId();
369 return state.myName;
372 public Model getMavenModel() {
373 return myState.myStrippedMavenModel;
376 public MavenId getMavenId() {
377 return myState.myMavenId;
380 public MavenId getParentId() {
381 return myState.myParentId;
384 public String getPackaging() {
385 return myState.myPackaging;
388 public String getFinalName() {
389 return myState.myFinalName;
392 public String getDefaultGoal() {
393 return myState.myDefaultGoal;
396 public String getBuildDirectory() {
397 return myState.myBuildDirectory;
400 public String getGeneratedSourcesDirectory() {
401 return getBuildDirectory() + "/generated-sources";
404 public String getOutputDirectory() {
405 return myState.myOutputDirectory;
408 public String getTestOutputDirectory() {
409 return myState.myTestOutputDirectory;
412 public List<String> getSources() {
413 return myState.mySources;
416 public List<String> getTestSources() {
417 return myState.myTestSources;
420 public List<MavenResource> getResources() {
421 return myState.myResources;
424 public List<MavenResource> getTestResources() {
425 return myState.myTestResources;
428 public List<String> getFilters() {
429 return myState.myFilters;
432 public MavenProjectChanges read(MavenGeneralSettings generalSettings,
433 Collection<String> profiles,
434 MavenProjectReader reader,
435 MavenProjectReaderProjectLocator locator) {
436 return set(reader.readProject(generalSettings, myFile, profiles, locator), true, false, true);
439 public Pair<MavenProjectChanges, org.apache.maven.project.MavenProject> resolve(MavenGeneralSettings generalSettings,
440 MavenEmbedderWrapper embedder,
441 MavenProjectReader reader,
442 MavenProjectReaderProjectLocator locator)
443 throws MavenProcessCanceledException {
444 MavenProjectReaderResult result = reader.resolveProject(generalSettings,
445 embedder,
446 getFile(),
447 getActiveProfilesIds(),
448 locator);
449 MavenProjectChanges changes = set(result, false, result.readingProblems.isEmpty(), false);
450 return Pair.create(changes, result.nativeMavenProject);
453 public Pair<Boolean, MavenProjectChanges> resolveFolders(MavenEmbedderWrapper embedder,
454 MavenGeneralSettings generalSettings,
455 MavenImportingSettings importingSettings,
456 MavenProjectReader reader,
457 MavenConsole console) throws MavenProcessCanceledException {
458 MavenProjectReaderResult result = reader.generateSources(embedder,
459 generalSettings,
460 importingSettings,
461 getFile(),
462 getActiveProfilesIds(),
463 console);
464 if (result == null || !result.readingProblems.isEmpty()) return Pair.create(false, MavenProjectChanges.NONE);
465 MavenProjectChanges changes = setFolders(result);
466 return Pair.create(true, changes);
469 public boolean isAggregator() {
470 return "pom".equals(getPackaging()) || !getModulePaths().isEmpty();
473 public List<MavenProjectProblem> getProblems() {
474 State state = myState;
475 if (state.myProblemsCache == null) {
476 synchronized (state) {
477 if (state.myProblemsCache == null) {
478 state.myProblemsCache = collectProblems(myFile, state);
482 return state.myProblemsCache;
485 private static List<MavenProjectProblem> collectProblems(VirtualFile file, State state) {
486 List<MavenProjectProblem> result = new ArrayList<MavenProjectProblem>();
488 validateParent(file, state, result);
489 result.addAll(state.myReadingProblems);
491 for (Map.Entry<String, String> each : state.myModulesPathsAndNames.entrySet()) {
492 if (LocalFileSystem.getInstance().findFileByPath(each.getKey()) == null) {
493 result.add(createDependencyProblem(file, ProjectBundle.message("maven.project.problem.moduleNotFound", each.getValue())));
497 validateDependencies(file, state, result);
498 validateExtensions(file, state, result);
499 validatePlugins(file, state, result);
501 return result;
504 private static void validateParent(VirtualFile file, State state, List<MavenProjectProblem> result) {
505 if (!isParentResolved(state)) {
506 result.add(createDependencyProblem(file, ProjectBundle.message("maven.project.problem.parentNotFound", state.myParentId)));
510 private static void validateDependencies(VirtualFile file, State state, List<MavenProjectProblem> result) {
511 for (MavenArtifact each : getUnresolvedDependencies(state)) {
512 result.add(createDependencyProblem(file, ProjectBundle.message("maven.project.problem.unresolvedDependency",
513 each.getDisplayStringWithType())));
517 private static void validateExtensions(VirtualFile file, State state, List<MavenProjectProblem> result) {
518 for (MavenArtifact each : getUnresolvedExtensions(state)) {
519 result.add(createDependencyProblem(file, ProjectBundle.message("maven.project.problem.unresolvedExtension",
520 each.getDisplayStringSimple())));
524 private static void validatePlugins(VirtualFile file, State state, List<MavenProjectProblem> result) {
525 for (MavenPlugin each : getUnresolvedPlugins(state)) {
526 result.add(createDependencyProblem(file, ProjectBundle.message("maven.project.problem.unresolvedPlugin", each)));
530 private static MavenProjectProblem createDependencyProblem(VirtualFile file, String description) {
531 return new MavenProjectProblem(file, description, MavenProjectProblem.ProblemType.DEPENDENCY);
534 private static boolean isParentResolved(State state) {
535 return !state.myUnresolvedArtifactIds.contains(state.myParentId);
538 private static List<MavenArtifact> getUnresolvedDependencies(State state) {
539 if (state.myUnresolvedDependenciesCache == null) {
540 synchronized (state) {
541 if (state.myUnresolvedDependenciesCache == null) {
542 List<MavenArtifact> result = new ArrayList<MavenArtifact>();
543 for (MavenArtifact each : state.myDependencies) {
544 if (!each.isResolved()) result.add(each);
546 state.myUnresolvedDependenciesCache = result;
550 return state.myUnresolvedDependenciesCache;
553 private static List<MavenArtifact> getUnresolvedExtensions(State state) {
554 if (state.myUnresolvedExtensionsCache == null) {
555 synchronized (state) {
556 if (state.myUnresolvedExtensionsCache == null) {
557 List<MavenArtifact> result = new ArrayList<MavenArtifact>();
558 for (MavenArtifact each : state.myExtensions) {
559 // Collect only extensions that were attempted to be resolved.
560 // It is because embedder does not even try to resolve extensions that
561 // are not necessary.
562 if (state.myUnresolvedArtifactIds.contains(each.getMavenId())
563 && !pomFileExists(state.myLocalRepository, each)) {
564 result.add(each);
567 state.myUnresolvedExtensionsCache = result;
571 return state.myUnresolvedExtensionsCache;
574 private static boolean pomFileExists(File localRepository, MavenArtifact artifact) {
575 return MavenArtifactUtil.hasArtifactFile(localRepository, artifact.getMavenId(), "pom");
578 private static List<MavenPlugin> getUnresolvedPlugins(State state) {
579 if (state.myUnresolvedPluginsCache == null) {
580 synchronized (state) {
581 if (state.myUnresolvedPluginsCache == null) {
582 List<MavenPlugin> result = new ArrayList<MavenPlugin>();
583 for (MavenPlugin each : getDeclaredPlugins(state)) {
584 if (!MavenArtifactUtil.hasArtifactFile(state.myLocalRepository, each.getMavenId())) {
585 result.add(each);
588 state.myUnresolvedPluginsCache = result;
592 return state.myUnresolvedPluginsCache;
595 public List<VirtualFile> getExistingModuleFiles() {
596 LocalFileSystem fs = LocalFileSystem.getInstance();
598 List<VirtualFile> result = new ArrayList<VirtualFile>();
599 Set<String> pathsInStack = getModulePaths();
600 for (String each : pathsInStack) {
601 VirtualFile f = fs.findFileByPath(each);
602 if (f != null) result.add(f);
604 return result;
607 public Set<String> getModulePaths() {
608 return getModulesPathsAndNames().keySet();
611 public Map<String, String> getModulesPathsAndNames() {
612 return myState.myModulesPathsAndNames;
615 public Collection<String> getProfilesIds() {
616 return myState.myProfilesIds;
619 public List<MavenArtifact> getDependencies() {
620 return myState.myDependencies;
623 public List<MavenArtifactNode> getDependenciesNodes() {
624 return buildDependenciesNodes(myState.myDependencies);
627 private static List<MavenArtifactNode> buildDependenciesNodes(List<MavenArtifact> artifacts) {
628 List<MavenArtifactNode> result = new ArrayList<MavenArtifactNode>();
629 for (MavenArtifact each : artifacts) {
630 List<MavenArtifactNode> currentScope = result;
631 for (String eachKey : each.getTrail()) {
632 MavenArtifactNode node = findNodeFor(eachKey, currentScope, true);
633 if (node == null) {
634 node = findNodeFor(eachKey, result, false);
635 if (node == null) {
636 MavenArtifact artifact = findArtifactFor(eachKey, artifacts);
637 if (artifact == null) break;
638 node = new MavenArtifactNode(artifact, new ArrayList<MavenArtifactNode>());
640 currentScope.add(node);
642 currentScope = node.getDependencies();
645 return result;
648 private static MavenArtifactNode findNodeFor(String artifactKey, Collection<MavenArtifactNode> nodes, boolean strict) {
649 for (MavenArtifactNode each : nodes) {
650 if (each.getArtifact().getDisplayStringWithTypeAndClassifier().equals(artifactKey)) {
651 return each;
654 if (strict) return null;
656 for (MavenArtifactNode each : nodes) {
657 MavenArtifactNode result = findNodeFor(artifactKey, each.getDependencies(), strict);
658 if (result != null) return result;
660 return null;
663 private static MavenArtifact findArtifactFor(String artifactKey, Collection<MavenArtifact> artifacts) {
664 for (MavenArtifact each : artifacts) {
665 if (each.getDisplayStringWithTypeAndClassifier().equals(artifactKey)) {
666 return each;
669 return null;
672 public boolean isSupportedDependency(MavenArtifact artifact) {
673 String t = artifact.getType();
674 if (MavenConstants.TYPE_JAR.equalsIgnoreCase(t)
675 || MavenConstants.TYPE_TEST_JAR.equalsIgnoreCase(t)
676 || "ejb".equalsIgnoreCase(t)
677 || "ejb-client".equalsIgnoreCase(t)) {
678 return true;
681 for (MavenImporter each : getSuitableImporters()) {
682 if (each.isSupportedDependency(artifact)) return true;
684 return false;
687 public void addDependency(MavenArtifact dependency) {
688 State state = myState;
689 List<MavenArtifact> dependenciesCopy = new ArrayList<MavenArtifact>(state.myDependencies);
690 dependenciesCopy.add(dependency);
691 state.myDependencies = dependenciesCopy;
694 public boolean hasUnresolvedArtifacts() {
695 State state = myState;
696 return !isParentResolved(state)
697 || !getUnresolvedDependencies(state).isEmpty()
698 || !getUnresolvedExtensions(state).isEmpty();
701 public boolean hasUnresolvedPlugins() {
702 return !getUnresolvedPlugins(myState).isEmpty();
705 public List<MavenPlugin> getPlugins() {
706 return myState.myPlugins;
709 public List<MavenPlugin> getDeclaredPlugins() {
710 return getDeclaredPlugins(myState);
713 private static List<MavenPlugin> getDeclaredPlugins(State state) {
714 return ContainerUtil.findAll(state.myPlugins, new Condition<MavenPlugin>() {
715 public boolean value(MavenPlugin mavenPlugin) {
716 return !mavenPlugin.isDefault();
721 @Nullable
722 public Element getPluginConfiguration(String groupId, String artifactId) {
723 return doGetPluginOrGoalConfiguration(groupId, artifactId, null);
726 @Nullable
727 public Element getPluginGoalConfiguration(String groupId, String artifactId, String goal) {
728 return doGetPluginOrGoalConfiguration(groupId, artifactId, goal);
731 @Nullable
732 private Element doGetPluginOrGoalConfiguration(String groupId, String artifactId, @Nullable String goalOrNull) {
733 MavenPlugin plugin = findPlugin(groupId, artifactId);
734 if (plugin == null) return null;
736 Element configElement = null;
737 if (goalOrNull == null) {
738 configElement = plugin.getConfigurationElement();
740 else {
741 for (MavenPlugin.Execution each : plugin.getExecutions()) {
742 if (each.getGoals().contains(goalOrNull)) {
743 configElement = each.getConfigurationElement();
747 return configElement;
750 @Nullable
751 public MavenPlugin findPlugin(String groupId, String artifactId) {
752 for (MavenPlugin each : getPlugins()) {
753 if (groupId.equals(each.getGroupId()) && artifactId.equals(each.getArtifactId())) return each;
755 return null;
758 @Nullable
759 public String getSourceLevel() {
760 return getCompilerLevel("source");
763 @Nullable
764 public String getTargetLevel() {
765 return getCompilerLevel("target");
768 private String getCompilerLevel(String level) {
769 String result = MavenJDOMUtil.findChildValueByPath(getPluginConfiguration("org.apache.maven.plugins", "maven-compiler-plugin"), level);
770 return normalizeCompilerLevel(result);
773 private static class CompilerLevelTable {
774 public static Map<String, String> table = new THashMap<String, String>();
776 static {
777 table.put("1.1", "1.1");
778 table.put("1.2", "1.2");
779 table.put("1.3", "1.3");
780 table.put("1.4", "1.4");
781 table.put("1.5", "1.5");
782 table.put("5", "1.5");
783 table.put("1.6", "1.6");
784 table.put("1.7", "1.7");
785 table.put("7", "1.7");
789 public static String normalizeCompilerLevel(String level) {
790 if (level == null) return null;
791 return CompilerLevelTable.table.get(level);
794 public Properties getProperties() {
795 return myState.myProperties;
798 public File getLocalRepository() {
799 return myState.myLocalRepository;
802 public List<MavenRemoteRepository> getRemoteRepositories() {
803 return myState.myRemoteRepositories;
806 public List<MavenImporter> getSuitableImporters() {
807 return MavenImporter.getSuitableImporters(this);
810 @Override
811 public String toString() {
812 return getMavenId().toString();
815 private static class State implements Cloneable, Serializable {
816 long myLastReadStamp = 0;
818 MavenId myMavenId;
819 MavenId myParentId;
820 String myPackaging;
821 String myName;
823 String myFinalName;
824 String myDefaultGoal;
826 String myBuildDirectory;
827 String myOutputDirectory;
828 String myTestOutputDirectory;
830 List<String> mySources;
831 List<String> myTestSources;
832 List<MavenResource> myResources;
833 List<MavenResource> myTestResources;
835 List<String> myFilters;
836 Properties myProperties;
837 List<MavenPlugin> myPlugins;
838 List<MavenArtifact> myExtensions;
840 List<MavenArtifact> myDependencies;
842 Map<String, String> myModulesPathsAndNames;
844 Collection<String> myProfilesIds;
846 Model myStrippedMavenModel;
847 List<MavenRemoteRepository> myRemoteRepositories;
849 Collection<String> myActiveProfilesIds;
850 Collection<MavenProjectProblem> myReadingProblems;
851 Set<MavenId> myUnresolvedArtifactIds;
852 File myLocalRepository;
854 volatile List<MavenProjectProblem> myProblemsCache;
855 volatile List<MavenArtifact> myUnresolvedDependenciesCache;
856 volatile List<MavenPlugin> myUnresolvedPluginsCache;
857 volatile List<MavenArtifact> myUnresolvedExtensionsCache;
859 @Override
860 public State clone() {
861 try {
862 State result = (State)super.clone();
863 result.myProblemsCache = null;
864 result.myUnresolvedDependenciesCache = null;
865 result.myUnresolvedPluginsCache = null;
866 result.myUnresolvedExtensionsCache = null;
867 return result;
869 catch (CloneNotSupportedException e) {
870 throw new RuntimeException(e);
874 public MavenProjectChanges getChanges(State other) {
875 if (myLastReadStamp == 0) return MavenProjectChanges.ALL;
877 MavenProjectChanges result = new MavenProjectChanges();
879 result.packaging |= !Comparing.equal(myPackaging, other.myPackaging);
881 result.output |= !Comparing.equal(myFinalName, other.myFinalName);
882 result.output |= !Comparing.equal(myBuildDirectory, other.myBuildDirectory);
883 result.output |= !Comparing.equal(myOutputDirectory, other.myOutputDirectory);
884 result.output |= !Comparing.equal(myTestOutputDirectory, other.myTestOutputDirectory);
886 result.sources |= !Comparing.equal(mySources, other.mySources);
887 result.sources |= !Comparing.equal(myTestSources, other.myTestSources);
888 result.sources |= !Comparing.equal(myResources, other.myResources);
889 result.sources |= !Comparing.equal(myTestResources, other.myTestResources);
891 boolean repositoryChanged = !Comparing.equal(myLocalRepository, other.myLocalRepository);
893 result.dependencies |= repositoryChanged;
894 result.dependencies |= !Comparing.equal(myDependencies, other.myDependencies);
896 result.plugins |= repositoryChanged;
897 result.plugins |= !Comparing.equal(myPlugins, other.myPlugins);
899 return result;