You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sn...@apache.org on 2006/08/06 12:43:47 UTC

svn commit: r429122 - in /maven/plugins/trunk/maven-ear-plugin/src: main/java/org/apache/maven/plugin/ear/ site/apt/ site/apt/examples/

Author: snicoll
Date: Sun Aug  6 03:43:45 2006
New Revision: 429122

URL: http://svn.apache.org/viewvc?rev=429122&view=rev
Log:
MEAR-31: Added JBoss support (jboss-app.xml is now generated automatically).

Added:
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractXmlWriter.java   (with props)
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarExecutionContext.java   (with props)
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossAppXmlWriter.java   (with props)
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossConfiguration.java   (with props)
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossEarModule.java   (with props)
    maven/plugins/trunk/maven-ear-plugin/src/site/apt/examples/generating-jboss-app.apt   (with props)
Modified:
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarModule.java
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarMojo.java
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/ApplicationXmlWriter.java
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarModule.java
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/GenerateApplicationXmlMojo.java
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/HarModule.java
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JavaModule.java
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/SarModule.java
    maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/WebModule.java
    maven/plugins/trunk/maven-ear-plugin/src/site/apt/index.apt
    maven/plugins/trunk/maven-ear-plugin/src/site/apt/usage.apt

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarModule.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarModule.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarModule.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarModule.java Sun Aug  6 03:43:45 2006
@@ -71,7 +71,7 @@
         this.bundleDir = null;
     }
 
-    public void resolveArtifact( Set artifacts, String defaultJavaBundleDir )
+    public void resolveArtifact( Set artifacts )
         throws EarPluginException, MojoFailureException
     {
         if ( artifact == null )

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarMojo.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarMojo.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractEarMojo.java Sun Aug  6 03:43:45 2006
@@ -45,6 +45,22 @@
 
     public static final String META_INF = "META-INF";
 
+    public static final String UTF_8 = "UTF-8";
+
+    /**
+     * Character encoding for the auto-generated deployment file(s).
+     *
+     * @parameter
+     */
+    protected String encoding = UTF_8;
+
+    /**
+     * Directory where the deployment descriptor file(s) will be auto-generated.
+     *
+     * @parameter expression="${project.build.directory}"
+     */
+    protected String generatedDescriptorLocation;
+
     /**
      * The maven project.
      *
@@ -83,17 +99,27 @@
      */
     private File workDirectory;
 
+    /**
+     * The JBoss specific configuration.
+     *
+     * @parameter
+     */
+    private PlexusConfiguration jboss;
+
+
     private List earModules;
 
     private List allModules;
 
+    private JbossConfiguration jbossConfiguration;
+
     public void execute()
         throws MojoExecutionException, MojoFailureException
     {
-        getLog().debug( "Resolving artifact type mappings ...");
+        getLog().debug( "Resolving artifact type mappings ..." );
         try
         {
-            ArtifactTypeMappingService.getInstance().configure( artifactTypeMappings);
+            ArtifactTypeMappingService.getInstance().configure( artifactTypeMappings );
         }
         catch ( EarPluginException e )
         {
@@ -104,6 +130,19 @@
             throw new MojoExecutionException( "Invalid artifact type mappings configuration", e );
         }
 
+        getLog().debug( "Initializing JBoss configuration if necessary ..." );
+        try
+        {
+            initializeJbossConfiguration();
+        }
+        catch ( EarPluginException e )
+        {
+            throw new MojoExecutionException( "Failed to initialize JBoss configuration", e );
+        }
+
+        getLog().debug( "Initializing ear execution context" );
+        EarExecutionContext.getInstance().initialize( defaultJavaBundleDir, jbossConfiguration );
+
         getLog().debug( "Resolving ear modules ..." );
         allModules = new ArrayList();
         try
@@ -117,7 +156,7 @@
                 {
                     module = modules[i];
                     getLog().debug( "Resolving ear module[" + module + "]" );
-                    module.resolveArtifact( project.getArtifacts(), defaultJavaBundleDir );
+                    module.resolveArtifact( project.getArtifacts() );
                     allModules.add( module );
                 }
             }
@@ -187,6 +226,11 @@
         return workDirectory;
     }
 
+    protected JbossConfiguration getJbossConfiguration()
+    {
+        return jbossConfiguration;
+    }
+
     private static boolean isArtifactRegistered( Artifact a, List currentList )
     {
         Iterator i = currentList.iterator();
@@ -199,5 +243,42 @@
             }
         }
         return false;
+    }
+
+    /**
+     * Initializes the JBoss configuration.
+     *
+     * @throws EarPluginException if the configuration is invalid
+     */
+    private void initializeJbossConfiguration()
+        throws EarPluginException
+    {
+        if ( jboss == null )
+        {
+            jbossConfiguration = null;
+        }
+        else
+        {
+            try
+            {
+                String version = jboss.getChild( JbossConfiguration.VERSION ).getValue();
+                if ( version == null )
+                {
+                    getLog().info( "JBoss version not set, using JBoss 4 by default" );
+                    version = JbossConfiguration.VERSION_4;
+                }
+                final String securityDomain = jboss.getChild( JbossConfiguration.SECURITY_DOMAIN ).getValue();
+                final String unauthenticatedPrincipal =
+                    jboss.getChild( JbossConfiguration.UNAUHTHENTICTED_PRINCIPAL ).getValue();
+                final String jmxName = jboss.getChild( JbossConfiguration.JMX_NAME ).getValue();
+
+                jbossConfiguration =
+                    new JbossConfiguration( version, securityDomain, unauthenticatedPrincipal, jmxName );
+            }
+            catch ( PlexusConfigurationException e )
+            {
+                throw new EarPluginException( "Invalid JBoss configuration", e );
+            }
+        }
     }
 }

Added: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractXmlWriter.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractXmlWriter.java?rev=429122&view=auto
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractXmlWriter.java (added)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractXmlWriter.java Sun Aug  6 03:43:45 2006
@@ -0,0 +1,84 @@
+package org.apache.maven.plugin.ear;
+
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+
+/**
+ * A base class for deployment descriptor file generators.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id$
+ */
+abstract class AbstractXmlWriter
+{
+
+    private final String encoding;
+
+    AbstractXmlWriter( String encoding )
+    {
+        this.encoding = encoding;
+    }
+
+    protected Writer initializeWriter( final File destinationFile )
+        throws EarPluginException
+    {
+        try
+        {
+            return new FileWriter( destinationFile );
+        }
+        catch ( IOException ex )
+        {
+            throw new EarPluginException( "Exception while opening file[" + destinationFile.getAbsolutePath() + "]",
+                                          ex );
+        }
+    }
+
+    protected XMLWriter initializeXmlWriter( final Writer writer, final String docType )
+    {
+        return new PrettyPrintXMLWriter( writer, encoding, docType );
+    }
+
+    protected void close( Writer closeable )
+    {
+        if ( closeable == null )
+        {
+            return;
+        }
+
+        try
+        {
+            closeable.close();
+        }
+        catch ( Exception e )
+        {
+            // TODO: warn
+        }
+    }
+
+    public String getEncoding()
+    {
+        return encoding;
+    }
+}

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractXmlWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/AbstractXmlWriter.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/ApplicationXmlWriter.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/ApplicationXmlWriter.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/ApplicationXmlWriter.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/ApplicationXmlWriter.java Sun Aug  6 03:43:45 2006
@@ -1,11 +1,8 @@
 package org.apache.maven.plugin.ear;
 
-import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
 import org.codehaus.plexus.util.xml.XMLWriter;
 
 import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
 import java.io.Writer;
 import java.util.Iterator;
 import java.util.List;
@@ -33,7 +30,8 @@
  * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
  * @version $Id$
  */
-public final class ApplicationXmlWriter
+final class ApplicationXmlWriter
+    extends AbstractXmlWriter
 {
     public static final String DOCTYPE_1_3 = "application PUBLIC\n" +
         "\t\"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN\"\n" +
@@ -44,28 +42,17 @@
 
     private final String version;
 
-    private final String encoding;
-
-    public ApplicationXmlWriter( String version, String encoding )
+    ApplicationXmlWriter( String version, String encoding )
     {
+        super( encoding );
         this.version = version;
-        this.encoding = encoding;
     }
 
     public void write( File destinationFile, List earModules, List securityRoles, String displayName,
                        String description )
         throws EarPluginException
     {
-        FileWriter w;
-        try
-        {
-            w = new FileWriter( destinationFile );
-        }
-        catch ( IOException ex )
-        {
-            throw new EarPluginException( "Exception while opening file[" + destinationFile.getAbsolutePath() + "]",
-                                          ex );
-        }
+        Writer w = initializeWriter( destinationFile );
 
         XMLWriter writer = null;
         if ( GenerateApplicationXmlMojo.VERSION_1_3.equals( version ) )
@@ -126,33 +113,16 @@
         }
     }
 
-    private void close( Writer closeable )
-    {
-        if ( closeable == null )
-        {
-            return;
-        }
-
-        try
-        {
-            closeable.close();
-        }
-        catch ( Exception e )
-        {
-            // TODO: warn
-        }
-    }
-
-    private XMLWriter initializeRootElementOneDotThree( FileWriter w )
+    private XMLWriter initializeRootElementOneDotThree( Writer w )
     {
-        XMLWriter writer = new PrettyPrintXMLWriter( w, encoding, DOCTYPE_1_3 );
+        XMLWriter writer = initializeXmlWriter( w, DOCTYPE_1_3 );
         writer.startElement( APPLICATION_ELEMENT );
         return writer;
     }
 
-    private XMLWriter initializeRootElementOneDotFour( FileWriter w )
+    private XMLWriter initializeRootElementOneDotFour( Writer w )
     {
-        XMLWriter writer = new PrettyPrintXMLWriter( w, encoding, null );
+        XMLWriter writer = initializeXmlWriter( w, null );
         writer.startElement( APPLICATION_ELEMENT );
         writer.addAttribute( "xmlns", "http://java.sun.com/xml/ns/j2ee" );
         writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
@@ -162,9 +132,9 @@
         return writer;
     }
 
-    private XMLWriter initializeRootElementFive( FileWriter w )
+    private XMLWriter initializeRootElementFive( Writer w )
     {
-        XMLWriter writer = new PrettyPrintXMLWriter( w, encoding, null );
+        XMLWriter writer = initializeXmlWriter( w, null );
         writer.startElement( APPLICATION_ELEMENT );
         writer.addAttribute( "xmlns", "http://java.sun.com/xml/ns/javaee" );
         writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

Added: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarExecutionContext.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarExecutionContext.java?rev=429122&view=auto
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarExecutionContext.java (added)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarExecutionContext.java Sun Aug  6 03:43:45 2006
@@ -0,0 +1,66 @@
+package org.apache.maven.plugin.ear;
+
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+
+/**
+ * Contains various runtime parameters used to customize the generated EAR file.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id$
+ */
+public class EarExecutionContext
+{
+    private static final EarExecutionContext INSTANCE = new EarExecutionContext();
+
+    public static EarExecutionContext getInstance()
+    {
+        return INSTANCE;
+    }
+
+    // Singleton implementation
+
+    private String defaultJavaBundleDir;
+
+    private JbossConfiguration jbossConfiguration;
+
+    private EarExecutionContext()
+    {
+
+    }
+
+    public String getDefaultJavaBundleDir()
+    {
+        return defaultJavaBundleDir;
+    }
+
+    public JbossConfiguration getJbossConfiguration()
+    {
+        return jbossConfiguration;
+    }
+
+    public boolean isJbossConfigured()
+    {
+        return jbossConfiguration != null;
+    }
+
+    protected void initialize( String defaultJavaBundleDir, JbossConfiguration jbossConfiguration )
+    {
+        this.defaultJavaBundleDir = defaultJavaBundleDir;
+        this.jbossConfiguration = jbossConfiguration;
+    }
+}

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarExecutionContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarExecutionContext.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarModule.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarModule.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarModule.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/EarModule.java Sun Aug  6 03:43:45 2006
@@ -38,7 +38,7 @@
      * module has been resolved.
      *
      * @return the artifact
-     * @see #resolveArtifact(java.util.Set, String)
+     * @see #resolveArtifact(java.util.Set)
      */
     public Artifact getArtifact();
 
@@ -65,14 +65,14 @@
     public void appendModule( XMLWriter writer, String version );
 
     /**
-     * Resolves the {@link Artifact} represented by the module with
-     * the specified execution configuration.
+     * Resolves the {@link Artifact} represented by the module. Note
+     * that the {@link EarExecutionContext} might be used to customiz
+     * further the resolution.
      *
-     * @param artifacts            the project's artifacts
-     * @param defaultJavaBundleDir the default bundle dir for {@link JavaModule}
+     * @param artifacts the project's artifacts
      * @throws EarPluginException if the artifact could not be resolved
      */
-    public void resolveArtifact( Set artifacts, String defaultJavaBundleDir )
+    public void resolveArtifact( Set artifacts )
         throws EarPluginException, MojoFailureException;
 
 }

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/GenerateApplicationXmlMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/GenerateApplicationXmlMojo.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/GenerateApplicationXmlMojo.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/GenerateApplicationXmlMojo.java Sun Aug  6 03:43:45 2006
@@ -28,7 +28,7 @@
 import java.util.List;
 
 /**
- * A Mojo that generates the application.xml deployment descriptor file.
+ * A Mojo that generates the EAR deployment descriptor file(s).
  *
  * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
  * @version $Id$
@@ -46,9 +46,6 @@
 
     public static final String VERSION_5 = "5";
 
-    public static final String UTF_8 = "UTF-8";
-
-
     /**
      * Whether the application.xml should be generated or not.
      *
@@ -81,13 +78,6 @@
     private String description = null;
 
     /**
-     * Character encoding for the auto-generated application.xml file.
-     *
-     * @parameter
-     */
-    private String encoding = UTF_8;
-
-    /**
      * The security-roles to be added to the auto-generated
      * application.xml file.
      *
@@ -95,13 +85,6 @@
      */
     private PlexusConfiguration security;
 
-    /**
-     * Directory where the application.xml file will be auto-generated.
-     *
-     * @parameter expression="${project.build.directory}"
-     */
-    private String generatedDescriptorLocation;
-
 
     public void execute()
         throws MojoExecutionException, MojoFailureException
@@ -109,44 +92,76 @@
         // Initializes ear modules
         super.execute();
 
+        // Handle application.xml
         if ( !generateApplicationXml.booleanValue() )
         {
             getLog().debug( "Generation of application.xml is disabled" );
-            return;
-        }
-
-        // Check version
-        if ( !version.equals( VERSION_1_3 ) && !version.equals( VERSION_1_4 ) && !version.equals( VERSION_5 ) )
-        {
-            throw new MojoExecutionException( "Invalid version[" + version + "]" );
-        }
-
-        // Generate deployment descriptor and copy it to the build directory
-        getLog().info( "Generating application.xml" );
-        try
-        {
-            generateDeploymentDescriptor();
         }
-        catch ( EarPluginException e )
+        else
         {
-            throw new MojoExecutionException( "Failed to generate application.xml", e );
+            // Check version
+            if ( !version.equals( VERSION_1_3 ) && !version.equals( VERSION_1_4 ) && !version.equals( VERSION_5 ) )
+            {
+                throw new MojoExecutionException( "Invalid version[" + version + "]" );
+            }
+
+            // Generate deployment descriptor and copy it to the build directory
+            getLog().info( "Generating application.xml" );
+            try
+            {
+                generateStandardDeploymentDescriptor();
+            }
+            catch ( EarPluginException e )
+            {
+                throw new MojoExecutionException( "Failed to generate application.xml", e );
+            }
+
+            try
+            {
+                FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "application.xml" ),
+                                               new File( getWorkDirectory(), "META-INF" ) );
+            }
+            catch ( IOException e )
+            {
+                throw new MojoExecutionException( "Unable to copy application.xml to final destination", e );
+            }
         }
 
-        try
+        // Handle jboss-app.xml
+        if ( getJbossConfiguration() == null )
         {
-            FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "application.xml" ),
-                                           new File( getWorkDirectory(), "META-INF" ) );
+            getLog().debug( "Generation of jboss-app.xml is disabled" );
+            return;
         }
-        catch ( IOException e )
+        else
         {
-            throw new MojoExecutionException( "Unable to copy application.xml to final destination", e );
+            // Generate deployment descriptor and copy it to the build directory
+            getLog().info( "Generating jboss-app.xml" );
+            try
+            {
+                generateJbossDeploymentDescriptor();
+            }
+            catch ( EarPluginException e )
+            {
+                throw new MojoExecutionException( "Failed to generate jboss-app.xml", e );
+            }
+
+            try
+            {
+                FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "jboss-app.xml" ),
+                                               new File( getWorkDirectory(), "META-INF" ) );
+            }
+            catch ( IOException e )
+            {
+                throw new MojoExecutionException( "Unable to copy jboss-app.xml to final destination", e );
+            }
         }
     }
 
     /**
-     * Generates the deployment descriptor if necessary.
+     * Generates the deployment descriptor.
      */
-    protected void generateDeploymentDescriptor()
+    protected void generateStandardDeploymentDescriptor()
         throws EarPluginException
     {
         File outputDir = new File( generatedDescriptorLocation );
@@ -159,6 +174,24 @@
 
         ApplicationXmlWriter writer = new ApplicationXmlWriter( version, encoding );
         writer.write( descriptor, getModules(), buildSecurityRoles(), displayName, description );
+    }
+
+    /**
+     * Generates the jboss deployment descriptor.
+     */
+    protected void generateJbossDeploymentDescriptor()
+        throws EarPluginException
+    {
+        File outputDir = new File( generatedDescriptorLocation );
+        if ( !outputDir.exists() )
+        {
+            outputDir.mkdirs();
+        }
+
+        File descriptor = new File( outputDir, "jboss-app.xml" );
+
+        JbossAppXmlWriter writer = new JbossAppXmlWriter( encoding );
+        writer.write( descriptor, getJbossConfiguration(), getModules() );
     }
 
     /**

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/HarModule.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/HarModule.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/HarModule.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/HarModule.java Sun Aug  6 03:43:45 2006
@@ -28,6 +28,7 @@
  */
 public class HarModule
     extends AbstractEarModule
+    implements JbossEarModule
 {
     public HarModule()
     {
@@ -43,6 +44,15 @@
         // No entry is generated by this artifact ; it should be
         // defined in the jboss-app.xml.
         // See http://docs.jboss.org/jbossas/getting_started/v4/html/hibernate.html
+    }
+
+    public void appendJbossModule( XMLWriter writer, String version )
+    {
+        writer.startElement( MODULE_ELEMENT );
+        writer.startElement( "har" );
+        writer.writeText( getUri() );
+        writer.endElement();
+        writer.endElement();
     }
 
     protected String getType()

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JavaModule.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JavaModule.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JavaModule.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JavaModule.java Sun Aug  6 03:43:45 2006
@@ -61,15 +61,15 @@
         }
     }
 
-    public void resolveArtifact( Set artifacts, String defaultJavaBundleDir )
-        throws EarPluginException , MojoFailureException
+    public void resolveArtifact( Set artifacts )
+        throws EarPluginException, MojoFailureException
     {
         // Let's resolve the artifact
-        super.resolveArtifact( artifacts, defaultJavaBundleDir );
+        super.resolveArtifact( artifacts );
 
         // If the defaultJavaBundleDir is set and no bundle dir is
         // set, set the default as bundle dir
-        setJavaBundleDir( defaultJavaBundleDir );
+        setJavaBundleDir( EarExecutionContext.getInstance().getDefaultJavaBundleDir() );
     }
 
     protected String getType()

Added: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossAppXmlWriter.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossAppXmlWriter.java?rev=429122&view=auto
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossAppXmlWriter.java (added)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossAppXmlWriter.java Sun Aug  6 03:43:45 2006
@@ -0,0 +1,108 @@
+package org.apache.maven.plugin.ear;
+
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+import java.io.File;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.List;
+
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/**
+ * An <tt>XmlWriter</tt> based implementation used to generate a
+ * <tt>jboss-app.xml</tt> file
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id$
+ */
+final class JbossAppXmlWriter
+    extends AbstractXmlWriter
+{
+
+    public static final String DOCTYPE_3_2 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD J2EE Application 1.3//EN\"\n" +
+        "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_3_2.dtd\"";
+
+    public static final String DOCTYPE_4 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD J2EE Application 1.4//EN\"\n" +
+        "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_4_0.dtd\"";
+
+    private static final String JBOSS_APP_ELEMENT = "jboss-app";
+
+    private static final String MODULE_ELEMENT = "module";
+
+    JbossAppXmlWriter( String encoding )
+    {
+        super( encoding );
+    }
+
+    public void write( File destinationFile, JbossConfiguration jbossConfiguration, List earModules )
+        throws EarPluginException
+    {
+        final Writer w = initializeWriter( destinationFile );
+
+        XMLWriter writer = null;
+        if ( jbossConfiguration.isJbossThreeDot2() )
+        {
+            writer = initializeXmlWriter( w, DOCTYPE_3_2 );
+        }
+        else
+        {
+            writer = initializeXmlWriter( w, DOCTYPE_4 );
+        }
+        writer.startElement( JBOSS_APP_ELEMENT );
+
+        // If JBoss 4, write the jboss4 specific stuff
+        if ( jbossConfiguration.isJbossFour() )
+        {
+            if ( jbossConfiguration.getSecurityDomain() != null )
+            {
+                writer.startElement( JbossConfiguration.SECURITY_DOMAIN );
+                writer.writeText( jbossConfiguration.getSecurityDomain() );
+                writer.endElement();
+            }
+            if ( jbossConfiguration.getUnauthenticatedPrincipal() != null )
+            {
+                writer.startElement( JbossConfiguration.UNAUHTHENTICTED_PRINCIPAL );
+                writer.writeText( jbossConfiguration.getUnauthenticatedPrincipal() );
+                writer.endElement();
+            }
+        }
+
+        // jmx name
+        if ( jbossConfiguration.getJmxName() != null )
+        {
+            writer.startElement( JbossConfiguration.JMX_NAME );
+            writer.writeText( jbossConfiguration.getJmxName() );
+            writer.endElement();
+        }
+
+        // Write the JBoss specific modules
+        final Iterator it = earModules.iterator();
+        while ( it.hasNext() )
+        {
+            EarModule earModule = (EarModule) it.next();
+            if ( JbossEarModule.class.isInstance( earModule ) )
+            {
+                JbossEarModule jbossEarModule = (JbossEarModule) earModule;
+                jbossEarModule.appendJbossModule( writer, jbossConfiguration.getVersion() );
+            }
+        }
+        writer.endElement();
+
+        close( w );
+    }
+}

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossAppXmlWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossAppXmlWriter.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossConfiguration.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossConfiguration.java?rev=429122&view=auto
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossConfiguration.java (added)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossConfiguration.java Sun Aug  6 03:43:45 2006
@@ -0,0 +1,160 @@
+package org.apache.maven.plugin.ear;
+
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+
+/**
+ * The JBoss specific configuration, used to generate the jboss-app.xml
+ * deployment descriptor file
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id$
+ */
+class JbossConfiguration
+{
+    static final String VERSION_3_2 = "3.2";
+
+    static final String VERSION_4 = "4";
+
+    static final String VERSION = "version";
+
+    static final String SECURITY_DOMAIN = "security-domain";
+
+    static final String UNAUHTHENTICTED_PRINCIPAL = "unauthenticated-principal";
+
+    static final String JMX_NAME = "jmx-name";
+
+
+    private final String version;
+
+    private boolean jbossThreeDot2;
+
+    private boolean jbossFour;
+
+    private final String securityDomain;
+
+    private final String unauthenticatedPrincipal;
+
+    private final String jmxName;
+
+
+    public JbossConfiguration( String version, String securityDomain, String unauthenticatedPrincipal, String jmxName )
+        throws EarPluginException
+    {
+        if ( version == null )
+        {
+            throw new EarPluginException( "jboss version could not be null." );
+        }
+        else
+        {
+            this.version = version;
+            if ( version.equals( JbossConfiguration.VERSION_3_2 ) )
+            {
+                this.jbossThreeDot2 = true;
+            }
+            else if ( version.equals( JbossConfiguration.VERSION_4 ) )
+            {
+                this.jbossFour = true;
+            }
+            else
+            {
+                throw new EarPluginException(
+                    "Invalid JBoss configuration, version[" + version + "] is not supported." );
+            }
+            this.securityDomain = securityDomain;
+            this.unauthenticatedPrincipal = unauthenticatedPrincipal;
+            this.jmxName = jmxName;
+        }
+    }
+
+    /**
+     * Returns the targeted version of JBoss.
+     *
+     * @return the jboss version
+     */
+    public String getVersion()
+    {
+        return version;
+    }
+
+    /**
+     * Returns true if the targeted JBoss version is 3.2.
+     *
+     * @return if the targeted version is 3.2
+     */
+    public boolean isJbossThreeDot2()
+    {
+        return jbossThreeDot2;
+    }
+
+    /**
+     * Returns true if the targeted JBoss version is 4.
+     *
+     * @return if the targeted version is 4
+     */
+    public boolean isJbossFour()
+    {
+        return jbossFour;
+    }
+
+    /**
+     * The security-domain element specifies the JNDI name of the security
+     * manager that implements the EJBSecurityManager and RealmMapping for
+     * the domain. When specified at the jboss level it specifies the security
+     * domain for all j2ee components in the deployment unit.
+     * <p/>
+     * One can override the global security-domain at the container
+     * level using the security-domain element at the container-configuration
+     * level.
+     * <p/>
+     * Only available as from JBoss 4.
+     *
+     * @return the JNDI name of the security manager
+     */
+    public String getSecurityDomain()
+    {
+        return securityDomain;
+    }
+
+    /**
+     * The unauthenticated-principal element specifies the name of the principal
+     * that will be returned by the EJBContext.getCallerPrincipal() method if there
+     * is no authenticated user. This Principal has no roles or privaledges to call
+     * any other beans.
+     * <p/>
+     * Only available as from JBoss 4.
+     *
+     * @return the unauthenticated principal
+     */
+    public String getUnauthenticatedPrincipal()
+    {
+        return unauthenticatedPrincipal;
+    }
+
+    /**
+     * The jmx-name element allows one to specify the JMX ObjectName to use
+     * for the MBean associated with the ear module. This must be a unique
+     * name and valid JMX ObjectName string.
+     *
+     * @return the object name of the ear mbean
+     */
+    public String getJmxName()
+    {
+        return jmxName;
+    }
+
+}

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossConfiguration.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossEarModule.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossEarModule.java?rev=429122&view=auto
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossEarModule.java (added)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossEarModule.java Sun Aug  6 03:43:45 2006
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2006 Your Corporation. All Rights Reserved.
+ */
+package org.apache.maven.plugin.ear;
+
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * Represents a JBoss specific ear module.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id$
+ */
+public interface JbossEarModule
+{
+    /**
+     * Appends the <tt>XML</tt> representation of this module for
+     * the jboss-app.xml file.
+     *
+     * @param writer  the writer to use
+     * @param version the version of the <tt>jboss-app.xml</tt> file
+     */
+    public void appendJbossModule( XMLWriter writer, String version );
+}

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossEarModule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/JbossEarModule.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/SarModule.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/SarModule.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/SarModule.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/SarModule.java Sun Aug  6 03:43:45 2006
@@ -28,6 +28,7 @@
  */
 public class SarModule
     extends AbstractEarModule
+    implements JbossEarModule
 {
     protected static final String SAR_MODULE = "connector";
 
@@ -42,8 +43,21 @@
 
     public void appendModule( XMLWriter writer, String version )
     {
+        // If JBoss is not configured, add the module as a connector element
+        if ( !EarExecutionContext.getInstance().isJbossConfigured() )
+        {
+            writer.startElement( MODULE_ELEMENT );
+            writer.startElement( SAR_MODULE );
+            writer.writeText( getUri() );
+            writer.endElement();
+            writer.endElement();
+        }
+    }
+
+    public void appendJbossModule( XMLWriter writer, String version )
+    {
         writer.startElement( MODULE_ELEMENT );
-        writer.startElement( SAR_MODULE );
+        writer.startElement( "service" );
         writer.writeText( getUri() );
         writer.endElement();
         writer.endElement();

Modified: maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/WebModule.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/WebModule.java?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/WebModule.java (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/main/java/org/apache/maven/plugin/ear/WebModule.java Sun Aug  6 03:43:45 2006
@@ -61,7 +61,8 @@
 
         // If noContextRoot is true, skip the generation of
         // the context-root element
-        if (!noContextRoot.booleanValue()) {
+        if ( !noContextRoot.booleanValue() )
+        {
             writer.startElement( CONTEXT_ROOT_FIELD );
             writer.writeText( getContextRoot() );
             writer.endElement(); // context-root
@@ -70,11 +71,11 @@
         writer.endElement(); // module
     }
 
-    public void resolveArtifact( Set artifacts, String defaultJavaBundleDir )
+    public void resolveArtifact( Set artifacts )
         throws EarPluginException, MojoFailureException
     {
         // Let's resolve the artifact
-        super.resolveArtifact( artifacts, defaultJavaBundleDir );
+        super.resolveArtifact( artifacts );
 
         // Context root has not been customized - using default
         if ( contextRoot == null )

Added: maven/plugins/trunk/maven-ear-plugin/src/site/apt/examples/generating-jboss-app.apt
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/site/apt/examples/generating-jboss-app.apt?rev=429122&view=auto
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/site/apt/examples/generating-jboss-app.apt (added)
+++ maven/plugins/trunk/maven-ear-plugin/src/site/apt/examples/generating-jboss-app.apt Sun Aug  6 03:43:45 2006
@@ -0,0 +1,48 @@
+  ------
+  Generating the JBoss deployment descriptor file
+  ------
+  Stephane Nicoll
+  <sn...@apache.org>
+  ------
+  August 06, 2006
+
+~~ Copyright 2006 The Apache Software Foundation.
+~~
+~~ Licensed 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/guides/mini/guide-apt-format.html
+
+
+Generating the JBoss deployment descriptor file
+
+  To trigger the generation of the jboss-app.xml file you need to configure the 'jboss' element. For instance
+  to target version 4 of JBoss with a 'guest' unauthenticated principal:
+
++--------
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-ear-plugin</artifactId>
+        <configuration>
+           [...]
+           <jboss>
+             <version>4</version>
+             <unauthenticated-principal>guest</unauthenticated-principal>
+           </jboss>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
++---------

Propchange: maven/plugins/trunk/maven-ear-plugin/src/site/apt/examples/generating-jboss-app.apt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-ear-plugin/src/site/apt/examples/generating-jboss-app.apt
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/plugins/trunk/maven-ear-plugin/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/site/apt/index.apt?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/site/apt/index.apt (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/site/apt/index.apt Sun Aug  6 03:43:45 2006
@@ -67,7 +67,7 @@
   * {{{ear-mojo.html}ear:ear}} generates J2EE Enterprise Archive (EAR) files.
 
   * {{{generate-application-xml-mojo.html}ear:generate-application-xml}}
-  generates the application.xml deployment descriptor file.
+  generates the deployment descriptor file(s).
 
 * Usage
 
@@ -94,3 +94,5 @@
 
   * {{{examples/specifying-security-roles-for-the-generated-application-xml.html}
   Specifying Security Roles For The Generated application.xml}}
+
+  * {{{examples/generating-jboss-app.html} Generating the jboss-app.xml file}}

Modified: maven/plugins/trunk/maven-ear-plugin/src/site/apt/usage.apt
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-ear-plugin/src/site/apt/usage.apt?rev=429122&r1=429121&r2=429122&view=diff
==============================================================================
--- maven/plugins/trunk/maven-ear-plugin/src/site/apt/usage.apt (original)
+++ maven/plugins/trunk/maven-ear-plugin/src/site/apt/usage.apt Sun Aug  6 03:43:45 2006
@@ -99,3 +99,22 @@
 
   You can take a look at the examples for more information on these advanced
   configurations.
+
+* JBoss support
+
+  The EAR plugin can generate the jboss-app.xml automatically. To do so, the 'jboss'
+  element must be configured and takes the following child elements:
+
+   * <<version>>: the targeted JBoss version to use (3.2 or 4 which is the default).
+
+   * <<security-domain>>: the JNDI name of the security manager (JBoss 4 only)
+
+   * <<unauthenticated-principal>>: the unauthenticated principal (JBoss 4 only)
+
+   * <<jmx-name>>: the object name of the ear mbean.
+
+  Hibernate archives (HAR) and Service archives (SAR) will be recognized automatically
+  and added the the jboss-app.xml file.
+
+  You can take a look at the examples for more information on the JBoss support.
+