View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.eclipse;
20  
21  import java.io.File;
22  import java.io.FileOutputStream;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.OutputStream;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.Iterator;
29  import java.util.LinkedHashSet;
30  import java.util.LinkedList;
31  import java.util.List;
32  import java.util.ListIterator;
33  import java.util.Map;
34  import java.util.Set;
35  
36  import org.apache.maven.artifact.Artifact;
37  import org.apache.maven.artifact.handler.ArtifactHandler;
38  import org.apache.maven.model.Build;
39  import org.apache.maven.model.Plugin;
40  import org.apache.maven.model.Resource;
41  import org.apache.maven.plugin.MojoExecutionException;
42  import org.apache.maven.plugin.eclipse.reader.ReadWorkspaceLocations;
43  import org.apache.maven.plugin.eclipse.writers.EclipseAjdtWriter;
44  import org.apache.maven.plugin.eclipse.writers.EclipseClasspathWriter;
45  import org.apache.maven.plugin.eclipse.writers.EclipseManifestWriter;
46  import org.apache.maven.plugin.eclipse.writers.EclipseOSGiManifestWriter;
47  import org.apache.maven.plugin.eclipse.writers.EclipseProjectWriter;
48  import org.apache.maven.plugin.eclipse.writers.EclipseSettingsWriter;
49  import org.apache.maven.plugin.eclipse.writers.EclipseWriterConfig;
50  import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpApplicationXMLWriter;
51  import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponent15Writer;
52  import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponentWriter;
53  import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpFacetsWriter;
54  import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpmodulesWriter;
55  import org.apache.maven.plugin.ide.AbstractIdeSupportMojo;
56  import org.apache.maven.plugin.ide.IdeDependency;
57  import org.apache.maven.plugin.ide.IdeUtils;
58  import org.apache.maven.plugin.ide.JeeUtils;
59  import org.apache.maven.project.MavenProject;
60  import org.codehaus.plexus.resource.ResourceManager;
61  import org.codehaus.plexus.resource.loader.FileResourceLoader;
62  import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
63  import org.codehaus.plexus.util.FileUtils;
64  import org.codehaus.plexus.util.IOUtil;
65  import org.codehaus.plexus.util.StringUtils;
66  import org.codehaus.plexus.util.xml.Xpp3Dom;
67  
68  /**
69   * Generates the following eclipse configuration files:
70   * <ul>
71   * <li><code>.project</code> and <code>.classpath</code> files</li>
72   * <li><code>.setting/org.eclipse.jdt.core.prefs</code> with project specific compiler settings</li>
73   * <li>various configuration files for WTP (Web Tools Project), if the parameter <code>wtpversion</code> is set to a
74   * valid version (WTP configuration is not generated by default)</li>
75   * </ul>
76   * If this goal is run on a multiproject root, dependencies between modules will be configured as direct project
77   * dependencies in Eclipse (unless <code>useProjectReferences</code> is set to <code>false</code>).
78   * 
79   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
80   * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a>
81   * @version $Id: EclipsePlugin.java 779829 2009-05-29 03:41:15Z baerrach $
82   * @goal eclipse
83   * @execute phase="generate-resources"
84   */
85  public class EclipsePlugin
86  extends AbstractIdeSupportMojo
87  {
88      private static final String WEAVE_DEPENDENCY = "weaveDependency";
89  
90      private static final String WEAVE_DEPENDENCIES = "weaveDependencies";
91  
92      private static final String ASPECT_LIBRARY = "aspectLibrary";
93  
94      private static final String ASPECT_LIBRARIES = "aspectLibraries";
95  
96      private static final String ASPECT_DIRECTORY = "aspectDirectory";
97  
98      private static final String TEST_ASPECT_DIRECTORY = "testAspectDirectory";
99  
100     private static final String ASPECTJ_MAVEN_PLUGIN = "aspectj-maven-plugin";
101 
102     private static final String ORG_CODEHAUS_MOJO = "org.codehaus.mojo";
103 
104     private static final String DEFAULT_TEST_ASPECT_DIRECTORY = "src/test/aspect";
105 
106     private static final String DEFAULT_ASPECT_DIRECTORY = "src/main/aspect";
107 
108     private static final String NATURE_WST_FACET_CORE_NATURE = "org.eclipse.wst.common.project.facet.core.nature"; //$NON-NLS-1$
109 
110     private static final String BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER =
111         "org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver"; //$NON-NLS-1$
112 
113     protected static final String BUILDER_WST_VALIDATION = "org.eclipse.wst.validation.validationbuilder"; //$NON-NLS-1$
114 
115     private static final String BUILDER_JDT_CORE_JAVA = "org.eclipse.jdt.core.javabuilder"; //$NON-NLS-1$
116 
117     private static final String BUILDER_WST_COMPONENT_STRUCTURAL =
118         "org.eclipse.wst.common.modulecore.ComponentStructuralBuilder"; //$NON-NLS-1$
119 
120     private static final String BUILDER_WST_FACET = "org.eclipse.wst.common.project.facet.core.builder"; //$NON-NLS-1$
121 
122     private static final String BUILDER_PDE_MANIFEST = "org.eclipse.pde.ManifestBuilder"; //$NON-NLS-1$
123 
124     private static final String BUILDER_PDE_SCHEMA = "org.eclipse.pde.SchemaBuilder"; //$NON-NLS-1$
125 
126     private static final String BUILDER_AJDT_CORE_JAVA = "org.eclipse.ajdt.core.ajbuilder"; //$NON-NLS-1$
127 
128     private static final String NATURE_WST_MODULE_CORE_NATURE = "org.eclipse.wst.common.modulecore.ModuleCoreNature"; //$NON-NLS-1$
129 
130     private static final String NATURE_JDT_CORE_JAVA = "org.eclipse.jdt.core.javanature"; //$NON-NLS-1$
131 
132     private static final String NATURE_JEM_WORKBENCH_JAVA_EMF = "org.eclipse.jem.workbench.JavaEMFNature"; //$NON-NLS-1$
133 
134     private static final String NATURE_PDE_PLUGIN = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$
135 
136     private static final String NATURE_AJDT_CORE_JAVA = "org.eclipse.ajdt.ui.ajnature"; //$NON-NLS-1$
137 
138     protected static final String COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER = "org.eclipse.jdt.launching.JRE_CONTAINER"; //$NON-NLS-1$
139 
140     protected static final String ASPECTJ_RT_CONTAINER = "org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"; //$NON-NLS-1$
141 
142     protected static final String REQUIRED_PLUGINS_CONTAINER = "org.eclipse.pde.core.requiredPlugins"; //$NON-NLS-1$
143 
144     // warning, order is important for binary search
145     public static final String[] WTP_SUPPORTED_VERSIONS = new String[] { "1.0", "1.5", "2.0", "R7", "none" }; //$NON-NLS-1$ //$NON-NLS-2$  //$NON-NLS-3$
146     
147     public static final String ASPECTJ_FILE_PATTERN = "**/*.aj";
148     
149     public static final String JAVA_FILE_PATTERN = "**/*.java"; 
150 
151     /**
152      * Constant for 'artifactId' element in POM.xml.
153      */
154     private static final String POM_ELT_ARTIFACT_ID = "artifactId"; //$NON-NLS-1$
155 
156     /**
157      * Constant for 'groupId' element in POM.xml.
158      */
159     private static final String POM_ELT_GROUP_ID = "groupId"; //$NON-NLS-1$
160 
161     /**
162      * List of eclipse project natures. By default the <code>org.eclipse.jdt.core.javanature</code> nature plus the
163      * needed WTP natures are added. Natures added using this property <strong>replace</strong> the default list.
164      * 
165      * <pre>
166      * &lt;projectnatures&gt;
167      *    &lt;projectnature&gt;org.eclipse.jdt.core.javanature&lt;/projectnature&gt;
168      *    &lt;projectnature&gt;org.eclipse.wst.common.modulecore.ModuleCoreNature&lt;/projectnature&gt;
169      * &lt;/projectnatures&gt;
170      * </pre>
171      * 
172      * @parameter
173      */
174     private List projectnatures;
175 
176     /**
177      * List of artifact to exclude from eclipse classpath, beeing provided by some eclipse classPathContainer
178      * [MECLIPSE-79]
179      * 
180      * @since 2.5
181      * @parameter
182      */
183     private List excludes;
184 
185     /**
186      * List of eclipse project natures to be added to the default ones.
187      * 
188      * <pre>
189      * &lt;additionalProjectnatures&gt;
190      *    &lt;projectnature&gt;org.springframework.ide.eclipse.core.springnature&lt;/projectnature&gt;
191      * &lt;/additionalProjectnatures&gt;
192      * </pre>
193      * 
194      * @parameter
195      */
196     private List additionalProjectnatures;
197 
198     /**
199      * List of eclipse project facets to be added to the default ones.
200      * 
201      * <pre>
202      * &lt;additionalProjectFacets&gt;
203      *    &lt;jst.jsf&gt;1.1&lt;jst.jsf/&gt;
204      * &lt;/additionalProjectFacets&gt;
205      * </pre>
206      * 
207      * @parameter
208      */
209     private Map additionalProjectFacets;
210 
211     /**
212      * List of eclipse build commands. By default the <code>org.eclipse.jdt.core.javabuilder</code> builder plus the
213      * needed WTP builders are added. If you specify any configuration for this parameter, only those buildcommands
214      * specified will be used; the defaults won't be added. Use the <code>additionalBuildCommands</code> parameter for
215      * that. Configuration example: Old style:
216      * 
217      * <pre>
218      * &lt;buildcommands&gt;
219      *    &lt;buildcommand&gt;org.eclipse.wst.common.modulecore.ComponentStructuralBuilder&lt;/buildcommand&gt;
220      *    &lt;buildcommand&gt;org.eclipse.jdt.core.javabuilder&lt;/buildcommand&gt;
221      *    &lt;buildcommand&gt;org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver&lt;/buildcommand&gt;
222      * &lt;/buildcommands&gt;
223      * </pre>
224      * 
225      * For new style, see <code>additionalBuildCommands</code>.
226      * 
227      * @parameter
228      */
229     private List buildcommands;
230 
231     /**
232      * List of eclipse build commands to be added to the default ones. Old style:
233      * 
234      * <pre>
235      * &lt;additionalBuildcommands&gt;
236      *    &lt;buildcommand&gt;org.springframework.ide.eclipse.core.springbuilder&lt;/buildcommand&gt;
237      * &lt;/additionalBuildcommands&gt;
238      * </pre>
239      * 
240      * New style:
241      * 
242      * <pre>
243      * &lt;additionalBuildcommands&gt;
244      *    &lt;buildCommand&gt;
245      *      &lt;name&gt;org.ui.externaltools.ExternalToolBuilder&lt;/name&gt;
246      *      &lt;triggers&gt;auto,full,incremental,&lt;/triggers&gt;
247      *      &lt;arguments&gt;
248      *        &lt;LaunchConfigHandle&gt;&amp;lt;project&amp;gt;./externalToolBuilders/MavenBuilder.launch&lt;/LaunchConfighandle&gt;
249      *      &lt;/arguments&gt;
250      *    &lt;/buildCommand&gt;
251      * &lt;/additionalBuildcommands&gt;
252      * </pre>
253      * 
254      * Note the difference between <code>build<strong>c</strong>ommand</code> and
255      * <code>build<strong>C</strong>ommand</code>. You can mix and match old and new-style configuration entries.
256      * 
257      * @parameter
258      */
259     private List additionalBuildcommands;
260 
261     /**
262      * List of container classpath entries. By default the <code>org.eclipse.jdt.launching.JRE_CONTAINER</code>
263      * classpath container is added. Configuration example:
264      * 
265      * <pre>
266      * &lt;classpathContainers&gt;
267      *    &lt;classpathContainer&gt;org.eclipse.jdt.launching.JRE_CONTAINER&lt;/classpathContainer&gt;
268      *    &lt;classpathContainer&gt;org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v5.5&lt;/classpathContainer&gt;
269      *    &lt;classpathContainer&gt;org.eclipse.jst.j2ee.internal.web.container/artifact&lt;/classpathContainer&gt;
270      * &lt;/classpathContainers&gt;
271      * </pre>
272      * 
273      * @parameter
274      */
275     private List classpathContainers;
276 
277     /**
278      * Enables/disables the downloading of source attachments. Defaults to false. DEPRECATED - use downloadSources
279      * 
280      * @parameter expression="${eclipse.downloadSources}"
281      * @deprecated use downloadSources
282      */
283     private boolean eclipseDownloadSources;
284 
285     /**
286      * Eclipse workspace directory.
287      * 
288      * @parameter expression="${eclipse.projectDir}" alias="outputDir"
289      */
290     private File eclipseProjectDir;
291 
292     /**
293      * When set to false, the plugin will not create sub-projects and instead reference those sub-projects using the
294      * installed package in the local repository
295      * 
296      * @parameter expression="${eclipse.useProjectReferences}" default-value="true"
297      * @required
298      */
299     private boolean useProjectReferences;
300 
301     /**
302      * The default output directory
303      * 
304      * @parameter expression="${outputDirectory}" alias="outputDirectory"
305      *            default-value="${project.build.outputDirectory}"
306      * @required
307      */
308     private File buildOutputDirectory;
309 
310     /**
311      * The version of WTP for which configuration files will be generated. The default value is "none" (don't generate
312      * WTP configuration), supported versions are "R7", "1.0", and "1.5"
313      * 
314      * @parameter expression="${wtpversion}" default-value="none"
315      */
316     private String wtpversion;
317 
318     /**
319      * JEE context name of the WTP module. ( ex. WEB context name ).
320      * 
321      * @parameter expression="${wtpContextName}"
322      */
323     private String wtpContextName;
324 
325     /**
326      * Is it an PDE project? If yes, the plugin adds the necessary natures and build commands to the .project file.
327      * Additionally it copies all libraries to a project local directory and references them instead of referencing the
328      * files in the local Maven repository. It also ensured that the "Bundle-Classpath" in META-INF/MANIFEST.MF is
329      * synchronized.
330      * 
331      * @parameter expression="${eclipse.pde}" default-value="false"
332      */
333     private boolean pde;
334 
335     /**
336      * Is it an AJDT project? If yes, the plugin adds the necessary natures and build commands to the .project file.
337      */
338     private boolean ajdt;
339 
340     /**
341      * The relative path of the manifest file
342      * 
343      * @parameter expression="${eclipse.manifest}" default-value="${basedir}/META-INF/MANIFEST.MF"
344      */
345     private File manifest;
346 
347     /**
348      * Allow to configure additional generic configuration files for eclipse that will be written out to disk when
349      * running eclipse:eclipse. FOr each file you can specify the name and the text content.
350      * 
351      * <pre>
352      * &lt;plugin&gt;
353      *  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
354      *  &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
355      *  &lt;configuration&gt;
356      *   &lt;additionalConfig&gt;
357      *    &lt;file&gt;
358      *      &lt;name&gt;.checkstyle&lt;/name&gt;
359      *      &lt;content&gt;
360      *        &lt;![CDATA[&lt;fileset-config file-format-version=&quot;1.2.0&quot; simple-config=&quot;true&quot;&gt;
361      *          &lt;fileset name=&quot;all&quot; enabled=&quot;true&quot; check-config-name=&quot;acme corporate style&quot; local=&quot;false&quot;&gt;
362      *              &lt;file-match-pattern match-pattern=&quot;.&quot; include-pattern=&quot;true&quot;/&gt;
363      *          &lt;/fileset&gt;
364      *          &lt;filter name=&quot;NonSrcDirs&quot; enabled=&quot;true&quot;/&gt;
365      *        &lt;/fileset-config&gt;]]&gt;
366      *      &lt;/content&gt;
367      *    &lt;/file&gt;
368      *   &lt;/additionalConfig&gt;
369      *  &lt;/configuration&gt;
370      * &lt;/plugin&gt;
371      * </pre>
372      * 
373      * Instead of the content you can also define (from version 2.5) an url to download the file :
374      * 
375      * <pre>
376      * &lt;plugin&gt;
377      *  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
378      *  &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
379      *  &lt;configuration&gt;
380      *   &lt;additionalConfig&gt;
381      *    &lt;file&gt;
382      *      &lt;name&gt;.checkstyle&lt;/name&gt;
383      *      &lt;url&gt;http://some.place.org/path/to/file&lt;/url&gt;
384      *    &lt;/file&gt;
385      *   &lt;/additionalConfig&gt;
386      *  &lt;/configuration&gt;
387      * </pre>
388      * 
389      * or a location :
390      * 
391      * <pre>
392      * &lt;plugin&gt;
393      *  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
394      *  &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
395      *  &lt;configuration&gt;
396      *   &lt;additionalConfig&gt;
397      *    &lt;file&gt;
398      *     &lt;name&gt;.checkstyle&lt;/name&gt;
399      *     &lt;location&gt;/checkstyle-config.xml&lt;/location&gt;
400      *    &lt;/file&gt;
401      *   &lt;/additionalConfig&gt;
402      *  &lt;/configuration&gt;
403      *  &lt;dependencies&gt;
404      *   &lt;!-- The file defined in the location is stored in this dependency --&gt;
405      *   &lt;dependency&gt;
406      *    &lt;groupId&gt;eclipsetest&lt;/groupId&gt;
407      *    &lt;artifactId&gt;checkstyle-config&lt;/artifactId&gt;
408      *    &lt;version&gt;1.0&lt;/version&gt;
409      *   &lt;/dependency&gt;
410      *  &lt;/dependencies&gt;
411      * &lt;/plugin&gt;
412      * </pre>
413      * 
414      * @parameter
415      */
416     private EclipseConfigFile[] additionalConfig;
417 
418     /**
419      * If set to <code>true</code>, the version number of the artifact is appended to the name of the generated Eclipse
420      * project. See projectNameTemplate for other options.
421      * 
422      * @parameter expression="${eclipse.addVersionToProjectName}" default-value="false"
423      */
424     private boolean addVersionToProjectName;
425 
426     /**
427      * If set to <code>true</code>, the groupId of the artifact is appended to the name of the generated Eclipse
428      * project. See projectNameTemplate for other options.
429      * 
430      * @parameter expression="${eclipse.addGroupIdToProjectName}" default-value="false"
431      */
432     private boolean addGroupIdToProjectName;
433 
434     /**
435      * Allows configuring the name of the eclipse projects. This property if set wins over addVersionToProjectName and
436      * addGroupIdToProjectName You can use <code>[groupId]</code>, <code>[artifactId]</code> and <code>[version]</code>
437      * variables. eg. <code>[groupId].[artifactId]-[version]</code>
438      * 
439      * @parameter expression="${eclipse.projectNameTemplate}"
440      */
441     private String projectNameTemplate;
442 
443     /**
444      * Parsed wtp version.
445      */
446     private float wtpVersionFloat;
447 
448     /**
449      * Not a plugin parameter. Is this a java project?
450      */
451     private boolean isJavaProject;
452 
453     /**
454      * Must the manifest files be written for java projects so that that the jee classpath for wtp is correct.
455      * 
456      * @parameter expression="${eclipse.wtpmanifest}" default-value="false"
457      */
458     private boolean wtpmanifest;
459 
460     /**
461      * Must the application files be written for ear projects in a separate directory.
462      * 
463      * @parameter expression="${eclipse.wtpapplicationxml}" default-value="false"
464      */
465     private boolean wtpapplicationxml;
466 
467     /**
468      * What WTP defined server to use for deployment informations.
469      * 
470      * @parameter expression="${eclipse.wtpdefaultserver}"
471      */
472     private String wtpdefaultserver;
473 
474     private WorkspaceConfiguration workspaceConfiguration;
475 
476     /**
477      * ResourceManager for getting additonalConfig files from resources
478      * 
479      * @component
480      * @required
481      * @readonly
482      */
483     private ResourceManager locator;
484 
485     /**
486      * This eclipse workspace is read and all artifacts detected there will be connected as eclipse projects and will
487      * not be linked to the jars in the local repository. Requirement is that it was created with the similar wtp
488      * settings as the reactor projects, but the project name template my differ. The pom's in the workspace projects
489      * may not contain variables in the artefactId, groupId and version tags.
490      * 
491      * If workspace is not defined, then an attempt to locate it by checking up the directory hierarchy will be made.
492      * 
493      * @since 2.5
494      * @parameter expression="${eclipse.workspace}"
495      */
496     protected File workspace;
497 
498     /**
499      * Limit the use of project references to the current workspace. No project references will be created to projects
500      * in the reactor when they are not available in the workspace.
501      * 
502      * @parameter expression="${eclipse.limitProjectReferencesToWorkspace}" default-value="false"
503      */
504     protected boolean limitProjectReferencesToWorkspace;
505 
506     /**
507      * The version of AJDT for which configuration files will be generated. The default value is "1.5", supported
508      * versions are "none", "1.4", and "1.5".
509      * 
510      * @parameter expression="${eclipse.ajdtVersion}" default-value="1.5"
511      */
512     private String ajdtVersion;
513     
514     /**
515      * List of exclusions to add to the source directories on the classpath.
516      * Adds excluding="" to the classpathentry of the eclipse .classpath file.
517      * [MECLIPSE-104]
518      * 
519      * @since 2.6.1
520      * @parameter 
521      */
522     private List sourceExcludes;
523     
524     /**
525      * List of inclusions to add to the source directories on the classpath.
526      * Adds including="" to the classpathentry of the eclipse .classpath file.
527      * <p>
528      * Java projects will always include "**&#47;*.java"
529      * <p>
530      * Ajdt projects will always include "**&#47;*.aj"
531      * <p>
532      * [MECLIPSE-104]
533      * 
534      * @since 2.6.1
535      * @parameter
536      */
537     private List sourceIncludes;
538 
539     protected final boolean isJavaProject()
540     {
541         return isJavaProject;
542     }
543 
544     protected final boolean isPdeProject()
545     {
546         return pde;
547     }
548 
549     /**
550      * Getter for <code>buildcommands</code>.
551      * 
552      * @return Returns the buildcommands.
553      */
554     public final List getBuildcommands()
555     {
556         return buildcommands;
557     }
558 
559     /**
560      * Setter for <code>buildcommands</code>.
561      * 
562      * @param buildcommands The buildcommands to set.
563      */
564     public final void setBuildcommands( List buildcommands )
565     {
566         this.buildcommands = buildcommands;
567     }
568 
569     /**
570      * Getter for <code>buildOutputDirectory</code>.
571      * 
572      * @return Returns the buildOutputDirectory.
573      */
574     public final File getBuildOutputDirectory()
575     {
576         return buildOutputDirectory;
577     }
578 
579     /**
580      * Setter for <code>buildOutputDirectory</code>.
581      * 
582      * @param buildOutputDirectory The buildOutputDirectory to set.
583      */
584     public final void setBuildOutputDirectory( File buildOutputDirectory )
585     {
586         this.buildOutputDirectory = buildOutputDirectory;
587     }
588 
589     /**
590      * Getter for <code>classpathContainers</code>.
591      * 
592      * @return Returns the classpathContainers.
593      */
594     public final List getClasspathContainers()
595     {
596         return classpathContainers;
597     }
598 
599     /**
600      * Setter for <code>classpathContainers</code>.
601      * 
602      * @param classpathContainers The classpathContainers to set.
603      */
604     public final void setClasspathContainers( List classpathContainers )
605     {
606         this.classpathContainers = classpathContainers;
607     }
608 
609     /**
610      * Getter for <code>eclipseProjectDir</code>.
611      * 
612      * @return Returns the eclipseProjectDir.
613      */
614     public final File getEclipseProjectDir()
615     {
616         return eclipseProjectDir;
617     }
618 
619     /**
620      * Setter for <code>eclipseProjectDir</code>.
621      * 
622      * @param eclipseProjectDir The eclipseProjectDir to set.
623      */
624     public final void setEclipseProjectDir( File eclipseProjectDir )
625     {
626         this.eclipseProjectDir = eclipseProjectDir;
627     }
628 
629     /**
630      * Getter for <code>projectnatures</code>.
631      * 
632      * @return Returns the projectnatures.
633      */
634     public final List getProjectnatures()
635     {
636         return projectnatures;
637     }
638 
639     /**
640      * Setter for <code>projectnatures</code>.
641      * 
642      * @param projectnatures The projectnatures to set.
643      */
644     public final void setProjectnatures( List projectnatures )
645     {
646         this.projectnatures = projectnatures;
647     }
648 
649     /**
650      * Getter for <code>useProjectReferences</code>.
651      * 
652      * @return Returns the useProjectReferences.
653      */
654     public final boolean getUseProjectReferences()
655     {
656         return useProjectReferences;
657     }
658 
659     /**
660      * Setter for <code>useProjectReferences</code>.
661      * 
662      * @param useProjectReferences The useProjectReferences to set.
663      */
664     public final void setUseProjectReferences( boolean useProjectReferences )
665     {
666         this.useProjectReferences = useProjectReferences;
667     }
668 
669     /**
670      * Getter for <code>wtpversion</code>.
671      * 
672      * @return Returns the wtpversion.
673      */
674     public final String getWtpversion()
675     {
676         return wtpversion;
677     }
678 
679     /**
680      * Setter for <code>wtpversion</code>.
681      * 
682      * @param wtpversion The wtpversion to set.
683      */
684     public final void setWtpversion( String wtpversion )
685     {
686         this.wtpversion = wtpversion;
687     }
688 
689     /**
690      * Getter for <code>additionalBuildcommands</code>.
691      * 
692      * @return Returns the additionalBuildcommands.
693      */
694     public final List getAdditionalBuildcommands()
695     {
696         return additionalBuildcommands;
697     }
698 
699     /**
700      * Setter for <code>additionalBuildcommands</code>.
701      * 
702      * @param additionalBuildcommands The additionalBuildcommands to set.
703      */
704     public final void setAdditionalBuildcommands( List additionalBuildcommands )
705     {
706         this.additionalBuildcommands = additionalBuildcommands;
707     }
708 
709     /**
710      * Getter for <code>additionalProjectnatures</code>.
711      * 
712      * @return Returns the additionalProjectnatures.
713      */
714     public final List getAdditionalProjectnatures()
715     {
716         return additionalProjectnatures;
717     }
718 
719     /**
720      * Setter for <code>additionalProjectnatures</code>.
721      * 
722      * @param additionalProjectnatures The additionalProjectnatures to set.
723      */
724     public final void setAdditionalProjectnatures( List additionalProjectnatures )
725     {
726         this.additionalProjectnatures = additionalProjectnatures;
727     }
728 
729     /**
730      * Getter for <code>addVersionToProjectName</code>.
731      */
732     public final boolean isAddVersionToProjectName()
733     {
734         return addVersionToProjectName;
735     }
736 
737     /**
738      * Setter for <code>addVersionToProjectName</code>.
739      */
740     public final void setAddVersionToProjectName( boolean addVersionToProjectName )
741     {
742         this.addVersionToProjectName = addVersionToProjectName;
743     }
744 
745     /**
746      * Getter for <code>addGroupIdToProjectName</code>.
747      */
748     public final boolean isAddGroupIdToProjectName()
749     {
750         return addGroupIdToProjectName;
751     }
752 
753     /**
754      * Setter for <code>addGroupIdToProjectName</code>.
755      */
756     public final void setAddGroupIdToProjectName( boolean addGroupIdToProjectName )
757     {
758         this.addGroupIdToProjectName = addGroupIdToProjectName;
759     }
760 
761     /**
762      * Getter for <code>projectNameTemplate</code>
763      * 
764      * @return projectNameTemplate
765      */
766     public final String getProjectNameTemplate()
767     {
768         return projectNameTemplate;
769     }
770 
771     /**
772      * Setter for <code>projectNameTemplate</code>.
773      * 
774      * @param projectNameTemplate projectNameTemplate
775      */
776     public final void setProjectNameTemplate( String projectNameTemplate )
777     {
778         this.projectNameTemplate = projectNameTemplate;
779     }
780 
781     /**
782      * @see org.apache.maven.plugin.Mojo#execute()
783      */
784     public final boolean setup()
785         throws MojoExecutionException
786     {
787         boolean ready = true;
788 
789         checkDeprecations();
790         setProjectNameTemplate( IdeUtils.calculateProjectNameTemplate( getProjectNameTemplate(), isAddVersionToProjectName(),
791                                                               isAddGroupIdToProjectName(), getLog() ) );
792         ajdt = enableAjdt( executedProject ) && !ajdtVersion.equals( "none" );
793         ready = validate();
794 
795         // TODO: Why are we using project in some places, and executedProject in others??
796         ArtifactHandler artifactHandler = project.getArtifact().getArtifactHandler();
797 
798         // ear projects don't contain java sources
799         // pde projects are always java projects
800         isJavaProject =
801             pde
802                 || ( Constants.LANGUAGE_JAVA.equals( artifactHandler.getLanguage() ) && !Constants.PROJECT_PACKAGING_EAR.equals( packaging ) );
803 
804         if ( sourceIncludes == null ) {
805             sourceIncludes = new ArrayList();
806         }
807         if ( isJavaProject ) {
808             sourceIncludes.add( JAVA_FILE_PATTERN );
809         }
810         if ( ajdt ) {
811             sourceIncludes.add( ASPECTJ_FILE_PATTERN );
812         }
813 
814         if ( sourceExcludes == null ) {
815             sourceExcludes = new ArrayList();
816         }
817         
818         setupExtras();
819 
820         parseConfigurationOptions();
821 
822         // defaults
823         if ( projectnatures == null )
824         {
825             fillDefaultNatures( packaging );
826         }
827 
828         if ( additionalProjectnatures != null )
829         {
830             projectnatures.addAll( additionalProjectnatures );
831         }
832 
833         if ( buildcommands == null )
834         {
835             fillDefaultBuilders( packaging );
836         }
837         else
838         {
839             convertBuildCommandList( buildcommands );
840         }
841 
842         if ( additionalBuildcommands != null )
843         {
844             convertBuildCommandList( additionalBuildcommands );
845             buildcommands.addAll( additionalBuildcommands );
846         }
847 
848         if ( classpathContainers == null )
849         {
850             fillDefaultClasspathContainers( packaging );
851         }
852         else
853         {
854             verifyClasspathContainerListIsComplete();
855         }
856         locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() );
857         locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) );
858 
859         // ready to start
860         return ready;
861     }
862 
863     /**
864      * Convert any Strings in the <code>commands</code> List to <code>BuildCommand</code>s. The conversion happens
865      * in situ.
866      * 
867      * @param commands a list of commands to convert into <code>BuildCommand</code>
868      */
869     protected final void convertBuildCommandList( List commands )
870     {
871         if ( commands != null )
872         {
873             for ( ListIterator i = commands.listIterator(); i.hasNext(); )
874             {
875                 Object command = i.next();
876 
877                 if ( command instanceof String )
878                 {
879                     command = new BuildCommand( (String) command );
880                     i.set( command );
881                 }
882             }
883         }
884     }
885 
886     private void parseConfigurationOptions()
887     {
888         if ( "R7".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
889         {
890             wtpVersionFloat = 0.7f;
891         }
892         else if ( "1.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
893         {
894             wtpVersionFloat = 1.0f;
895         }
896         else if ( "1.5".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
897         {
898             wtpVersionFloat = 1.5f;
899         }
900         else if ( "2.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
901         {
902             wtpVersionFloat = 2.0f;
903         }
904         if ( !"none".equalsIgnoreCase( wtpversion ) )
905         {
906             getLog().info( Messages.getString( "EclipsePlugin.wtpversion", wtpversion ) );
907         }
908     }
909 
910     /**
911      * Extension point for subclasses.
912      * <p>
913      * Called during <code>setup</code>.
914      * 
915      * @throws MojoExecutionException mojo failures.
916      */
917     protected void setupExtras()
918         throws MojoExecutionException
919     {
920         // extension point.
921     }
922 
923     private void verifyClasspathContainerListIsComplete()
924     {
925         boolean containsJREContainer = false;
926         // Check if classpathContainer contains a JRE (default, alternate or
927         // Execution Environment)
928         for ( Iterator iter = classpathContainers.iterator(); iter.hasNext(); )
929         {
930             Object classPathContainer = iter.next();
931             if ( classPathContainer != null
932                 && classPathContainer.toString().startsWith( COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ) )
933             {
934                 containsJREContainer = true;
935                 break;
936             }
937         }
938         if ( !containsJREContainer )
939         {
940             getLog().warn( Messages.getString( "EclipsePlugin.missingjrecontainer" ) ); //$NON-NLS-1$
941             classpathContainers.add( 0, COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER );
942         }
943     }
944 
945     private boolean validate()
946         throws MojoExecutionException
947     {
948         // validate sanity of the current m2 project
949         if ( Arrays.binarySearch( WTP_SUPPORTED_VERSIONS, wtpversion ) < 0 )
950         {
951             throw new MojoExecutionException(
952                                               Messages.getString( "EclipsePlugin.unsupportedwtp", new Object[] { //$NON-NLS-1$
953                                                                   wtpversion,
954                                                                       StringUtils.join( WTP_SUPPORTED_VERSIONS, " " ) } ) ); //$NON-NLS-1$
955         }
956 
957         assertNotEmpty( executedProject.getGroupId(), POM_ELT_GROUP_ID );
958         assertNotEmpty( executedProject.getArtifactId(), POM_ELT_ARTIFACT_ID );
959 
960         if ( executedProject.getFile() == null || !executedProject.getFile().exists() )
961         {
962             throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingpom" ) ); //$NON-NLS-1$
963         }
964 
965         if ( "pom".equals( packaging ) && eclipseProjectDir == null ) //$NON-NLS-1$
966         {
967             getLog().info( Messages.getString( "EclipsePlugin.pompackaging" ) ); //$NON-NLS-1$
968             return false;
969         }
970 
971         if ( "eclipse-plugin".equals( packaging ) )
972         {
973             pde = true;
974         }
975 
976         if ( eclipseProjectDir == null )
977         {
978             eclipseProjectDir = executedProject.getFile().getParentFile();
979         }
980 
981         if ( !eclipseProjectDir.exists() && !eclipseProjectDir.mkdirs() )
982         {
983             throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) ); //$NON-NLS-1$
984         }
985 
986         if ( !eclipseProjectDir.equals( executedProject.getFile().getParentFile() ) )
987         {
988             if ( !eclipseProjectDir.isDirectory() )
989             {
990                 throw new MojoExecutionException( Messages.getString( "EclipsePlugin.notadir", eclipseProjectDir ) ); //$NON-NLS-1$
991             }
992             eclipseProjectDir = new File( eclipseProjectDir, executedProject.getArtifactId() );
993             if ( !eclipseProjectDir.isDirectory() && !eclipseProjectDir.mkdirs() )
994             {
995                 throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) ); //$NON-NLS-1$
996             }
997         }
998 
999         validateExtras();
1000 
1001         return true;
1002     }
1003 
1004     /**
1005      * Extension point for subclasses.
1006      * <p>
1007      * Called during <code>setup</code> and used to validate that the configuration is sane.
1008      * 
1009      * @throws MojoExecutionException mojo failures.
1010      */
1011     protected void validateExtras() throws MojoExecutionException
1012     {
1013         // provided for extension.
1014     }
1015 
1016     private void checkDeprecations()
1017     {
1018         if ( eclipseDownloadSources )
1019         {
1020             // deprecated warning
1021             getLog().warn( Messages.getString( "EclipsePlugin.deprecatedpar", new Object[] { //$NON-NLS-1$
1022                                                "eclipse.downloadSources", //$NON-NLS-1$
1023                                                    "downloadSources" } ) ); //$NON-NLS-1$
1024             downloadSources = true;
1025         }
1026 
1027         checkDeprecationsExtras();
1028     }
1029 
1030     /**
1031      * Extension point for subclasses.
1032      * <p>
1033      * Check for any extra deprecations and log warnings. Called during <code>setup</code>
1034      */
1035     protected void checkDeprecationsExtras()
1036     {
1037         // provided for extension.
1038     }
1039 
1040     public final void writeConfiguration( IdeDependency[] deps )
1041         throws MojoExecutionException
1042     {
1043         EclipseWriterConfig config = createEclipseWriterConfig( deps );
1044 
1045         if ( wtpmanifest && isJavaProject() )
1046         {
1047             // NOTE: This could change the config!            
1048             EclipseManifestWriter.addManifestResource( getLog(), config );
1049         }
1050         // NOTE: This could change the config!
1051         writeConfigurationExtras( config );
1052 
1053         if ( wtpVersionFloat == 0.7f )
1054         {
1055             new EclipseWtpmodulesWriter().init( getLog(), config ).write();
1056         }
1057 
1058         if ( wtpVersionFloat >= 1.0f )
1059         {
1060             new EclipseWtpFacetsWriter().init( getLog(), config ).write();
1061         }
1062         if ( wtpVersionFloat == 1.0f )
1063         {
1064             new EclipseWtpComponentWriter().init( getLog(), config ).write();
1065         }
1066         if ( wtpVersionFloat >= 1.5 )
1067         {
1068             new EclipseWtpComponent15Writer().init( getLog(), config ).write();
1069         }
1070 
1071         new EclipseSettingsWriter().init( getLog(), config ).write();
1072 
1073         if ( isJavaProject )
1074         {
1075             new EclipseClasspathWriter().init( getLog(), config ).write();
1076             if ( ajdt && ajdtVersion.equals( "1.4" ) )
1077             {
1078                 new EclipseAjdtWriter().init( getLog(), config ).write();
1079             }
1080         }
1081 
1082         if ( wtpapplicationxml )
1083         {
1084             new EclipseWtpApplicationXMLWriter().init( getLog(), config ).write();
1085         }
1086 
1087         if ( pde )
1088         {
1089             this.getLog().info( "The Maven Eclipse plugin runs in 'pde'-mode." );
1090             new EclipseOSGiManifestWriter().init( getLog(), config ).write();
1091         }
1092 
1093         // NOTE: This one MUST be after EclipseClasspathwriter, and possibly others,
1094         // since currently EclipseClasspathWriter does some magic to detect nested
1095         // output folders and modifies the configuration by adding new (Ant) builders.
1096         // So the .project file must be written AFTER those have run!
1097         new EclipseProjectWriter().init( getLog(), config ).write();
1098 
1099         writeAdditionalConfig();
1100 
1101         getLog().info( Messages.getString( "EclipsePlugin.wrote", new Object[] { //$NON-NLS-1$
1102                                            config.getEclipseProjectName(), eclipseProjectDir.getAbsolutePath() } ) );
1103     }
1104 
1105     private void writeAdditionalConfig()
1106         throws MojoExecutionException
1107     {
1108         if ( additionalConfig != null )
1109         {
1110             for ( int j = 0; j < additionalConfig.length; j++ )
1111             {
1112                 EclipseConfigFile file = additionalConfig[j];
1113                 File projectRelativeFile = new File( eclipseProjectDir, file.getName() );
1114                 if ( projectRelativeFile.isDirectory() )
1115                 {
1116                     // just ignore?
1117                     getLog().warn( Messages.getString( "EclipsePlugin.foundadir", //$NON-NLS-1$
1118                                                        projectRelativeFile.getAbsolutePath() ) );
1119                 }
1120 
1121                 try
1122                 {
1123                     projectRelativeFile.getParentFile().mkdirs();
1124                     if ( file.getContent() == null )
1125                     {
1126                         InputStream inStream;
1127                         if ( file.getLocation() != null )
1128                         {
1129                             inStream = locator.getResourceAsInputStream( file.getLocation() );
1130                         }
1131                         else
1132                         {
1133                             inStream = file.getURL().openConnection().getInputStream();
1134                         }
1135                         OutputStream outStream = new FileOutputStream( projectRelativeFile );
1136                         try
1137                         {
1138                             IOUtil.copy( inStream, outStream );
1139                         }
1140                         finally
1141                         {
1142                             inStream.close();
1143                             outStream.close();
1144                         }
1145                     }
1146                     else
1147                     {
1148                         FileUtils.fileWrite( projectRelativeFile.getAbsolutePath(), file.getContent() );
1149                     }
1150                 }
1151                 catch ( IOException e )
1152                 {
1153                     throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantwritetofile", //$NON-NLS-1$
1154                                                                           projectRelativeFile.getAbsolutePath() ) );
1155                 }
1156                 catch ( ResourceNotFoundException e )
1157                 {
1158                     throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantfindresource", //$NON-NLS-1$
1159                                                                           file.getLocation() ) );
1160                 }
1161 
1162             }
1163         }
1164     }
1165 
1166     /**
1167      * Create the <code>EclipseWriterConfig</code> for the specified dependencies.
1168      * 
1169      * @param deps the project dependencies
1170      * @return a configured <code>EclipseWriterConfig</code>
1171      * @throws MojoExecutionException mojo failures.
1172      */
1173     protected final EclipseWriterConfig createEclipseWriterConfig( IdeDependency[] deps )
1174         throws MojoExecutionException
1175     {
1176         File projectBaseDir = executedProject.getFile().getParentFile();
1177 
1178         // build a list of UNIQUE source dirs (both src and resources) to be
1179         // used in classpath and wtpmodules
1180         EclipseSourceDir[] sourceDirs = buildDirectoryList( executedProject, eclipseProjectDir, buildOutputDirectory );
1181 
1182         EclipseWriterConfig config = new EclipseWriterConfig();
1183 
1184         config.setWorkspaceConfiguration( getWorkspaceConfiguration() );
1185 
1186         config.setProjectNameTemplate( getProjectNameTemplate() );
1187 
1188         String projectName = IdeUtils.getProjectName( config.getProjectNameTemplate(), project );
1189 
1190         config.setEclipseProjectName( projectName );
1191 
1192         config.setWtpapplicationxml( wtpapplicationxml );
1193 
1194         config.setWtpVersion( wtpVersionFloat );
1195 
1196         float ajdtVersionFloat;
1197         try
1198         {
1199             ajdtVersionFloat = Float.parseFloat( ajdtVersion );
1200         }
1201         catch ( NumberFormatException e )
1202         {
1203             ajdtVersionFloat = 0.0f;
1204         }
1205 
1206         config.setAjdtVersion( ajdtVersionFloat );
1207 
1208         Set convertedBuildCommands = new LinkedHashSet();
1209 
1210         if ( buildcommands != null )
1211         {
1212             for ( Iterator it = buildcommands.iterator(); it.hasNext(); )
1213             {
1214                 Object cmd = it.next();
1215 
1216                 if ( cmd instanceof BuildCommand )
1217                 {
1218                     convertedBuildCommands.add( cmd );
1219                 }
1220                 else
1221                 {
1222                     convertedBuildCommands.add( new BuildCommand( (String) cmd ) );
1223                 }
1224             }
1225         }
1226 
1227         if ( ajdt )
1228         {
1229             buildAjdtWeaveDeps( deps );
1230             buildAspectjDeps( deps );
1231         }
1232 
1233         config.setBuildCommands( new LinkedList( convertedBuildCommands ) );
1234 
1235         config.setBuildOutputDirectory( buildOutputDirectory );
1236         config.setClasspathContainers( classpathContainers );
1237         config.setDeps( deps );
1238         config.setEclipseProjectDirectory( eclipseProjectDir );
1239         config.setLocalRepository( localRepository );
1240         config.setOSGIManifestFile( manifest );
1241         config.setPde( pde );
1242         config.setProject( project );
1243         config.setProjectBaseDir( projectBaseDir );
1244         config.setProjectnatures( projectnatures );
1245         config.setProjectFacets( additionalProjectFacets );
1246         config.setSourceDirs( sourceDirs );
1247         config.setAddVersionToProjectName( isAddVersionToProjectName() );
1248         config.setPackaging( packaging );
1249 
1250         collectWarContextRootsFromReactorEarConfiguration( config );
1251 
1252         return config;
1253     }
1254 
1255     /**
1256      * If this is a war module peek into the reactor an search for an ear module that defines the context root of this
1257      * module.
1258      * 
1259      * @param config config to save the context root.
1260      */
1261     private void collectWarContextRootsFromReactorEarConfiguration( EclipseWriterConfig config )
1262     {
1263         if ( reactorProjects != null && wtpContextName == null
1264             && Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) )
1265         {
1266             for ( Iterator iter = reactorProjects.iterator(); iter.hasNext(); )
1267             {
1268                 MavenProject reactorProject = (MavenProject) iter.next();
1269 
1270                 if ( Constants.PROJECT_PACKAGING_EAR.equals( reactorProject.getPackaging() ) )
1271                 {
1272                     Xpp3Dom[] warDefinitions =
1273                         IdeUtils.getPluginConfigurationDom( reactorProject, JeeUtils.ARTIFACT_MAVEN_EAR_PLUGIN,
1274                                                             new String[] { "modules", "webModule" } );
1275                     for ( int index = 0; index < warDefinitions.length; index++ )
1276                     {
1277                         Xpp3Dom groupId = warDefinitions[index].getChild( "groupId" );
1278                         Xpp3Dom artifactId = warDefinitions[index].getChild( "artifactId" );
1279                         Xpp3Dom contextRoot = warDefinitions[index].getChild( "contextRoot" );
1280                         if ( groupId != null && artifactId != null && contextRoot != null && groupId.getValue() != null
1281                             && artifactId.getValue() != null && contextRoot.getValue() != null )
1282                         {
1283                             getLog().info(
1284                                            "Found context root definition for " + groupId.getValue() + ":"
1285                                                + artifactId.getValue() + " " + contextRoot.getValue() );
1286                             if ( project.getArtifactId().equals( artifactId.getValue() )
1287                                 && project.getGroupId().equals( groupId.getValue() ) )
1288                             {
1289                                 config.setContextName( contextRoot.getValue() );
1290                             }
1291                         }
1292                         else
1293                         {
1294                             getLog().info(
1295                                            "Found incomplete ear configuration in " + reactorProject.getGroupId() + ":"
1296                                                + reactorProject.getGroupId() + " found "
1297                                                + warDefinitions[index].toString() );
1298                         }
1299                     }
1300                 }
1301             }
1302         }
1303         if ( config.getContextName() == null && Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) )
1304         {
1305             if ( wtpContextName == null )
1306             {
1307                 config.setContextName( project.getArtifactId() );
1308             }
1309             else
1310             {
1311                 config.setContextName( wtpContextName );
1312             }
1313         }
1314     }
1315 
1316     /**
1317      * Write any extra configuration information for the Eclipse project. This is an extension point, called before the
1318      * main configurations are written. <br/> <b> NOTE: This could change the config! </b>
1319      * 
1320      * @param config
1321      * @throws MojoExecutionException
1322      */
1323     protected void writeConfigurationExtras( EclipseWriterConfig config )
1324         throws MojoExecutionException
1325     {
1326         // extension point.
1327     }
1328 
1329     private void assertNotEmpty( String string, String elementName )
1330         throws MojoExecutionException
1331     {
1332         if ( string == null )
1333         {
1334             throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingelement", elementName ) ); //$NON-NLS-1$
1335         }
1336     }
1337     
1338     /**
1339      * Fill getProjectnatures() with values.
1340      * <p>
1341      * Subclasses should call super and then calculate their own additions and insert them via
1342      * <code>getProjectnatures().addAll()</code>.
1343      * 
1344      * @param packaging the pom's packaging
1345      */    
1346     protected void fillDefaultNatures( String packaging )
1347     {
1348         projectnatures = new ArrayList();
1349 
1350         if ( wtpVersionFloat >= 1.0f )
1351         {
1352             projectnatures.add( NATURE_WST_FACET_CORE_NATURE ); // WTP 1.0 nature
1353         }
1354 
1355         if ( isJavaProject )
1356         {
1357             if ( ajdt )
1358             {
1359                 projectnatures.add( NATURE_AJDT_CORE_JAVA );
1360             }
1361 
1362             projectnatures.add( NATURE_JDT_CORE_JAVA );
1363         }
1364 
1365         if ( wtpVersionFloat >= 0.7f )
1366         {
1367             projectnatures.add( NATURE_WST_MODULE_CORE_NATURE ); // WTP 0.7/1.0 nature
1368 
1369             if ( isJavaProject )
1370             {
1371                 projectnatures.add( NATURE_JEM_WORKBENCH_JAVA_EMF ); // WTP 0.7/1.0 nature
1372             }
1373         }
1374 
1375         if ( pde )
1376         {
1377             projectnatures.add( NATURE_PDE_PLUGIN );
1378         }
1379 
1380     }
1381 
1382     /**
1383      * Fill getClasspathContainers() with values.
1384      * <p>
1385      * Subclasses should call super and then calculate their own additions and insert them via
1386      * <code>getClasspathContainers().addAll()</code>.
1387      * 
1388      * @param packaging the pom's packaging
1389      */
1390     protected void fillDefaultClasspathContainers( String packaging )
1391     {
1392         classpathContainers = new ArrayList();
1393 
1394         if ( getWorkspaceConfiguration().getDefaultClasspathContainer() != null )
1395         {
1396             getLog().info(
1397                            "Adding default classpath container: "
1398                                + getWorkspaceConfiguration().getDefaultClasspathContainer() );
1399             classpathContainers.add( getWorkspaceConfiguration().getDefaultClasspathContainer() );
1400         }
1401         if ( pde )
1402         {
1403             classpathContainers.add( REQUIRED_PLUGINS_CONTAINER );
1404         }
1405 
1406         if ( ajdt )
1407         {
1408             classpathContainers.add( ASPECTJ_RT_CONTAINER );
1409         }
1410     }
1411 
1412     /**
1413      * Fill getBuildcommands() with values.
1414      * <p>
1415      * Subclasses should call super and then calculate their own additions and insert them via
1416      * <code>getBuildcommands().addAll()</code>.
1417      * 
1418      * @param packaging the pom's packaging
1419      */
1420     protected void fillDefaultBuilders( String packaging )
1421     {
1422         buildcommands = new ArrayList();
1423 
1424         if ( wtpVersionFloat == 0.7f )
1425         {
1426             buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL ) ); // WTP 0.7 builder
1427         }
1428 
1429         if ( isJavaProject )
1430         {
1431             if ( ajdt )
1432             {
1433                 buildcommands.add( new BuildCommand( BUILDER_AJDT_CORE_JAVA ) );
1434             }
1435             else
1436             {
1437                 buildcommands.add( new BuildCommand( BUILDER_JDT_CORE_JAVA ) );
1438             }
1439         }
1440 
1441         if ( wtpVersionFloat >= 1.5f )
1442         {
1443             buildcommands.add( new BuildCommand( BUILDER_WST_FACET ) ); // WTP 1.5 builder
1444         }
1445 
1446         if ( wtpVersionFloat >= 0.7f )
1447         {
1448             buildcommands.add( new BuildCommand( BUILDER_WST_VALIDATION ) ); // WTP 0.7/1.0 builder
1449         }
1450 
1451         if ( wtpVersionFloat == 0.7f )
1452         {
1453             // WTP 0.7 builder
1454             buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER ) );
1455         }
1456 
1457         if ( pde )
1458         {
1459             buildcommands.add( new BuildCommand( BUILDER_PDE_MANIFEST ) );
1460             buildcommands.add( new BuildCommand( BUILDER_PDE_SCHEMA ) );
1461         }
1462     }
1463 
1464     public final EclipseSourceDir[] buildDirectoryList( MavenProject project, File basedir, File buildOutputDirectory )
1465         throws MojoExecutionException
1466     {
1467         File projectBaseDir = project.getFile().getParentFile();
1468 
1469         String mainOutput = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, buildOutputDirectory, false );
1470 
1471         // If using the standard output location, don't mix the test output into it.
1472         String testOutput = null;
1473         boolean useStandardOutputDir =
1474             buildOutputDirectory.equals( new File( project.getBuild().getOutputDirectory() ) );
1475         if ( useStandardOutputDir )
1476         {
1477             getLog().debug(
1478                             "testOutput toRelativeAndFixSeparator " + projectBaseDir + " , "
1479                                 + project.getBuild().getTestOutputDirectory() );
1480             testOutput =
1481                 IdeUtils.toRelativeAndFixSeparator( projectBaseDir,
1482                                                     new File( project.getBuild().getTestOutputDirectory() ), false );
1483             getLog().debug( "testOutput after toRelative : " + testOutput );
1484         }
1485 
1486         Set mainDirectories = new LinkedHashSet();
1487 
1488         extractSourceDirs( mainDirectories, project.getCompileSourceRoots(), basedir, projectBaseDir, false, null );
1489 
1490         extractResourceDirs( mainDirectories, project.getBuild().getResources(), basedir, projectBaseDir, false,
1491                              mainOutput );
1492 
1493         Set testDirectories = new LinkedHashSet();
1494 
1495         extractSourceDirs( testDirectories, project.getTestCompileSourceRoots(), basedir, projectBaseDir, true,
1496                            testOutput );
1497 
1498         extractResourceDirs( testDirectories, project.getBuild().getTestResources(), basedir, projectBaseDir, true,
1499                              testOutput );
1500 
1501         // avoid duplicated entries
1502         Set directories = new LinkedHashSet();
1503 
1504         // NOTE: Since MNG-3118, test classes come before main classes
1505         boolean testBeforeMain = isMavenVersion( "[2.0.8,)" );
1506 
1507         if ( testBeforeMain )
1508         {
1509             directories.addAll( testDirectories );
1510             directories.removeAll( mainDirectories );
1511             directories.addAll( mainDirectories );
1512         }
1513         else
1514         {
1515             directories.addAll( mainDirectories );
1516             directories.addAll( testDirectories );
1517         }
1518         if ( ajdt )
1519             extractAspectDirs( directories, project, basedir, projectBaseDir, testOutput );
1520         return (EclipseSourceDir[]) directories.toArray( new EclipseSourceDir[directories.size()] );
1521     }
1522 
1523     private void extractSourceDirs( Set directories, List sourceRoots, File basedir, File projectBaseDir, boolean test,
1524                                     String output )
1525         throws MojoExecutionException
1526     {
1527         for ( Iterator it = sourceRoots.iterator(); it.hasNext(); )
1528         {
1529 
1530             File sourceRootFile = new File( (String) it.next() );
1531 
1532             if ( sourceRootFile.isDirectory() )
1533             {
1534                 String sourceRoot =
1535                     IdeUtils.toRelativeAndFixSeparator( projectBaseDir, sourceRootFile,
1536                                                         !projectBaseDir.equals( basedir ) );
1537 
1538                 directories.add( new EclipseSourceDir( sourceRoot, output, false, test, sourceIncludes, sourceExcludes, false ) ); 
1539             }
1540         }
1541     }
1542 
1543     final void extractResourceDirs( Set directories, List resources, File basedir, File workspaceProjectBaseDir,
1544                               boolean test, final String output )
1545         throws MojoExecutionException
1546     {
1547         for ( Iterator it = resources.iterator(); it.hasNext(); )
1548         {
1549             Resource resource = (Resource) it.next();
1550 
1551             getLog().debug( "Processing resource dir: " + resource.getDirectory() );
1552 
1553             List excludes = new ArrayList( resource.getExcludes() );
1554             // automatically exclude java files: eclipse doesn't have the concept of resource directory so it will
1555             // try to compile any java file found in maven resource dirs
1556             excludes.add( JAVA_FILE_PATTERN );
1557 
1558             // TODO: figure out how to merge if the same dir is specified twice
1559             // with different in/exclude patterns.
1560 
1561             File resourceDirectory = new File( /* basedir, */resource.getDirectory() );
1562 
1563             if ( !resourceDirectory.exists() || !resourceDirectory.isDirectory() )
1564             {
1565                 getLog().debug( "Resource dir: " + resourceDirectory + " either missing or not a directory." );
1566                 continue;
1567             }
1568 
1569             String resourcePath =
1570                 IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, resourceDirectory,
1571                                                     !workspaceProjectBaseDir.equals( basedir ) );
1572             String thisOutput = output;
1573             if ( thisOutput != null )
1574             {
1575                 // sometimes thisOutput is already an absolute path
1576                 File outputFile = new File( thisOutput );
1577                 if ( !outputFile.isAbsolute() )
1578                 {
1579                     outputFile = new File( workspaceProjectBaseDir, thisOutput );
1580                 }
1581                 // create output dir if it doesn't exist
1582                 outputFile.mkdirs();
1583 
1584                 if ( !StringUtils.isEmpty( resource.getTargetPath() ) )
1585                 {
1586                     outputFile = new File( outputFile, resource.getTargetPath() );
1587                     // create output dir if it doesn't exist
1588                     outputFile.mkdirs();
1589                 }
1590 
1591                 getLog().debug(
1592                                 "Making relative and fixing separator: { " + workspaceProjectBaseDir + ", "
1593                                     + outputFile + ", false }." );
1594                 thisOutput = IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, outputFile, false );
1595             }
1596 
1597             EclipseSourceDir resourceDir = new EclipseSourceDir( resourcePath, thisOutput, true, test, resource.getIncludes(), excludes,
1598                                   resource.isFiltering() );
1599 
1600             if (!directories.add( resourceDir )) {
1601                 EclipseSourceDir originalDir = (EclipseSourceDir) get(directories, resourceDir);
1602                 getLog().info(
1603                                "Resource directory's path matches an existing source directory. Resources will be merged with the source directory "
1604                                    + originalDir.getPath() );
1605                 originalDir.merge( resourceDir );
1606             }
1607         }
1608     }
1609     
1610     /**
1611      * java.util.Set doesn't have a get() method that returns the matching object.
1612      * Since we use objects that are different by conceptually "equal" based
1613      * on the path we need to locate the original object out of the Set. 
1614      *
1615      * @param set the set to iterate over looking for the specified object
1616      * @param o the object to locate in the set
1617      * @return the object from the set, or null if not found in the set
1618      */
1619     private Object get(Set set, Object o) {
1620         Iterator iter = set.iterator();
1621         while ( iter.hasNext() ) {
1622             Object item = iter.next();
1623             if (o.equals( item )) {
1624                 return item;
1625             }
1626         }
1627         return null;
1628     }
1629 
1630     private void extractAspectDirs( Set directories, MavenProject project, File basedir, File projectBaseDir,
1631                                     String testOutput )
1632         throws MojoExecutionException
1633     {
1634         Xpp3Dom configuration = getAspectjConfiguration( project );
1635         if ( configuration != null )
1636         {
1637             String aspectDirectory = DEFAULT_ASPECT_DIRECTORY;
1638             Xpp3Dom aspectDirectoryElement = configuration.getChild( ASPECT_DIRECTORY );
1639             if ( aspectDirectoryElement != null )
1640             {
1641                 aspectDirectory = aspectDirectoryElement.getValue();
1642             }
1643 
1644             File aspectDirectoryFile = new File( basedir, aspectDirectory );
1645             if ( aspectDirectoryFile.exists() && aspectDirectoryFile.isDirectory() )
1646             {
1647                 String sourceRoot =
1648                     IdeUtils.toRelativeAndFixSeparator( projectBaseDir, aspectDirectoryFile,
1649                                                         !projectBaseDir.equals( basedir ) );
1650 
1651                 directories.add( new EclipseSourceDir( sourceRoot, null, false, false, sourceIncludes, sourceExcludes, false ) );
1652             }
1653 
1654             String testAspectDirectory = DEFAULT_TEST_ASPECT_DIRECTORY;
1655             Xpp3Dom testAspectDirectoryElement = configuration.getChild( TEST_ASPECT_DIRECTORY );
1656             if ( testAspectDirectoryElement != null )
1657             {
1658                 testAspectDirectory = testAspectDirectoryElement.getValue();
1659             }
1660 
1661             File testAspectDirectoryFile = new File( basedir, testAspectDirectory );
1662             if ( testAspectDirectoryFile.exists() && testAspectDirectoryFile.isDirectory() )
1663             {
1664                 String sourceRoot =
1665                     IdeUtils.toRelativeAndFixSeparator( projectBaseDir, testAspectDirectoryFile,
1666                                                         !projectBaseDir.equals( basedir ) );
1667 
1668                 directories.add( new EclipseSourceDir( sourceRoot, testOutput, false, true, sourceIncludes, sourceExcludes, false ) );
1669             }
1670         }
1671     }
1672 
1673     private boolean enableAjdt( MavenProject project )
1674     {
1675         boolean enable = false;
1676         List buildPlugins = project.getBuildPlugins();
1677         for ( Iterator it = buildPlugins.iterator(); it.hasNext(); )
1678         {
1679             Plugin plugin = (Plugin) it.next();
1680             if ( plugin.getGroupId().equals( ORG_CODEHAUS_MOJO )
1681                 && plugin.getArtifactId().equals( ASPECTJ_MAVEN_PLUGIN ) )
1682             {
1683                 enable = true;
1684                 break;
1685             }
1686         }
1687 
1688         return enable;
1689     }
1690 
1691     private Xpp3Dom getAspectjConfiguration( MavenProject project )
1692     {
1693         Xpp3Dom configuration = null;
1694         List buildPlugins = project.getBuildPlugins();
1695         for ( Iterator it = buildPlugins.iterator(); it.hasNext(); )
1696         {
1697             Plugin plugin = (Plugin) it.next();
1698             if ( plugin.getGroupId().equals( ORG_CODEHAUS_MOJO )
1699                 && plugin.getArtifactId().equals( ASPECTJ_MAVEN_PLUGIN ) )
1700             {
1701                 configuration = (Xpp3Dom) plugin.getConfiguration();
1702                 break;
1703             }
1704         }
1705 
1706         return configuration;
1707     }
1708 
1709     private void buildAspectjDeps( IdeDependency[] deps )
1710         throws MojoExecutionException
1711     {
1712         Xpp3Dom configuration = getAspectjConfiguration( executedProject );
1713         if ( configuration != null )
1714         {
1715             Xpp3Dom aspectLibrariesParent = configuration.getChild( ASPECT_LIBRARIES );
1716             if ( aspectLibrariesParent != null )
1717             {
1718                 Xpp3Dom[] aspectLibraries = aspectLibrariesParent.getChildren( ASPECT_LIBRARY );
1719                 outerLoop: for ( int i = 0; i < aspectLibraries.length; i++ )
1720                 {
1721                     String artifactId = aspectLibraries[i].getChild( POM_ELT_ARTIFACT_ID ).getValue();
1722                     String groupId = aspectLibraries[i].getChild( POM_ELT_GROUP_ID ).getValue();
1723                     for ( int j = 0; j < deps.length; j++ )
1724                     {
1725                         if ( deps[j].getArtifactId().equals( artifactId ) && deps[j].getGroupId().equals( groupId ) )
1726                         {
1727                             deps[j].setAjdtDependency( true );
1728                             continue outerLoop;
1729                         }
1730                     }
1731 
1732                     throw new MojoExecutionException( "AspectLibrary is not a dependency of project" );
1733                 }
1734             }
1735         }
1736     }
1737 
1738     private void buildAjdtWeaveDeps( IdeDependency[] deps )
1739         throws MojoExecutionException
1740     {
1741         Xpp3Dom configuration = getAspectjConfiguration( executedProject );
1742         if ( configuration != null )
1743         {
1744             Xpp3Dom weaveDependenciesParent = configuration.getChild( WEAVE_DEPENDENCIES );
1745             if ( weaveDependenciesParent != null )
1746             {
1747                 Xpp3Dom[] weaveDependencies = weaveDependenciesParent.getChildren( WEAVE_DEPENDENCY );
1748                 outerLoop: for ( int i = 0; i < weaveDependencies.length; i++ )
1749                 {
1750                     String artifactId = weaveDependencies[i].getChild( POM_ELT_ARTIFACT_ID ).getValue();
1751                     String groupId = weaveDependencies[i].getChild( POM_ELT_GROUP_ID ).getValue();
1752                     for ( int j = 0; j < deps.length; j++ )
1753                     {
1754                         if ( deps[j].getArtifactId().equals( artifactId ) && deps[j].getGroupId().equals( groupId ) )
1755                         {
1756                             deps[j].setAjdtWeaveDependency( true );
1757                             continue outerLoop;
1758                         }
1759                     }
1760 
1761                     throw new MojoExecutionException( "WeaveDependency is not a dependency of project" );
1762                 }
1763             }
1764         }
1765     }
1766     
1767     /**
1768      * {@inheritDoc}
1769      */
1770     public String getProjectNameForArifact( Artifact artifact )
1771     {
1772         IdeDependency[] workspaceArtefacts = getWorkspaceArtefacts();
1773         for ( int index = 0; workspaceArtefacts != null && index < workspaceArtefacts.length; index++ )
1774         {
1775             IdeDependency workspaceArtefact = workspaceArtefacts[index];
1776             if ( workspaceArtefact.isAddedToClasspath()
1777                 && workspaceArtefact.getGroupId().equals( artifact.getGroupId() )
1778                 && workspaceArtefact.getArtifactId().equals( artifact.getArtifactId() ) )
1779             {
1780                 if ( workspaceArtefact.getVersion().equals( artifact.getVersion() ) )
1781                 {
1782                     return workspaceArtefact.getEclipseProjectName();
1783                 }
1784             }
1785         }
1786         MavenProject reactorProject = getReactorProject( artifact );
1787         if ( reactorProject != null ) {
1788             return IdeUtils.getProjectName( getProjectNameTemplateForMavenProject( reactorProject ), artifact );
1789         }
1790         return IdeUtils.getProjectName( getProjectNameTemplate(), artifact );
1791     }
1792     
1793     /**
1794      * @param mavenProject the project to get the projectNameTemplate configuration from
1795      * @return the projectNameTemplate configuration from the specified MavenProject 
1796      */
1797     private String getProjectNameTemplateForMavenProject( MavenProject mavenProject )
1798     {
1799         String projectNameTemplate = null;
1800         boolean addVersionToProjectName = false;
1801         boolean addGroupIdToProjectName = false;
1802 
1803         Build build = mavenProject.getBuild();
1804         if ( build != null )
1805         {
1806             Plugin plugin = (Plugin) build.getPluginsAsMap().get( "org.apache.maven.plugins:maven-eclipse-plugin" );
1807             if ( plugin != null )
1808             {
1809                 Xpp3Dom config = (Xpp3Dom) plugin.getConfiguration();
1810                 if ( config != null )
1811                 {
1812                     Xpp3Dom projectNameTemplateNode = config.getChild( "projectNameTemplate" );
1813                     if ( projectNameTemplateNode != null )
1814                     {
1815                         projectNameTemplate = projectNameTemplateNode.getValue();
1816                     }
1817                     Xpp3Dom addVersionToProjectNameNode = config.getChild( "addVersionToProjectName" );
1818                     addVersionToProjectName = addVersionToProjectNameNode != null;
1819                     Xpp3Dom addGroupIdToProjectNameNode = config.getChild( "addGroupIdToProjectName" );
1820                     addGroupIdToProjectName = addGroupIdToProjectNameNode != null;
1821                 }
1822             }
1823         }
1824         return IdeUtils.calculateProjectNameTemplate(projectNameTemplate, addVersionToProjectName, addGroupIdToProjectName, getLog());
1825     }
1826 
1827     /**
1828      * {@inheritDoc}
1829      */
1830     protected final IdeDependency[] getWorkspaceArtefacts()
1831     {
1832         return getWorkspaceConfiguration().getWorkspaceArtefacts();
1833     }
1834 
1835     public final WorkspaceConfiguration getWorkspaceConfiguration()
1836     {
1837         if ( workspaceConfiguration == null )
1838         {
1839             workspaceConfiguration = new WorkspaceConfiguration();
1840             locateWorkspace();
1841             getLog().info( Messages.getString( "EclipsePlugin.workspace", workspace ) );
1842             workspaceConfiguration.setWorkspaceDirectory( workspace );
1843 
1844             new ReadWorkspaceLocations().init( getLog(), workspaceConfiguration, project, wtpdefaultserver );
1845         }
1846         return workspaceConfiguration;
1847     }
1848 
1849     /**
1850      * If workspace is not defined, then attempt to locate it by checking up the directory hierarchy.
1851      */
1852     private void locateWorkspace()
1853     {
1854         if ( workspace == null )
1855         {
1856             File currentWorkingDirectory = new File( "." ).getAbsoluteFile();
1857             while ( currentWorkingDirectory != null )
1858             {
1859                 File metadataDirectory = new File( currentWorkingDirectory, ".metadata" );
1860                 logger.debug( "Checking for eclipse workspace at " + currentWorkingDirectory );
1861                 if ( metadataDirectory.exists() && metadataDirectory.isDirectory() )
1862                 {
1863                     logger.debug( "  Found workspace at " + currentWorkingDirectory );
1864                     workspace = currentWorkingDirectory;
1865                     return;
1866                 }
1867                 currentWorkingDirectory = currentWorkingDirectory.getParentFile();
1868             }
1869         }
1870     }
1871 
1872     public final List getExcludes()
1873     {
1874         return excludes;
1875     }
1876 
1877     /**
1878      * Utility method that locates a project in the workspace for the given artifact.
1879      * 
1880      * @param artifact the artifact a project should produce.
1881      * @return <code>true</code> if the artifact is produced by a reactor projectart.
1882      */
1883     private boolean isAvailableAsAWorkspaceProject( Artifact artifact )
1884     {
1885         IdeDependency[] workspaceArtefacts = getWorkspaceArtefacts();
1886         for ( int index = 0; workspaceArtefacts != null && index < workspaceArtefacts.length; index++ )
1887         {
1888             IdeDependency workspaceArtefact = workspaceArtefacts[index];
1889             if ( workspaceArtefact.getGroupId().equals( artifact.getGroupId() )
1890                 && workspaceArtefact.getArtifactId().equals( artifact.getArtifactId() ) )
1891             {
1892                 if ( workspaceArtefact.getVersion().equals( artifact.getVersion() ) )
1893                 {
1894                     workspaceArtefact.setAddedToClasspath( true );
1895                     getLog().debug( "Using workspace project: " + workspaceArtefact.getEclipseProjectName() );
1896                     return true;
1897                 }
1898                 else
1899                 {
1900                     getLog().info(
1901                                    "Artifact "
1902                                        + artifact.getId()
1903                                        + " already available as a workspace project, but with different version. Expected: "
1904                                        + artifact.getVersion() + ", found: " + workspaceArtefact.getVersion() );
1905                 }
1906             }
1907         }
1908         return false;
1909     }
1910 
1911     /**
1912      * Checks if jar has to be resolved for the given artifact
1913      * 
1914      * @param art the artifact to check
1915      * @return true if resolution should happen
1916      */
1917     protected final boolean hasToResolveJar( Artifact art )
1918     {
1919         return !( getUseProjectReferences() && isAvailableAsAReactorProject( art ) )
1920             || ( limitProjectReferencesToWorkspace && !( getUseProjectReferences() && isAvailableAsAWorkspaceProject( art ) ) );
1921     }
1922 
1923     /**
1924      * Checks if a projects reference has to be used for the given artifact
1925      * 
1926      * @param art the artifact to check
1927      * @return true if a project reference has to be used.
1928      */
1929     protected final boolean useProjectReference( Artifact art )
1930     {
1931         boolean isReactorProject = getUseProjectReferences() && isAvailableAsAReactorProject( art );
1932         boolean isWorkspaceProject = getUseProjectReferences() && isAvailableAsAWorkspaceProject( art );
1933         return ( isReactorProject && !limitProjectReferencesToWorkspace ) || // default
1934             ( limitProjectReferencesToWorkspace && isWorkspaceProject ) || // limitProjectReferencesToWorkspace
1935             ( !isReactorProject && isWorkspaceProject ); // default + workspace projects
1936     }
1937 }