diff --git a/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RunMojo.java b/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RunMojo.java index fbfec14a..35230313 100644 --- a/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RunMojo.java +++ b/plugins/alfresco-maven-plugin/src/main/java/org/alfresco/maven/plugin/RunMojo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2015 Alfresco Software Limited. + * Copyright (C) 2016 Alfresco Software Limited. *

* This file is part of the Alfresco SDK. *

@@ -17,9 +17,9 @@ */ package org.alfresco.maven.plugin; +import org.apache.commons.lang.StringUtils; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; -import org.apache.maven.model.Plugin; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.BuildPluginManager; import org.apache.maven.plugin.MojoExecutionException; @@ -29,18 +29,24 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; -import org.twdata.maven.mojoexecutor.MojoExecutor; import java.util.*; import static org.twdata.maven.mojoexecutor.MojoExecutor.*; - - -@Mojo( name = "run", defaultPhase = LifecyclePhase.PROCESS_SOURCES, requiresDependencyResolution = ResolutionScope.TEST) -public class RunMojo extends AbstractMojo -{ +/** + * Runner component that can be used to test your extension. + * + * @author ole.hejlskov, martin.bergljung + * @version 1.0 + * @since 3.0.0 + */ +@Mojo( name = "run", + defaultPhase = LifecyclePhase.TEST, + aggregator = true, + requiresDependencyResolution = ResolutionScope.TEST) +public class RunMojo extends AbstractMojo { @Component protected MavenProject project; @@ -50,70 +56,204 @@ public class RunMojo extends AbstractMojo @Component private BuildPluginManager pluginManager; + /** + * The following properties that start with 'maven.' are used to control the + * Alfresco Maven plugin itself. + *

+ * For example: + *

+     *    {@code
+     *      
+     *          org.alfresco.maven.plugin
+     *          alfresco-maven-plugin
+     *          3.0.0
+     *          
+     *              true
+     *              false
+     *              true
+     *              true
+     *          
+     *      
+     *    }
+     */
+
+    /**
+     * Switch to enable/disable the Apache Solr 4 web application when running embedded Tomcat.
+     */
     @Parameter(property = "maven.alfresco.enableSolr", defaultValue = "true")
     protected boolean enableSolr;
 
-    @Parameter(property = "maven.alfresco.solrHome", defaultValue = "${project.basedir}/${alfresco.data.location}/solr")
-    protected String solrHome;
-
-    @Parameter(property = "alfresco.version", defaultValue = "5.1-a-EA")
-    protected String alfrescoVersion;
-
-    @Parameter(property = "alfresco.groupId", defaultValue = "org.alfresco")
-    protected String alfrescoGroupId;
-
-    @Parameter(property = "alfresco.db.url", defaultValue = "jdbc:h2:./${alfresco.data.location}/h2_data/${alfresco.db.name};${alfresco.db.params}")
-    protected String alfrescoDbUrl;
-
-
+    /**
+     * Switch to enable/disable the H2 database when running embedded Tomcat.
+     * This also brings in the needed H2 database scripts.
+     */
     @Parameter(property = "maven.alfresco.enableH2", defaultValue = "true")
     protected boolean enableH2;
 
-
+    /**
+     * Switch to enable/disable the Repository (alfresco.war) when running embedded Tomcat.
+     */
     @Parameter(property = "maven.alfresco.enableRepository", defaultValue = "true")
     protected boolean enableRepository;
 
+    /**
+     * Switch to enable/disable the Share (share.war) when running embedded Tomcat.
+     */
     @Parameter(property = "maven.alfresco.enableShare", defaultValue = "true")
     protected boolean enableShare;
 
+    /**
+     * Switch to enable/disable the Alfresco REST API Explorer (api-explorer.war) when running embedded Tomcat.
+     */
+    @Parameter(property = "maven.alfresco.enableApiExplorer", defaultValue = "false")
+    protected boolean enableApiExplorer;
+
+    /**
+     * Switch to enable/disable test properties when running embedded Tomcat.
+     */
     @Parameter(property = "maven.alfresco.enableTestProperties", defaultValue = "true")
     protected boolean enableTestProperties;
 
+    /**
+     * Switch to enable/disable running embedded Apache Tomcat.
+     */
     @Parameter(property = "maven.alfresco.enableTomcat", defaultValue = "true")
     protected boolean enableTomcat;
 
-
+    /**
+     * Directory containing test files that should be used when running embedded Tomcat
+     */
     @Parameter(property = "maven.alfresco.testFolder", defaultValue = "src/test/properties/${env}")
     protected String testFolder;
 
-
+    /**
+     * Test files in testFolder that should be included when running embedded Tomcat
+     */
     @Parameter(property = "maven.alfresco.testInclude", defaultValue = "**")
     protected String testInclude;
 
-    @Parameter(property = "maven.alfresco.pgsqlDialectFolder", defaultValue = "${project.build.directory}/pg-dialect-tmp")
-    protected String pgsqlDialectFolder;
+    /**
+     * Maven GAV properties for standard Alfresco web applications.
+     */
+    @Parameter(property = "alfresco.groupId", defaultValue = "org.alfresco")
+    protected String alfrescoGroupId;
 
+    @Parameter(property = "alfresco.platform.war.artifactId", defaultValue = "alfresco")
+    protected String alfrescoRepoWarArtifactId;
 
+    @Parameter(property = "alfresco.share.war.artifactId", defaultValue = "share")
+    protected String alfrescoShareWarArtifactId;
 
+    @Parameter(property = "alfresco.solr.artifactId", defaultValue = "alfresco-solr4")
+    protected String alfrescoSolrArtifactId;
+
+    @Parameter(property = "alfresco.api.explorer.artifactId", defaultValue = "api-explorer")
+    protected String alfrescoApiExplorerArtifactId;
+
+    @Parameter(property = "alfresco.platform.version", defaultValue = "5.1.f")
+    protected String alfrescoRepoVersion;
+
+    @Parameter(property = "alfresco.share.version", defaultValue = "5.1.f")
+    protected String alfrescoShareVersion;
+
+    @Parameter(property = "alfresco.api.explorer.version", defaultValue = "1.0")
+    protected String alfrescoApiExplorerVersion;
+
+    /**
+     * Maven GAV properties for customized alfresco.war and share.war
+     * Used by the Maven Tomcat 7 Plugin
+     */
+    @Parameter(property = "runner.alfresco.groupId", defaultValue = "${alfresco.groupId}")
+    protected String runnerAlfrescoGroupId;
+
+    @Parameter(property = "runner.alfresco.platform.war.artifactId", defaultValue = "${alfresco.platform.war.artifactId}")
+    protected String runnerAlfrescoRepoWarArtifactId;
+
+    @Parameter(property = "runner.alfresco.share.war.artifactId", defaultValue = "${alfresco.share.war.artifactId}")
+    protected String runnerAlfrescoShareWarArtifactId;
+
+    @Parameter(property = "runner.alfresco.platform.version", defaultValue = "${alfresco.platform.version}")
+    protected String runnerAlfrescoRepoVersion;
+
+    @Parameter(property = "runner.alfresco.share.version", defaultValue = "${alfresco.share.version}")
+    protected String runnerAlfrescoShareVersion;
+
+    /**
+     * Directory that contains the Alfresco Solr 4 configuration
+     */
+    @Parameter(property = "solr.home", defaultValue = "${project.basedir}/${alfresco.data.location}/solr")
+    protected String solrHome;
+
+    /**
+     * Database JDBC connection URL
+     * TODO: Is this parameter needed here?
+     */
+    @Parameter(property = "alfresco.db.url", defaultValue = "jdbc:h2:./${alfresco.data.location}/h2_data/${alfresco.db.name};${alfresco.db.params}")
+    protected String alfrescoDbUrl;
 
     private ExecutionEnvironment execEnv;
 
+    /**
+     * Have to have this setter as it does not seem to work to assign a default value to a property
+     * where the value comes from a property that is not used (i.e. alfrescoRepoWarArtifactId)
+     *
+     * @param artifactId
+
+    public void setRunnerAlfrescoRepoArtifactId(String artifactId) {
+        getLog().info("setRunnerAlfrescoRepoArtifactId [artifactId=" + artifactId +
+                "][alfrescoRepoArtifactId=" + this.alfrescoRepoArtifactId + "]");
+        if (StringUtils.isBlank(artifactId)) {
+            if (StringUtils.isNotBlank(this.alfrescoRepoArtifactId)) {
+                this.runnerAlfrescoRepoArtifactId = this.alfrescoRepoArtifactId;
+            } else {
+                getLog().error("Alfresco Repository WAR Maven Artifact ID is not set via either " +
+                        "runner.alfresco.platform.war.artifactId or alfresco.platform.war.artifactId");
+            }
+        } else {
+            this.runnerAlfrescoRepoArtifactId = artifactId;
+        }
+    }
+     */
+
+    /**
+     * Have to have this setter as it does not seem to work to assign a default value to a property
+     * where the value comes from a property that is not used (i.e. alfrescoShareWarArtifactId)
+     *
+     * @param artifactId
+
+    public void setRunnerAlfrescoShareArtifactId(String artifactId) {
+        getLog().info("setRunnerAlfrescoShareArtifactId [artifactId=" + artifactId +
+                "][alfrescoShareWarArtifactId=" + this.alfrescoShareWarArtifactId + "]");
+        if (StringUtils.isBlank(artifactId)) {
+            if (StringUtils.isNotBlank(this.alfrescoShareWarArtifactId)) {
+                this.runnerAlfrescoShareWarArtifactId = this.alfrescoShareWarArtifactId;
+            } else {
+                getLog().error("Alfresco Share WAR Maven Artifact ID is not set via either " +
+                        "runner.alfresco.share.artifactId or alfresco.share.artifactId");
+            }
+        } else {
+            this.runnerAlfrescoShareWarArtifactId = artifactId;
+        }
+    }
+     */
+
     public void execute() throws MojoExecutionException {
+        // The runner repo artifact ID might not be set, initialize in that case
+/*        if (StringUtils.isBlank(this.runnerAlfrescoRepoWarArtifactId)) {
+            setRunneralfrescoRepoWarArtifactId(null);
+        }
 
-
-
+        // The runner share artifact ID might not be set, initialize in that case
+        if (StringUtils.isBlank(this.runnerAlfrescoShareWarArtifactId)) {
+            setRunnerAlfrescoShareArtifactId(null);
+        }
+*/
         execEnv = executionEnvironment(
                 project,
                 session,
                 pluginManager
         );
 
-
-        if (enableH2) {
-            unpackH2Config();
-            copyH2Config();
-        }
-
         if (enableSolr) {
             unpackSolrConfig();
             replaceSolrConfigProperties();
@@ -127,9 +267,14 @@ public class RunMojo extends AbstractMojo
         if (enableTomcat) {
             startTomcat();
         }
-
     }
 
+    /**
+     * Download and unpack the Solr 4 configuration as we don't have it in the project.
+     * It will reside under /alf_data_dev/solr
+     *
+     * @throws MojoExecutionException
+     */
     protected void unpackSolrConfig() throws MojoExecutionException {
         getLog().info("Unpacking Solr config");
         executeMojo(
@@ -144,8 +289,8 @@ public class RunMojo extends AbstractMojo
                         element(name("artifactItems"),
                                 element(name("artifactItem"),
                                         element(name("groupId"), alfrescoGroupId),
-                                        element(name("artifactId"), "alfresco-solr4"),
-                                        element(name("version"), alfrescoVersion),
+                                        element(name("artifactId"), alfrescoSolrArtifactId),
+                                        element(name("version"), alfrescoRepoVersion),
                                         element(name("classifier"), "config"),
                                         element(name("type"), "zip")
                                 )
@@ -156,6 +301,12 @@ public class RunMojo extends AbstractMojo
 
     }
 
+    /**
+     * Replace property placeholders in configuration files for the cores, so the
+     * index files can be found for each core when Solr starts up.
+     *
+     * @throws MojoExecutionException
+     */
     protected void replaceSolrConfigProperties() throws MojoExecutionException {
         getLog().info("Replacing Solr config properties");
         executeMojo(
@@ -168,7 +319,7 @@ public class RunMojo extends AbstractMojo
                 configuration(
                         element(name("regex"), "false"),
                         element(name("includes"),
-                                element(name("include"), solrHome + "/archive-SpacesStore/conf/solrcore.properties" ),
+                                element(name("include"), solrHome + "/archive-SpacesStore/conf/solrcore.properties"),
                                 element(name("include"), solrHome + "/workspace-SpacesStore/conf/solrcore.properties")
                         ),
                         element(name("replacements"),
@@ -183,70 +334,13 @@ public class RunMojo extends AbstractMojo
 
     }
 
-    // @TODO We don't need this anymore! As per https://issues.alfresco.com/jira/browse/ACE-4563 we will get an
-    // alfresco-repository artifact with h2scripts classifier which we simply slap in the Tomcat classpath
-    // and we're good!
-    protected void unpackH2Config() throws MojoExecutionException {
-        // @TODO Check if H2 is enabled, if not no need to do this step
-
-        getLog().info("Unpacking H2 config");
-        executeMojo(
-                plugin(
-                        groupId("org.apache.maven.plugins"),
-                        artifactId("maven-dependency-plugin"),
-                        version("2.9")
-                ),
-                goal("unpack"),
-                configuration(
-                        element(name("outputDirectory"), pgsqlDialectFolder),
-                        element(name("artifactItems"),
-                                element(name("artifactItem"),
-                                        element(name("groupId"), alfrescoGroupId),
-                                        element(name("artifactId"), "alfresco-repository"),
-                                        element(name("version"), alfrescoVersion),
-                                        element(name("includes"), "alfresco/dbscripts/create/org.hibernate.dialect.PostgreSQLDialect/*,alfresco/dbscripts/upgrade/*/org.hibernate.dialect.PostgreSQLDialect/*,alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/*")
-                                )
-                        )
-                ),
-                execEnv
-        );
-
-    }
-
-    protected void copyH2Config() throws MojoExecutionException {
-        // @TODO Check if H2 is enabled, if not no need to do this step
-        getLog().info("Extracting H2 Dialect");
-        executeMojo(
-                plugin(
-                        groupId("org.apache.maven.plugins"),
-                        artifactId("maven-resources-plugin"),
-                        version("2.7")
-                ),
-                goal("copy-resources"),
-                configuration(
-                        element(name("outputDirectory"), "${project.build.testOutputDirectory}"),
-                        element(name("resources"),
-                                element(name("resource"),
-                                        element(name("directory"), pgsqlDialectFolder + "/alfresco/dbscripts/create/org.hibernate.dialect.PostgreSQLDialect"),
-                                        element(name("includes"),
-                                                element(name("include"), "*")
-                                        ),
-                                        element(name("targetPath"), "alfresco/dbscripts/create/org.hibernate.dialect.H2Dialect")
-                                ),
-                                element(name("resource"),
-                                        element(name("directory"), pgsqlDialectFolder + "/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect"),
-                                        element(name("includes"),
-                                                element(name("include"), "*")
-                                        ),
-                                        element(name("targetPath"), "alfresco/ibatis/org.hibernate.dialect.H2Dialect")
-                                )
-                        )
-                ),
-                execEnv
-        );
-
-    }
-
+    /**
+     * Copy the alfresco-global.properties file that will be used when
+     * running Alfresco. It contains database connection parameters and
+     * other general configuration for Alfresco Repository (alfresco.war)
+     *
+     * @throws MojoExecutionException
+     */
     protected void copyAlfrescoGlobalProperties() throws MojoExecutionException {
         getLog().info("Copying alfresco-global.properties to test resources");
         executeMojo(
@@ -272,68 +366,67 @@ public class RunMojo extends AbstractMojo
         );
     }
 
+    /**
+     * Start up the embedded Tomcat server with the webapps that has been
+     * configured in the SDK project.
+     *
+     * @throws MojoExecutionException
+     */
     protected void startTomcat() throws MojoExecutionException {
         getLog().info("Starting Tomcat");
 
-        List tomcatDependencies = null;
-        Element solrElement = null;
-        Element repoElement = null;
-        Element shareElement = null;
-        ArrayList tmpWebapps = new ArrayList();
-
+        List tomcatDependencies = new ArrayList();
+        ArrayList webapps2Deploy = new ArrayList();
 
+        // Add the basic Tomcat dependencies
+        tomcatDependencies.add(
+                // Packaging goes faster with this lib
+                dependency("org.codehaus.plexus", "plexus-archiver", "2.3"));
+        tomcatDependencies.add(
+                // The following dependency is needed, otherwise you get
+                //  Caused by: java.lang.NoSuchMethodError:
+                //      javax.servlet.ServletContext.getSessionCookieConfig()Ljavax/servlet/SessionCookieConfig
+                // This method is in Servlet API 3.0
+                dependency("javax.servlet", "javax.servlet-api", "3.0.1"));
 
         if (enableH2) {
-            tomcatDependencies = dependencies(
-                    dependency("com.h2database", "h2", "1.4.190"),
-                    dependency("org.codehaus.plexus", "plexus-archiver", "2.3")
-            );
-        }
+            Dependency h2ScriptsDependency = dependency(alfrescoGroupId, "alfresco-repository", alfrescoRepoVersion);
+            h2ScriptsDependency.setClassifier("h2scripts");
 
-        if (enableSolr) {
-            solrElement = element(name("webapp"),
-                    element(name("groupId"), alfrescoGroupId),
-                    element(name("artifactId"), "alfresco-solr4"),
-                    element(name("version"), alfrescoVersion),
-                    element(name("type"), "war"),
-                    element(name("asWebapp"), "true"),
-                    element(name("contextPath"), "/solr4"),
-                    element(name("contextFile"), "${project.build.directory}/context-solr.xml")
-            );
-            tmpWebapps.add(solrElement);
+            tomcatDependencies.add(
+                    // Bring in the flat file H2 database
+                    dependency("com.h2database", "h2", "1.4.190"));
+            tomcatDependencies.add(
+                    // Bring in the H2 Database scripts for the Alfresco version we use
+                    h2ScriptsDependency);
         }
 
         if (enableRepository) {
-            repoElement = element(name("webapp"),
-                    element(name("groupId"), alfrescoGroupId),
-                    element(name("artifactId"), "${alfresco.repo.artifactId}"),
-                    element(name("version"), alfrescoVersion),
-                    element(name("type"), "war"),
-                    element(name("asWebapp"), "true"),
-                    element(name("contextFile"), "${project.build.directory}/context-repo.xml")
-            );
-            tmpWebapps.add( repoElement );
+            webapps2Deploy.add(createWebAppElement(
+                    runnerAlfrescoGroupId, runnerAlfrescoRepoWarArtifactId, runnerAlfrescoRepoVersion,
+                    "/alfresco", "${project.build.testOutputDirectory}/tomcat/context-repo.xml"));
         }
 
-
         if (enableShare) {
-            shareElement = element(name("webapp"),
-                    element(name("groupId"), alfrescoGroupId),
-                    element(name("artifactId"), "${alfresco.share.artifactId}"),
-                    element(name("version"), alfrescoVersion),
-                    element(name("type"), "war"),
-                    element(name("asWebapp"), "true"),
-                    element(name("contextFile"), "${project.build.directory}/context-share.xml")
-            );
-            tmpWebapps.add( shareElement );
+            webapps2Deploy.add(createWebAppElement(
+                    runnerAlfrescoGroupId, runnerAlfrescoShareWarArtifactId, runnerAlfrescoShareVersion,
+                    "/share", "${project.build.testOutputDirectory}/tomcat/context-share.xml"));
+        }
 
+        if (enableSolr) {
+            webapps2Deploy.add(createWebAppElement(alfrescoGroupId, alfrescoSolrArtifactId, alfrescoRepoVersion,
+                    "/solr4", "${project.build.testOutputDirectory}/tomcat/context-solr.xml"));
+        }
 
+        if (enableApiExplorer) {
+            webapps2Deploy.add(createWebAppElement(alfrescoGroupId, alfrescoApiExplorerArtifactId, alfrescoApiExplorerVersion,
+                    "/api-explorer", null));
         }
 
         // This might be ugly, the MojoExecuter will only accept Element[] and we need this list to be dynamic
-        // to avoid NPEs. If there's a prettier way to do the above please feel free to change it!
-        Element[] webapps = new Element[tmpWebapps.size()];
-        tmpWebapps.toArray(webapps);
+        // to avoid NPEs. If there's a better way to do this, then feel free to change it!
+        Element[] webapps = new Element[webapps2Deploy.size()];
+        webapps2Deploy.toArray(webapps);
 
         executeMojo(
                 plugin(
@@ -344,14 +437,52 @@ public class RunMojo extends AbstractMojo
                 ),
                 goal("run"),
                 configuration(
+                        /*
+                         * SDK Projects doesn't have packaging set to 'war', they are JARs or POMs, this setting ignores that fact.
+                         */
                         element(name("ignorePackaging"), "true"),
-                        element(name("useSeparateTomcatClassLoader"), "true"),
+
+                        /*
+                         * Make sure Catalina classes are picked up when we got virtual webapp contexts with classpaths.
+                         *
+                         * If true a new classLoader separated from maven core will be created to start.
+                         * This does not work to run with, getting :
+                         *      NoSuchMethodError: javax.servlet.ServletContext.getSessionCookieConfig
+                         *      (which lives in Servlet API 3)
+                         *
+                         */
+                        //element(name("useSeparateTomcatClassLoader"), "true"),
+
+                        /*
+                         * Bring in stuff in the test classpath, such as the alfresco-global.properties that should be used
+                         */
                         element(name("useTestClasspath"), "true"),
+
+                        /**
+                         * Set up where Solr Home directory is
+                         */
                         element(name("systemProperties"),
-                                element(name("java.io.tmpdir"), "${project.build.directory}")
+                                element(name("java.io.tmpdir"), "${project.build.directory}"),
+                                element(name("solr.solr.home"), solrHome)
                         ),
+
+                        /*  Should this class loader delegate to the parent class loader before searching its
+                            own repositories (i.e. the usual Java2 delegation model).
+                            Prevent parent classloader delegation, each webapp loads.
+                            If set to true then you will get a truckload of Solr logging as
+                            the alf_data_dev/solr4/config/log4j-solr.properties file is not picked up.
+                            This also fixes issues with the Google Guava Library, which this tomcat plugin uses
+                            version 10.0.1 of but Solr uses 14.0.1 */
                         element(name("delegate"), "false"),
 
+                        /*
+                         * Encode url in UTF-8 for proper character handling -->
+                         */
+                        element(name("uriEncoding"), "UTF-8"),
+
+                        /*
+                         * Bring in the webapps that should be deployed and run
+                         */
                         element(name("webapps"), webapps)
 
                 ),
@@ -359,6 +490,62 @@ public class RunMojo extends AbstractMojo
         );
     }
 
+    /**
+     * Create a webapp element that can be added as a webapp configuration to the Tomcat plug-in.
+     * 

+ * For example: + *

+     *    {@code
+     *    
+     *        ${project.groupId}
+     *        share
+     *        ${project.version}
+     *        war
+     *        true
+     *        /share
+     *        ${project.build.directory}/contexts/context-share.xml
+     *    
+     *    }
+     * 
+ * + * @param groupId + * @param artifactId + * @param version + * @param contextPath + * @param contextFile + * @return + */ + private Element createWebAppElement(String groupId, + String artifactId, + String version, + String contextPath, + String contextFile) { + String errorStr = "cannot be null when creating webapp element for Tomcat 7 plugin"; + if (StringUtils.isBlank(groupId)) { + getLog().error("Maven Group Id " + errorStr); + } + if (StringUtils.isBlank(artifactId)) { + getLog().error("Maven Artifact Id " + errorStr); + } + if (StringUtils.isBlank(version)) { + getLog().error("Maven Version number " + errorStr); + } + Element e = element(name("webapp"), + element(name("groupId"), groupId), + element(name("artifactId"), artifactId), + element(name("version"), version), + element(name("type"), "war"), + // Make sure webapp is loaded with context and everything, + // if set to 'false' then you will get 404 when trying to access the webapp from browser + element(name("asWebapp"), "true"), + + element(name("contextPath"), contextPath), + StringUtils.isNotBlank(contextFile) ? element(name("contextFile"), contextFile) : null); + + getLog().info(e.toDom().toUnescapedString()); + + return e; + } }