diff options
Diffstat (limited to 'maven-plugins/tags/maven-bundle-plugin-1.0.1/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java')
-rw-r--r-- | maven-plugins/tags/maven-bundle-plugin-1.0.1/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java | 1556 |
1 files changed, 0 insertions, 1556 deletions
diff --git a/maven-plugins/tags/maven-bundle-plugin-1.0.1/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java b/maven-plugins/tags/maven-bundle-plugin-1.0.1/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java deleted file mode 100644 index 38a906570e..0000000000 --- a/maven-plugins/tags/maven-bundle-plugin-1.0.1/src/main/java/org/apache/tuscany/maven/plugin/eclipse/EclipsePlugin.java +++ /dev/null @@ -1,1556 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.maven.plugin.eclipse; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.handler.ArtifactHandler; -import org.apache.maven.model.Resource; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.eclipse.BuildCommand; -import org.apache.maven.plugin.eclipse.Constants; -import org.apache.maven.plugin.eclipse.EclipseConfigFile; -import org.apache.maven.plugin.eclipse.EclipseSourceDir; -import org.apache.maven.plugin.eclipse.WorkspaceConfiguration; -import org.apache.maven.plugin.eclipse.reader.ReadWorkspaceLocations; -import org.apache.maven.plugin.eclipse.writers.EclipseManifestWriter; -import org.apache.maven.plugin.eclipse.writers.EclipseSettingsWriter; -import org.apache.maven.plugin.eclipse.writers.EclipseWriterConfig; -import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpApplicationXMLWriter; -import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponent15Writer; -import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponentWriter; -import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpFacetsWriter; -import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpmodulesWriter; -import org.apache.maven.plugin.ide.IdeDependency; -import org.apache.maven.plugin.ide.IdeUtils; -import org.apache.maven.plugin.ide.JeeUtils; -import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.resource.ResourceManager; -import org.codehaus.plexus.resource.loader.FileResourceLoader; -import org.codehaus.plexus.resource.loader.ResourceNotFoundException; -import org.codehaus.plexus.util.FileUtils; -import org.codehaus.plexus.util.IOUtil; -import org.codehaus.plexus.util.StringUtils; -import org.codehaus.plexus.util.xml.Xpp3Dom; - -/** - * Generates the following eclipse configuration files: - * <ul> - * <li><code>.project</code> and <code>.classpath</code> files</li> - * <li><code>.setting/org.eclipse.jdt.core.prefs</code> with project specific compiler settings</li> - * <li>various configuration files for WTP (Web Tools Project), if the parameter <code>wtpversion</code> is set to a - * valid version (WTP configuration is not generated by default)</li> - * </ul> - * If this goal is run on a multiproject root, dependencies between modules will be configured as direct project - * dependencies in Eclipse (unless <code>useProjectReferences</code> is set to <code>false</code>). - * - * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a> - * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a> - * @version $Id: EclipsePlugin.java 641616 2008-03-26 22:42:42Z aheritier $ - * @goal eclipse - * @execute phase="generate-resources" - */ -public class EclipsePlugin - extends AbstractIdeSupportMojo -{ - - private static final String NATURE_WST_FACET_CORE_NATURE = "org.eclipse.wst.common.project.facet.core.nature"; //$NON-NLS-1$ - - private static final String BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER = - "org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver"; //$NON-NLS-1$ - - protected static final String BUILDER_WST_VALIDATION = "org.eclipse.wst.validation.validationbuilder"; //$NON-NLS-1$ - - private static final String BUILDER_JDT_CORE_JAVA = "org.eclipse.jdt.core.javabuilder"; //$NON-NLS-1$ - - private static final String BUILDER_WST_COMPONENT_STRUCTURAL = - "org.eclipse.wst.common.modulecore.ComponentStructuralBuilder"; //$NON-NLS-1$ - - private static final String BUILDER_WST_FACET = "org.eclipse.wst.common.project.facet.core.builder"; //$NON-NLS-1$ - - private static final String BUILDER_PDE_MANIFEST = "org.eclipse.pde.ManifestBuilder"; //$NON-NLS-1$ - - private static final String BUILDER_PDE_SCHEMA = "org.eclipse.pde.SchemaBuilder"; //$NON-NLS-1$ - - private static final String NATURE_WST_MODULE_CORE_NATURE = "org.eclipse.wst.common.modulecore.ModuleCoreNature"; //$NON-NLS-1$ - - private static final String NATURE_JDT_CORE_JAVA = "org.eclipse.jdt.core.javanature"; //$NON-NLS-1$ - - private static final String NATURE_JEM_WORKBENCH_JAVA_EMF = "org.eclipse.jem.workbench.JavaEMFNature"; //$NON-NLS-1$ - - private static final String NATURE_PDE_PLUGIN = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$ - - protected static final String COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER = "org.eclipse.jdt.launching.JRE_CONTAINER"; //$NON-NLS-1$ - - protected static final String REQUIRED_PLUGINS_CONTAINER = "org.eclipse.pde.core.requiredPlugins"; //$NON-NLS-1$ - - // warning, order is important for binary search - 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$ - - /** - * Constant for 'artifactId' element in POM.xml. - */ - private static final String POM_ELT_ARTIFACT_ID = "artifactId"; //$NON-NLS-1$ - - /** - * Constant for 'groupId' element in POM.xml. - */ - private static final String POM_ELT_GROUP_ID = "groupId"; //$NON-NLS-1$ - - /** - * List of eclipse project natures. By default the <code>org.eclipse.jdt.core.javanature</code> nature plus the - * needed WTP natures are added. Natures added using this property <strong>replace</strong> the default list. - * - * <pre> - * <projectnatures> - * <projectnature>org.eclipse.jdt.core.javanature</projectnature> - * <projectnature>org.eclipse.wst.common.modulecore.ModuleCoreNature</projectnature> - * </projectnatures> - * </pre> - * - * @parameter - */ - private List projectnatures; - - /** - * List of artifact to exclude from eclipse classpath, beeing provided by some eclipse classPathContainer - * [MECLIPSE-79] - * - * @since 2.5 - * @parameter - */ - private List excludes; - - /** - * List of eclipse project natures to be added to the default ones. - * - * <pre> - * <additionalProjectnatures> - * <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature> - * </additionalProjectnatures> - * </pre> - * - * @parameter - */ - private List additionalProjectnatures; - - /** - * List of eclipse project facets to be added to the default ones. - * - * <pre> - * <additionalProjectFacets> - * <jst.jsf>1.1<jst.jsf/> - * </additionalProjectFacets> - * </pre> - * - * @parameter - */ - private Map additionalProjectFacets; - - /** - * List of eclipse build commands. By default the <code>org.eclipse.jdt.core.javabuilder</code> builder plus the - * needed WTP builders are added. If you specify any configuration for this parameter, only those buildcommands - * specified will be used; the defaults won't be added. Use the <code>additionalBuildCommands</code> parameter for - * that. Configuration example: Old style: - * - * <pre> - * <buildcommands> - * <buildcommand>org.eclipse.wst.common.modulecore.ComponentStructuralBuilder</buildcommand> - * <buildcommand>org.eclipse.jdt.core.javabuilder</buildcommand> - * <buildcommand>org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver</buildcommand> - * </buildcommands> - * </pre> - * - * For new style, see <code>additionalBuildCommands</code>. - * - * @parameter - */ - private List buildcommands; - - /** - * List of eclipse build commands to be added to the default ones. Old style: - * - * <pre> - * <additionalBuildcommands> - * <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand> - * </additionalBuildcommands> - * </pre> - * - * New style: - * - * <pre> - * <additionalBuildcommands> - * <buildCommand> - * <name>org.ui.externaltools.ExternalToolBuilder</name> - * <triggers>auto,full,incremental,</triggers> - * <arguments> - * <LaunchConfigHandle>&lt;project&gt;./externalToolBuilders/MavenBuilder.launch</LaunchConfighandle> - * </arguments> - * </buildCommand> - * </additionalBuildcommands> - * </pre> - * - * Note the difference between <code>build<strong>c</strong>ommand</code> and - * <code>build<strong>C</strong>ommand</code>. You can mix and match old and new-style configuration entries. - * - * @parameter - */ - private List additionalBuildcommands; - - /** - * List of container classpath entries. By default the <code>org.eclipse.jdt.launching.JRE_CONTAINER</code> - * classpath container is added. Configuration example: - * - * <pre> - * <classpathContainers> - * <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer> - * <classpathContainer>org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v5.5</classpathContainer> - * <classpathContainer>org.eclipse.jst.j2ee.internal.web.container/artifact</classpathContainer> - * </classpathContainers> - * </pre> - * - * @parameter - */ - private List classpathContainers; - - /** - * Enables/disables the downloading of source attachments. Defaults to false. DEPRECATED - use downloadSources - * - * @parameter expression="${eclipse.downloadSources}" - * @deprecated use downloadSources - */ - private boolean eclipseDownloadSources; - - /** - * Eclipse workspace directory. - * - * @parameter expression="${eclipse.projectDir}" alias="outputDir" - */ - private File eclipseProjectDir; - - /** - * When set to false, the plugin will not create sub-projects and instead reference those sub-projects using the - * installed package in the local repository - * - * @parameter expression="${eclipse.useProjectReferences}" default-value="true" - * @required - */ - private boolean useProjectReferences; - - /** - * The default output directory - * - * @parameter expression="${outputDirectory}" alias="outputDirectory" - * default-value="${project.build.outputDirectory}" - * @required - */ - private File buildOutputDirectory; - - /** - * The version of WTP for which configuration files will be generated. The default value is "none" (don't generate - * WTP configuration), supported versions are "R7", "1.0", and "1.5" - * - * @parameter expression="${wtpversion}" default-value="none" - */ - private String wtpversion; - - /** - * JEE context name of the WTP module. ( ex. WEB context name ). - * - * @parameter expression="${wtpContextName}" - */ - private String wtpContextName; - - /** - * The relative path of the manifest file - * - * @parameter expression="${eclipse.manifest}" default-value="${basedir}/META-INF/MANIFEST.MF" - */ - private File manifest; - - /** - * Allow to configure additional generic configuration files for eclipse that will be written out to disk when - * running eclipse:eclipse. FOr each file you can specify the name and the text content. - * - * <pre> - * <plugin> - * <groupId>org.apache.maven.plugins</groupId> - * <artifactId>maven-eclipse-plugin</artifactId> - * <configuration> - * <additionalConfig> - * <file> - * <name>.checkstyle</name> - * <content> - * <![CDATA[<fileset-config file-format-version="1.2.0" simple-config="true"> - * <fileset name="all" enabled="true" check-config-name="acme corporate style" local="false"> - * <file-match-pattern match-pattern="." include-pattern="true"/> - * </fileset> - * <filter name="NonSrcDirs" enabled="true"/> - * </fileset-config>]]> - * </content> - * </file> - * </additionalConfig> - * </configuration> - * </plugin> - * </pre> - * - * Instead of the content you can also define (from version 2.5) an url to download the file : - * - * <pre> - * <plugin> - * <groupId>org.apache.maven.plugins</groupId> - * <artifactId>maven-eclipse-plugin</artifactId> - * <configuration> - * <additionalConfig> - * <file> - * <name>.checkstyle</name> - * <url>http://some.place.org/path/to/file</url> - * </file> - * </additionalConfig> - * </configuration> - * </pre> - * - * or a location : - * - * <pre> - * <plugin> - * <groupId>org.apache.maven.plugins</groupId> - * <artifactId>maven-eclipse-plugin</artifactId> - * <configuration> - * <additionalConfig> - * <file> - * <name>.checkstyle</name> - * <location>/checkstyle-config.xml</location> - * </file> - * </additionalConfig> - * </configuration> - * <dependencies> - * <!-- The file defined in the location is stored in this dependency --> - * <dependency> - * <groupId>eclipsetest</groupId> - * <artifactId>checkstyle-config</artifactId> - * <version>1.0</version> - * </dependency> - * </dependencies> - * </plugin> - * </pre> - * - * @parameter - */ - private EclipseConfigFile[] additionalConfig; - - /** - * If set to <code>true</code>, the version number of the artifact is appended to the name of the generated - * Eclipse project. See projectNameTemplate for other options. - * - * @parameter expression="${eclipse.addVersionToProjectName}" default-value="false" - */ - private boolean addVersionToProjectName; - - /** - * If set to <code>true</code>, the groupId of the artifact is appended to the name of the generated Eclipse - * project. See projectNameTemplate for other options. - * - * @parameter expression="${eclipse.addGroupIdToProjectName}" default-value="false" - */ - private boolean addGroupIdToProjectName; - - /** - * Allows configuring the name of the eclipse projects. This property if set wins over addVersionToProjectName and - * addGroupIdToProjectName You can use <code>[groupId]</code>, <code>[artifactId]</code> and - * <code>[version]</code> variables. eg. <code>[groupId].[artifactId]-[version]</code> - * - * @parameter expression="${eclipse.projectNameTemplate}" - */ - private String projectNameTemplate; - - /** - * Parsed wtp version. - */ - private float wtpVersionFloat; - - /** - * Not a plugin parameter. Is this a java project? - */ - private boolean isJavaProject; - - /** - * Must the manifest files be written for java projects so that that the jee classpath for wtp is correct. - * - * @parameter expression="${eclipse.wtpmanifest}" default-value="false" - */ - private boolean wtpmanifest; - - /** - * Must the application files be written for ear projects in a separate directory. - * - * @parameter expression="${eclipse.wtpapplicationxml}" default-value="false" - */ - private boolean wtpapplicationxml; - - /** - * What WTP defined server to use for deployment informations. - * - * @parameter expression="${eclipse.wtpdefaultserver}" - */ - private String wtpdefaultserver; - - private WorkspaceConfiguration workspaceConfiguration; - - /** - * ResourceManager for getting additonalConfig files from resources - * - * @component - * @required - * @readonly - */ - private ResourceManager locator; - - /** - * This eclipse workspace is read and all artifacts detected there will be connected as eclipse projects and will - * not be linked to the jars in the local repository. Requirement is that it was created with the similar wtp - * settings as the reactor projects, but the project name template my differ. The pom's in the workspace projects - * may not contain variables in the artefactId, groupId and version tags. - * - * @since 2.5 - * @parameter expression="${eclipse.workspace}" - */ - protected String workspace; - - /** - * Limit the use of project references to the current workspace. No project references will be created to projects - * in the reactor when they are not available in the workspace. - * - * @parameter expression="${eclipse.limitProjectReferencesToWorkspace}" default-value="false" - */ - protected boolean limitProjectReferencesToWorkspace; - - protected boolean isJavaProject() - { - return isJavaProject; - } - - protected boolean isPdeProject() - { - return pde; - } - - /** - * Getter for <code>buildcommands</code>. - * - * @return Returns the buildcommands. - */ - public List getBuildcommands() - { - return buildcommands; - } - - /** - * Setter for <code>buildcommands</code>. - * - * @param buildcommands The buildcommands to set. - */ - public void setBuildcommands( List buildcommands ) - { - this.buildcommands = buildcommands; - } - - /** - * Getter for <code>buildOutputDirectory</code>. - * - * @return Returns the buildOutputDirectory. - */ - public File getBuildOutputDirectory() - { - return buildOutputDirectory; - } - - /** - * Setter for <code>buildOutputDirectory</code>. - * - * @param buildOutputDirectory The buildOutputDirectory to set. - */ - public void setBuildOutputDirectory( File buildOutputDirectory ) - { - this.buildOutputDirectory = buildOutputDirectory; - } - - /** - * Getter for <code>classpathContainers</code>. - * - * @return Returns the classpathContainers. - */ - public List getClasspathContainers() - { - return classpathContainers; - } - - /** - * Setter for <code>classpathContainers</code>. - * - * @param classpathContainers The classpathContainers to set. - */ - public void setClasspathContainers( List classpathContainers ) - { - this.classpathContainers = classpathContainers; - } - - /** - * Getter for <code>eclipseProjectDir</code>. - * - * @return Returns the eclipseProjectDir. - */ - public File getEclipseProjectDir() - { - return eclipseProjectDir; - } - - /** - * Setter for <code>eclipseProjectDir</code>. - * - * @param eclipseProjectDir The eclipseProjectDir to set. - */ - public void setEclipseProjectDir( File eclipseProjectDir ) - { - this.eclipseProjectDir = eclipseProjectDir; - } - - /** - * Getter for <code>projectnatures</code>. - * - * @return Returns the projectnatures. - */ - public List getProjectnatures() - { - return projectnatures; - } - - /** - * Setter for <code>projectnatures</code>. - * - * @param projectnatures The projectnatures to set. - */ - public void setProjectnatures( List projectnatures ) - { - this.projectnatures = projectnatures; - } - - /** - * Getter for <code>useProjectReferences</code>. - * - * @return Returns the useProjectReferences. - */ - public boolean getUseProjectReferences() - { - return useProjectReferences; - } - - /** - * Setter for <code>useProjectReferences</code>. - * - * @param useProjectReferences The useProjectReferences to set. - */ - public void setUseProjectReferences( boolean useProjectReferences ) - { - this.useProjectReferences = useProjectReferences; - } - - /** - * Getter for <code>wtpversion</code>. - * - * @return Returns the wtpversion. - */ - public String getWtpversion() - { - return wtpversion; - } - - /** - * Setter for <code>wtpversion</code>. - * - * @param wtpversion The wtpversion to set. - */ - public void setWtpversion( String wtpversion ) - { - this.wtpversion = wtpversion; - } - - /** - * Getter for <code>additionalBuildcommands</code>. - * - * @return Returns the additionalBuildcommands. - */ - public List getAdditionalBuildcommands() - { - return additionalBuildcommands; - } - - /** - * Setter for <code>additionalBuildcommands</code>. - * - * @param additionalBuildcommands The additionalBuildcommands to set. - */ - public void setAdditionalBuildcommands( List additionalBuildcommands ) - { - this.additionalBuildcommands = additionalBuildcommands; - } - - /** - * Getter for <code>additionalProjectnatures</code>. - * - * @return Returns the additionalProjectnatures. - */ - public List getAdditionalProjectnatures() - { - return additionalProjectnatures; - } - - /** - * Setter for <code>additionalProjectnatures</code>. - * - * @param additionalProjectnatures The additionalProjectnatures to set. - */ - public void setAdditionalProjectnatures( List additionalProjectnatures ) - { - this.additionalProjectnatures = additionalProjectnatures; - } - - /** - * Getter for <code>addVersionToProjectName</code>. - */ - public boolean isAddVersionToProjectName() - { - return addVersionToProjectName; - } - - /** - * Setter for <code>addVersionToProjectName</code>. - */ - public void setAddVersionToProjectName( boolean addVersionToProjectName ) - { - this.addVersionToProjectName = addVersionToProjectName; - } - - /** - * Getter for <code>addGroupIdToProjectName</code>. - */ - public boolean isAddGroupIdToProjectName() - { - return addGroupIdToProjectName; - } - - /** - * Setter for <code>addGroupIdToProjectName</code>. - */ - public void setAddGroupIdToProjectName( boolean addGroupIdToProjectName ) - { - this.addGroupIdToProjectName = addGroupIdToProjectName; - } - - public String getProjectNameTemplate() - { - return projectNameTemplate; - } - - public void setProjectNameTemplate( String projectNameTemplate ) - { - this.projectNameTemplate = projectNameTemplate; - } - - /** - * @see org.apache.maven.plugin.Mojo#execute() - */ - public boolean setup() - throws MojoExecutionException - { - boolean ready = true; - - checkDeprecations(); - - ready = validate(); - - // TODO: Why are we using project in some places, and executedProject in others?? - ArtifactHandler artifactHandler = project.getArtifact().getArtifactHandler(); - - // ear projects don't contain java sources - // pde projects are always java projects - isJavaProject = - pde || - ( Constants.LANGUAGE_JAVA.equals( artifactHandler.getLanguage() ) && !Constants.PROJECT_PACKAGING_EAR.equals( packaging ) ); - - setupExtras(); - - parseConfigurationOptions(); - - // defaults - if ( projectnatures == null ) - { - fillDefaultNatures( packaging ); - } - - if ( additionalProjectnatures != null ) - { - projectnatures.addAll( additionalProjectnatures ); - } - - if ( buildcommands == null ) - { - fillDefaultBuilders( packaging ); - } - else - { - convertBuildCommandList( buildcommands ); - } - - if ( additionalBuildcommands != null ) - { - convertBuildCommandList( additionalBuildcommands ); - buildcommands.addAll( additionalBuildcommands ); - } - - if ( classpathContainers == null ) - { - fillDefaultClasspathContainers( packaging ); - } - else - { - verifyClasspathContainerListIsComplete(); - } - locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() ); - locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) ); - - // ready to start - return ready; - } - - protected void convertBuildCommandList( List commands ) - { - if ( commands != null ) - { - for ( ListIterator i = commands.listIterator(); i.hasNext(); ) - { - Object command = i.next(); - - if ( command instanceof String ) - { - command = new BuildCommand( (String) command ); - i.set( command ); - } - } - } - } - - private void parseConfigurationOptions() - { - if ( "R7".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$ - { - wtpVersionFloat = 0.7f; - } - else if ( "1.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$ - { - wtpVersionFloat = 1.0f; - } - else if ( "1.5".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$ - { - wtpVersionFloat = 1.5f; - } - else if ( "2.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$ - { - wtpVersionFloat = 2.0f; - } - if ( !"none".equalsIgnoreCase( wtpversion ) ) - { - getLog().info( Messages.getString( "EclipsePlugin.wtpversion", wtpversion ) ); - } - } - - protected void setupExtras() - throws MojoExecutionException - { - // extension point. - } - - protected void verifyClasspathContainerListIsComplete() - { - boolean containsJREContainer = false; - // Check if classpathContainer contains a JRE (default, alternate or - // Execution Environment) - for ( Iterator iter = classpathContainers.iterator(); iter.hasNext(); ) - { - Object classPathContainer = iter.next(); - if ( classPathContainer != null && - classPathContainer.toString().startsWith( COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ) ) - { - containsJREContainer = true; - break; - } - } - if ( !containsJREContainer ) - { - getLog().warn( Messages.getString( "EclipsePlugin.missingjrecontainer" ) ); //$NON-NLS-1$ - classpathContainers.add( 0, COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ); - } - } - - private boolean validate() - throws MojoExecutionException - { - // validate sanity of the current m2 project - if ( Arrays.binarySearch( WTP_SUPPORTED_VERSIONS, wtpversion ) < 0 ) - { - throw new MojoExecutionException( - Messages.getString( "EclipsePlugin.unsupportedwtp", new Object[] { //$NON-NLS-1$ - wtpversion, - StringUtils.join( WTP_SUPPORTED_VERSIONS, " " ) } ) ); //$NON-NLS-1$ - } - - assertNotEmpty( executedProject.getGroupId(), POM_ELT_GROUP_ID ); - assertNotEmpty( executedProject.getArtifactId(), POM_ELT_ARTIFACT_ID ); - - if ( executedProject.getFile() == null || !executedProject.getFile().exists() ) - { - throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingpom" ) ); //$NON-NLS-1$ - } - - if ( "pom".equals( packaging ) && eclipseProjectDir == null ) //$NON-NLS-1$ - { - getLog().info( Messages.getString( "EclipsePlugin.pompackaging" ) ); //$NON-NLS-1$ - return false; - } - - if ( "eclipse-plugin".equals( packaging ) ) - { - pde = true; - } - - // [rfeng] Set PDE to false if the project is not a bundle - if(!isOSGiBundle()) { - pde = false; - } - - if ( eclipseProjectDir == null ) - { - eclipseProjectDir = executedProject.getFile().getParentFile(); - } - - if ( !eclipseProjectDir.exists() && !eclipseProjectDir.mkdirs() ) - { - throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) ); //$NON-NLS-1$ - } - - if ( !eclipseProjectDir.equals( executedProject.getFile().getParentFile() ) ) - { - if ( !eclipseProjectDir.isDirectory() ) - { - throw new MojoExecutionException( Messages.getString( "EclipsePlugin.notadir", eclipseProjectDir ) ); //$NON-NLS-1$ - } - eclipseProjectDir = new File( eclipseProjectDir, executedProject.getArtifactId() ); - if ( !eclipseProjectDir.isDirectory() && !eclipseProjectDir.mkdirs() ) - { - throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) ); //$NON-NLS-1$ - } - } - - validateExtras(); - - return true; - } - - protected void validateExtras() - { - // provided for extension. - } - - private void checkDeprecations() - { - if ( eclipseDownloadSources ) - { - // deprecated warning - getLog().warn( Messages.getString( "EclipsePlugin.deprecatedpar", new Object[] { //$NON-NLS-1$ - "eclipse.downloadSources", //$NON-NLS-1$ - "downloadSources" } ) ); //$NON-NLS-1$ - downloadSources = true; - } - - checkExtraDeprecations(); - } - - protected void checkExtraDeprecations() - { - // provided for extension. - } - - public void writeConfiguration( IdeDependency[] deps ) - throws MojoExecutionException - { - EclipseWriterConfig config = createEclipseWriterConfig( deps ); - - if ( wtpmanifest && isJavaProject() ) - { - EclipseManifestWriter.addManifestResource( getLog(), config ); - } - // NOTE: This could change the config! - writeExtraConfiguration( config ); - - if ( wtpVersionFloat == 0.7f ) - { - new EclipseWtpmodulesWriter().init( getLog(), config ).write(); - } - - if ( wtpVersionFloat >= 1.0f ) - { - new EclipseWtpFacetsWriter().init( getLog(), config ).write(); - } - if ( wtpVersionFloat == 1.0f ) - { - new EclipseWtpComponentWriter().init( getLog(), config ).write(); - } - if ( wtpVersionFloat >= 1.5 ) - { - new EclipseWtpComponent15Writer().init( getLog(), config ).write(); - } - - new EclipseSettingsWriter().init( getLog(), config ).write(); - - if ( isJavaProject ) - { - new EclipseClasspathWriter().init( getLog(), config ).write(); - } - - if ( wtpapplicationxml ) - { - new EclipseWtpApplicationXMLWriter().init( getLog(), config ).write(); - } - - // [rfeng] - /* - if ( pde ) - { - this.getLog().info( "The Maven Eclipse plugin runs in 'pde'-mode." ); - new EclipseOSGiManifestWriter().init( getLog(), config ).write(); - } - */ - // [rfeng] - - // NOTE: This one MUST be after EclipseClasspathwriter, and possibly others, - // since currently EclipseClasspathWriter does some magic to detect nested - // output folders and modifies the configuration by adding new (Ant) builders. - // So the .project file must be written AFTER those have run! - new EclipseProjectWriter().init( getLog(), config ).write(); - - writeAdditionalConfig(); - - getLog().info( Messages.getString( "EclipsePlugin.wrote", new Object[] { //$NON-NLS-1$ - config.getEclipseProjectName(), eclipseProjectDir.getAbsolutePath() } ) ); - } - - protected void writeAdditionalConfig() - throws MojoExecutionException - { - if ( additionalConfig != null ) - { - for ( int j = 0; j < additionalConfig.length; j++ ) - { - EclipseConfigFile file = additionalConfig[j]; - File projectRelativeFile = new File( eclipseProjectDir, file.getName() ); - if ( projectRelativeFile.isDirectory() ) - { - // just ignore? - getLog().warn( Messages.getString( "EclipsePlugin.foundadir", //$NON-NLS-1$ - projectRelativeFile.getAbsolutePath() ) ); - } - - try - { - projectRelativeFile.getParentFile().mkdirs(); - if ( file.getContent() == null ) - { - InputStream inStream; - if ( file.getLocation() != null ) - { - inStream = locator.getResourceAsInputStream( file.getLocation() ); - } - else - { - inStream = file.getURL().openConnection().getInputStream(); - } - OutputStream outStream = new FileOutputStream( projectRelativeFile ); - try - { - IOUtil.copy( inStream, outStream ); - } - finally - { - inStream.close(); - outStream.close(); - } - } - else - { - FileUtils.fileWrite( projectRelativeFile.getAbsolutePath(), file.getContent() ); - } - } - catch ( IOException e ) - { - throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantwritetofile", //$NON-NLS-1$ - projectRelativeFile.getAbsolutePath() ) ); - } - catch ( ResourceNotFoundException e ) - { - throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantfindresource", //$NON-NLS-1$ - file.getLocation() ) ); - } - - } - } - } - - protected EclipseWriterConfig createEclipseWriterConfig( IdeDependency[] deps ) - throws MojoExecutionException - { - File projectBaseDir = executedProject.getFile().getParentFile(); - - // build a list of UNIQUE source dirs (both src and resources) to be - // used in classpath and wtpmodules - EclipseSourceDir[] sourceDirs = buildDirectoryList( executedProject, eclipseProjectDir, buildOutputDirectory ); - - EclipseWriterConfig config = new EclipseWriterConfig(); - - config.setWorkspaceConfiguration( getWorkspaceConfiguration() ); - - config.setProjectNameTemplate( calculateProjectNameTemplate() ); - - String projectName = IdeUtils.getProjectName( config.getProjectNameTemplate(), project ); - - config.setEclipseProjectName( projectName ); - - config.setWtpapplicationxml( wtpapplicationxml ); - - config.setWtpVersion( wtpVersionFloat ); - - Set convertedBuildCommands = new LinkedHashSet(); - - if ( buildcommands != null ) - { - for ( Iterator it = buildcommands.iterator(); it.hasNext(); ) - { - Object cmd = it.next(); - - if ( cmd instanceof BuildCommand ) - { - convertedBuildCommands.add( cmd ); - } - else - { - convertedBuildCommands.add( new BuildCommand( (String) cmd ) ); - } - } - } - - config.setBuildCommands( new LinkedList( convertedBuildCommands ) ); - - config.setBuildOutputDirectory( buildOutputDirectory ); - config.setClasspathContainers( classpathContainers ); - config.setDeps( deps ); - config.setEclipseProjectDirectory( eclipseProjectDir ); - config.setLocalRepository( localRepository ); - config.setOSGIManifestFile( manifest ); - config.setPde( pde ); - config.setProject( project ); - config.setProjectBaseDir( projectBaseDir ); - config.setProjectnatures( projectnatures ); - config.setProjectFacets( additionalProjectFacets ); - config.setSourceDirs( sourceDirs ); - config.setAddVersionToProjectName( isAddVersionToProjectName() ); - config.setPackaging( packaging ); - - collectWarContextRootsFromReactorEarConfiguration( config ); - - return config; - } - - /** - * If this is a war module peek into the reactor an search for an ear module that defines the context root of this - * module. - * - * @param config config to save the context root. - */ - private void collectWarContextRootsFromReactorEarConfiguration( EclipseWriterConfig config ) - { - if ( reactorProjects != null && wtpContextName == null && - Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) ) - { - for ( Iterator iter = reactorProjects.iterator(); iter.hasNext(); ) - { - MavenProject reactorProject = (MavenProject) iter.next(); - - if ( Constants.PROJECT_PACKAGING_EAR.equals( reactorProject.getPackaging() ) ) - { - Xpp3Dom[] warDefinitions = - IdeUtils.getPluginConfigurationDom( reactorProject, JeeUtils.ARTIFACT_MAVEN_EAR_PLUGIN, - new String[] { "modules", "webModule" } ); - for ( int index = 0; index < warDefinitions.length; index++ ) - { - Xpp3Dom groupId = warDefinitions[index].getChild( "groupId" ); - Xpp3Dom artifactId = warDefinitions[index].getChild( "artifactId" ); - Xpp3Dom contextRoot = warDefinitions[index].getChild( "contextRoot" ); - if ( groupId != null && artifactId != null && contextRoot != null && - groupId.getValue() != null && artifactId.getValue() != null && - contextRoot.getValue() != null ) - { - getLog().info( - "Found context root definition for " + groupId.getValue() + ":" + - artifactId.getValue() + " " + contextRoot.getValue() ); - if ( project.getArtifactId().equals( artifactId.getValue() ) && - project.getGroupId().equals( groupId.getValue() ) ) - { - config.setContextName( contextRoot.getValue() ); - } - } - else - { - getLog().info( - "Found incomplete ear configuration in " + reactorProject.getGroupId() + - ":" + reactorProject.getGroupId() + " found " + - warDefinitions[index].toString() ); - } - } - } - } - } - if ( config.getContextName() == null && Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) ) - { - if ( wtpContextName == null ) - { - config.setContextName( project.getArtifactId() ); - } - else - { - config.setContextName( wtpContextName ); - } - } - } - - /** - * Write any extra configuration information for the Eclipse project. This is an extension point, called before the - * main configurations are written. <br/> <b> NOTE: This could change the config! </b> - * - * @param config - * @throws MojoExecutionException - */ - protected void writeExtraConfiguration( EclipseWriterConfig config ) - throws MojoExecutionException - { - // extension point. - } - - private void assertNotEmpty( String string, String elementName ) - throws MojoExecutionException - { - if ( string == null ) - { - throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingelement", elementName ) ); //$NON-NLS-1$ - } - } - - protected void fillDefaultNatures( String packaging ) - { - projectnatures = new ArrayList(); - - if ( wtpVersionFloat >= 1.0f ) - { - projectnatures.add( NATURE_WST_FACET_CORE_NATURE ); // WTP 1.0 nature - } - - if ( isJavaProject ) - { - projectnatures.add( NATURE_JDT_CORE_JAVA ); - } - - if ( wtpVersionFloat >= 0.7f ) - { - projectnatures.add( NATURE_WST_MODULE_CORE_NATURE ); // WTP 0.7/1.0 nature - - if ( isJavaProject ) - { - projectnatures.add( NATURE_JEM_WORKBENCH_JAVA_EMF ); // WTP 0.7/1.0 nature - } - } - - if ( pde ) - { - projectnatures.add( NATURE_PDE_PLUGIN ); - } - - } - - protected void fillDefaultClasspathContainers( String packaging ) - { - classpathContainers = new ArrayList(); - - if ( getWorkspaceConfiguration().getDefaultClasspathContainer() != null ) - { - getLog().info( - "Adding default classpath contaigner: " + - getWorkspaceConfiguration().getDefaultClasspathContainer() ); - classpathContainers.add( getWorkspaceConfiguration().getDefaultClasspathContainer() ); - } - if ( pde ) - { - classpathContainers.add( REQUIRED_PLUGINS_CONTAINER ); - } - } - - protected void fillDefaultBuilders( String packaging ) - { - buildcommands = new ArrayList(); - - if ( wtpVersionFloat == 0.7f ) - { - buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL ) ); // WTP 0.7 builder - } - - if ( isJavaProject ) - { - buildcommands.add( new BuildCommand( BUILDER_JDT_CORE_JAVA ) ); - } - - if ( wtpVersionFloat >= 1.5f ) - { - buildcommands.add( new BuildCommand( BUILDER_WST_FACET ) ); // WTP 1.5 builder - } - - if ( wtpVersionFloat >= 0.7f ) - { - buildcommands.add( new BuildCommand( BUILDER_WST_VALIDATION ) ); // WTP 0.7/1.0 builder - } - - if ( wtpVersionFloat == 0.7f ) - { - // WTP 0.7 builder - buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER ) ); - } - - if ( pde ) - { - buildcommands.add( new BuildCommand( BUILDER_PDE_MANIFEST ) ); - buildcommands.add( new BuildCommand( BUILDER_PDE_SCHEMA ) ); - } - } - - public EclipseSourceDir[] buildDirectoryList( MavenProject project, File basedir, File buildOutputDirectory ) - throws MojoExecutionException - { - File projectBaseDir = project.getFile().getParentFile(); - - // avoid duplicated entries - Set directories = new TreeSet(); - - extractSourceDirs( directories, project.getCompileSourceRoots(), basedir, projectBaseDir, false, null ); - - String relativeOutput = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, buildOutputDirectory, false ); - - extractResourceDirs( directories, project.getBuild().getResources(), project, basedir, projectBaseDir, false, - relativeOutput ); - - // If using the standard output location, don't mix the test output into it. - String testOutput = null; - boolean useStandardOutputDir = - buildOutputDirectory.equals( new File( project.getBuild().getOutputDirectory() ) ); - if ( useStandardOutputDir ) - { - getLog().debug( - "testOutput toRelativeAndFixSeparator " + projectBaseDir + " , " + - project.getBuild().getTestOutputDirectory() ); - testOutput = - IdeUtils.toRelativeAndFixSeparator( projectBaseDir, - new File( project.getBuild().getTestOutputDirectory() ), false ); - getLog().debug( "testOutput after toRelative : " + testOutput ); - } - - extractSourceDirs( directories, project.getTestCompileSourceRoots(), basedir, projectBaseDir, true, testOutput ); - - extractResourceDirs( directories, project.getBuild().getTestResources(), project, basedir, projectBaseDir, - true, testOutput ); - - return (EclipseSourceDir[]) directories.toArray( new EclipseSourceDir[directories.size()] ); - } - - private void extractSourceDirs( Set directories, List sourceRoots, File basedir, File projectBaseDir, boolean test, - String output ) - throws MojoExecutionException - { - for ( Iterator it = sourceRoots.iterator(); it.hasNext(); ) - { - - File sourceRootFile = new File( (String) it.next() ); - getLog().debug( "Processing source dir: " + sourceRootFile ); - - if ( sourceRootFile.isDirectory() ) - { - String sourceRoot = - IdeUtils.toRelativeAndFixSeparator( projectBaseDir, sourceRootFile, - !projectBaseDir.equals( basedir ) ); - - directories.add( new EclipseSourceDir( sourceRoot, output, false, test, null, null, false ) ); - } - } - } - - void extractResourceDirs( Set directories, List resources, MavenProject project, File basedir, - File workspaceProjectBaseDir, boolean test, final String output ) - throws MojoExecutionException - { - for ( Iterator it = resources.iterator(); it.hasNext(); ) - { - Resource resource = (Resource) it.next(); - - getLog().debug( "Processing resource dir: " + resource.getDirectory() ); - - String includePattern = null; - String excludePattern = null; - - if ( resource.getIncludes().size() != 0 ) - { - includePattern = StringUtils.join( resource.getIncludes().iterator(), "|" ); - } - - if ( resource.getExcludes().size() != 0 ) - { - excludePattern = StringUtils.join( resource.getExcludes().iterator(), "|" ); - } - - // TODO: figure out how to merge if the same dir is specified twice - // with different in/exclude patterns. - - File resourceDirectory = new File( /* basedir, */resource.getDirectory() ); - - if ( !resourceDirectory.exists() || !resourceDirectory.isDirectory() ) - { - getLog().debug( "Resource dir: " + resourceDirectory + " either missing or not a directory." ); - continue; - } - - String resourceDir = - IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, resourceDirectory, - !workspaceProjectBaseDir.equals( basedir ) ); - String thisOutput = output; - if ( thisOutput != null ) - { - // sometimes thisOutput is already an absolute path - File outputFile = new File( thisOutput ); - if ( !outputFile.isAbsolute() ) - { - outputFile = new File( workspaceProjectBaseDir, thisOutput ); - } - // create output dir if it doesn't exist - outputFile.mkdirs(); - - if ( !StringUtils.isEmpty( resource.getTargetPath() ) ) - { - outputFile = new File( outputFile, resource.getTargetPath() ); - // create output dir if it doesn't exist - outputFile.mkdirs(); - } - - getLog().debug( - "Making relative and fixing separator: { " + workspaceProjectBaseDir + ", " + - outputFile + ", false }." ); - thisOutput = IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, outputFile, false ); - } - - getLog().debug( - "Adding eclipse source dir: { " + resourceDir + ", " + thisOutput + ", true, " + test + - ", " + includePattern + ", " + excludePattern + " }." ); - - directories.add( new EclipseSourceDir( resourceDir, thisOutput, true, test, includePattern, excludePattern, - resource.isFiltering() ) ); - } - } - - /** - * Calculate the project name template from the fields {@link #projectNameTemplate}, - * {@link #addVersionToProjectName} and {@link #addGroupIdToProjectName} - * - * @return the project name template that should be used after considering the plugin configuration - */ - private String calculateProjectNameTemplate() - { - if ( getProjectNameTemplate() != null ) - { - if ( isAddVersionToProjectName() || isAddGroupIdToProjectName() ) - { - getLog().warn( - "projectNameTemplate definition overrides " - + "addVersionToProjectName or addGroupIdToProjectName" ); - } - return getProjectNameTemplate(); - } - else if ( isAddVersionToProjectName() && isAddGroupIdToProjectName() ) - { - return IdeUtils.PROJECT_NAME_WITH_GROUP_AND_VERSION_TEMPLATE; - } - else if ( isAddVersionToProjectName() ) - { - return IdeUtils.PROJECT_NAME_WITH_VERSION_TEMPLATE; - } - else if ( isAddGroupIdToProjectName() ) - { - return IdeUtils.PROJECT_NAME_WITH_GROUP_TEMPLATE; - } - return IdeUtils.PROJECT_NAME_DEFAULT_TEMPLATE; - } - - /** - * {@inheritDoc} - */ - public String getProjectNameForArifact( Artifact artifact ) - { - IdeDependency[] workspaceArtefacts = getWorkspaceArtefacts(); - for ( int index = 0; workspaceArtefacts != null && index < workspaceArtefacts.length; index++ ) - { - IdeDependency workspaceArtefact = workspaceArtefacts[index]; - if ( workspaceArtefact.isAddedToClasspath() && - workspaceArtefact.getGroupId().equals( artifact.getGroupId() ) && - workspaceArtefact.getArtifactId().equals( artifact.getArtifactId() ) ) - { - if ( workspaceArtefact.getVersion().equals( artifact.getVersion() ) ) - { - return workspaceArtefact.getEclipseProjectName(); - } - } - } - return IdeUtils.getProjectName( calculateProjectNameTemplate(), artifact ); - } - - /** - * {@inheritDoc} - */ - protected IdeDependency[] getWorkspaceArtefacts() - { - return getWorkspaceConfiguration().getWorkspaceArtefacts(); - } - - public WorkspaceConfiguration getWorkspaceConfiguration() - { - if ( workspaceConfiguration == null ) - { - workspaceConfiguration = new WorkspaceConfiguration(); - if ( workspace != null ) - { - workspaceConfiguration.setWorkspaceDirectory( new File( workspace ) ); - } - new ReadWorkspaceLocations().init( getLog(), workspaceConfiguration, project, wtpdefaultserver ); - } - return workspaceConfiguration; - } - - public List getExcludes() - { - return excludes; - } - - /** - * Utility method that locates a project in the workspace for the given artifact. - * - * @param artifact the artifact a project should produce. - * @return <code>true</code> if the artifact is produced by a reactor projectart. - */ - private boolean isAvailableAsAWorkspaceProject( Artifact artifact ) - { - IdeDependency[] workspaceArtefacts = getWorkspaceArtefacts(); - for ( int index = 0; workspaceArtefacts != null && index < workspaceArtefacts.length; index++ ) - { - IdeDependency workspaceArtefact = workspaceArtefacts[index]; - if ( workspaceArtefact.getGroupId().equals( artifact.getGroupId() ) && - workspaceArtefact.getArtifactId().equals( artifact.getArtifactId() ) ) - { - if ( workspaceArtefact.getVersion().equals( artifact.getVersion() ) ) - { - workspaceArtefact.setAddedToClasspath( true ); - getLog().debug( "Using workspace project: " + workspaceArtefact.getEclipseProjectName() ); - return true; - } - else - { - getLog().info( - "Artifact " + - artifact.getId() + - " already available as a workspace project, but with different version. Expected: " + - artifact.getVersion() + ", found: " + workspaceArtefact.getVersion() ); - } - } - } - return false; - } - - /* - * (non-Javadoc) - * - * @see org.apache.maven.plugin.ide.AbstractIdeSupportMojo#doDependencyResolution() - */ - protected IdeDependency[] doDependencyResolution() - throws MojoExecutionException - { - - return super.doDependencyResolution(); - } - - /** - * Checks if jar has to be resolved for the given artifact - * - * @param art the artifact to check - * @return true if resolution should happen - */ - protected boolean hasToResolveJar( Artifact art ) - { - return !( getUseProjectReferences() && isAvailableAsAReactorProject( art ) ) || - ( limitProjectReferencesToWorkspace && !( getUseProjectReferences() && isAvailableAsAWorkspaceProject( art ) ) ); - } - - /** - * Checks if a projects reference has to be used for the given artifact - * - * @param art the artifact to check - * @return true if a project reference has to be used. - */ - protected boolean useProjectReference( Artifact art ) - { - boolean isReactorProject = getUseProjectReferences() && isAvailableAsAReactorProject( art ); - boolean isWorkspaceProject = getUseProjectReferences() && isAvailableAsAWorkspaceProject( art ); - return ( isReactorProject && !limitProjectReferencesToWorkspace ) || // default - ( limitProjectReferencesToWorkspace && isWorkspaceProject ) || // limitProjectReferencesToWorkspace - ( !isReactorProject && isWorkspaceProject ); // default + workspace projects - } -} |