From carolyn93@example.net Tue May 01 08:38:50 2007 Return-Path: <carolyn93@example.net> Delivered-To: carolyn93@example.net Received: (qmail 37664 invoked from network); 1 May 2007 08:38:48 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 May 2007 08:38:48 -0000 Received: (qmail 73094 invoked by uid 500); 1 May 2007 08:38:54 -0000 Delivered-To: carolyn93@example.net Received: (qmail 73035 invoked by uid 500); 1 May 2007 08:38:53 -0000 Mailing-List: contact carolyn93@example.net; run by ezmlm Precedence: bulk Reply-To: carolyn93@example.net list-help: <mailto:carolyn93@example.net> list-unsubscribe: <mailto:carolyn93@example.net> List-Post: <mailto:carolyn93@example.net> List-Id: <cvs.cocoon.apache.org> Delivered-To: mailing list carolyn93@example.net Received: (qmail 73024 invoked by uid 99); 1 May 2007 08:38:53 -0000 Received: from herse.apache.org (HELO herse.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 May 2007 01:38:53 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 May 2007 01:38:46 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 7F0771A9838; Tue, 1 May 2007 01:38:26 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r533963 - /cocoon/trunk/core/cocoon-core/src/test/java/org/apache/cocoon/components/source/impl/CachingSourceTestCase.java Date: Tue, 01 May 2007 08:38:26 -0000 To: carolyn93@example.net From: carolyn93@example.net X-Mailer: svnmailer-1.1.0 Message-Id: <carolyn93@example.net> X-Virus-Checked: Checked by ClamAV on apache.org Author: reinhard Date: Tue May 1 01:38:25 2007 New Revision: 533963 URL: http://svn.apache.org/viewvc?view=rev&rev=533963 Log: with Eclipse this already worked when using an expiry time of 1 sec. Maven seems to fail sometimes. Hope that 2 secs improve the situation. Modified: cocoon/trunk/core/cocoon-core/src/test/java/org/apache/cocoon/components/source/impl/CachingSourceTestCase.java Modified: cocoon/trunk/core/cocoon-core/src/test/java/org/apache/cocoon/components/source/impl/CachingSourceTestCase.java URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/test/java/org/apache/cocoon/components/source/impl/CachingSourceTestCase.java?view=diff&rev=533963&r1=533962&r2=533963 ============================================================================== --- cocoon/trunk/core/cocoon-core/src/test/java/org/apache/cocoon/components/source/impl/CachingSourceTestCase.java (original) +++ cocoon/trunk/core/cocoon-core/src/test/java/org/apache/cocoon/components/source/impl/CachingSourceTestCase.java Tue May 1 01:38:25 2007 @@ -70,7 +70,7 @@ } public void testCachingURI() throws Exception { - String uri = "cached:http://slashdot.org/?cocoon:cache-expires=1"; + String uri = "cached:http://slashdot.org/?cocoon:cache-expires=2"; CachingSource source; @@ -93,7 +93,7 @@ // Source is still cached -- still same meta data assertSame(meta1, meta3); - Thread.sleep(1100); + Thread.sleep(2100); source = (CachingSource) resolver.resolveURI(uri); source.refresh(); From carolyn93@example.net Tue May 01 11:35:57 2007 Return-Path: <carolyn93@example.net> Delivered-To: carolyn93@example.net Received: (qmail 87918 invoked from network); 1 May 2007 11:35:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 May 2007 11:35:54 -0000 Received: (qmail 91630 invoked by uid 500); 1 May 2007 11:35:59 -0000 Delivered-To: carolyn93@example.net Received: (qmail 91563 invoked by uid 500); 1 May 2007 11:35:59 -0000 Mailing-List: contact carolyn93@example.net; run by ezmlm Precedence: bulk Reply-To: carolyn93@example.net list-help: <mailto:carolyn93@example.net> list-unsubscribe: <mailto:carolyn93@example.net> List-Post: <mailto:carolyn93@example.net> List-Id: <cvs.cocoon.apache.org> Delivered-To: mailing list carolyn93@example.net Received: (qmail 91506 invoked by uid 99); 1 May 2007 11:35:58 -0000 Received: from herse.apache.org (HELO herse.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 May 2007 04:35:58 -0700 X-ASF-Spam-Status: No, hits=-98.6 required=10.0 tests=ALL_TRUSTED,INFO_TLD,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 May 2007 04:35:49 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id D70861A9838; Tue, 1 May 2007 04:35:28 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r534014 [1/3] - in /cocoon/trunk/tools/cocoon-maven-plugin: ./ src/ src/changes/ src/main/java/org/apache/cocoon/maven/deployer/ src/main/java/org/apache/cocoon/maven/deployer/monolithic/ src/main/java/org/apache/cocoon/maven/deployer/servl... Date: Tue, 01 May 2007 11:35:27 -0000 To: carolyn93@example.net From: carolyn93@example.net X-Mailer: svnmailer-1.1.0 Message-Id: <carolyn93@example.net> X-Virus-Checked: Checked by ClamAV on apache.org Author: reinhard Date: Tue May 1 04:35:26 2007 New Revision: 534014 URL: http://svn.apache.org/viewvc?view=rev&rev=534014 Log: Merging deployer plugin and reloading classloader plugin Added: cocoon/trunk/tools/cocoon-maven-plugin/ - copied from r531008, cocoon/trunk/tools/cocoon-rcl/cocoon-rcl-plugin/ cocoon/trunk/tools/cocoon-maven-plugin/pom.xml - copied, changed from r533959, cocoon/trunk/tools/cocoon-rcl/cocoon-rcl-plugin/pom.xml cocoon/trunk/tools/cocoon-maven-plugin/src/ - copied from r533959, cocoon/trunk/tools/cocoon-rcl/cocoon-rcl-plugin/src/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployExplodedMojo.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployWarMojo.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/DeploymentException.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileAlreadyDeployedException.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileDeployer.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/MonolithicCocoonDeployer.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/RuleBasedZipExtractor.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/SingleFileDeployer.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/XPatchDeployer.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/CopyUtils.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/FileUtils.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WildcardHelper.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/XMLUtils.java (with props) cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/deployer/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/deployer/monolithic/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/deployer/monolithic/WEB-INF/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/deployer/monolithic/WEB-INF/cocoon/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/deployer/monolithic/WEB-INF/cocoon/properties/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/deployer/monolithic/blocks/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/deployer/utils/ cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/deployer/utils/web-app_2_3.dtd (with props) Modified: cocoon/trunk/tools/cocoon-maven-plugin/src/changes/changes.xml cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/ReloadingWebappMojo.java cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/RwmProperties.java cocoon/trunk/tools/cocoon-maven-plugin/src/main/resources/org/apache/cocoon/maven/rcl/WEB-INF/log4j.xml Copied: cocoon/trunk/tools/cocoon-maven-plugin/pom.xml (from r533959, cocoon/trunk/tools/cocoon-rcl/cocoon-rcl-plugin/pom.xml) URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/pom.xml?view=diff&rev=534014&p1=cocoon/trunk/tools/cocoon-rcl/cocoon-rcl-plugin/pom.xml&r1=533959&p2=cocoon/trunk/tools/cocoon-maven-plugin/pom.xml&r2=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-rcl/cocoon-rcl-plugin/pom.xml (original) +++ cocoon/trunk/tools/cocoon-maven-plugin/pom.xml Tue May 1 04:35:26 2007 @@ -20,73 +20,81 @@ <!--+ | @version $Id$ +--> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>cocoon-tools-modules</artifactId> <groupId>org.apache.cocoon</groupId> - <version>4-SNAPSHOT</version> - <relativePath>../../pom.xml</relativePath> + <version>4-SNAPSHOT</version> </parent> - <artifactId>cocoon-rcl-plugin</artifactId> + <artifactId>cocoon-maven-plugin</artifactId> <version>1.0.0-M1-SNAPSHOT</version> <packaging>maven-plugin</packaging> - <name>Cocoon Reloading Classloader - Maven 2 Plugin</name> + <name>Cocoon Maven 2 Plugin</name> <dependencies> <!-- utility libs --> <dependency> <groupId>antlr</groupId> <artifactId>stringtemplate</artifactId> - </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - </dependency> <dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> - </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> - </dependency> <!-- Maven specific --> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> - </dependency> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-artifact</artifactId> - </dependency> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-model</artifactId> - </dependency> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-artifact</artifactId> - </dependency> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-project</artifactId> - </dependency> + <dependency> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + </dependency> + <!-- Xalan neccessary for XPath operations --> + <dependency> + <groupId>xalan</groupId> + <artifactId>xalan</artifactId> + </dependency> + <dependency> + <groupId>xml-apis</groupId> + <artifactId>xml-apis</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <scope>compile</scope> + </dependency> <!-- test libs --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <scope>test</scope> </dependency> </dependencies> @@ -96,7 +104,7 @@ <plugin> <artifactId>maven-plugin-plugin</artifactId> <configuration> - <goalPrefix>cocoon-rcl</goalPrefix> + <goalPrefix>cocoon</goalPrefix> </configuration> </plugin> <plugin> @@ -132,4 +140,4 @@ </site> </distributionManagement> -</project> +</project> \ No newline at end of file Modified: cocoon/trunk/tools/cocoon-maven-plugin/src/changes/changes.xml URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/changes/changes.xml?view=diff&rev=534014&r1=533959&r2=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/changes/changes.xml (original) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/changes/changes.xml Tue May 1 04:35:26 2007 @@ -31,4 +31,4 @@ </release> </body> </document> - \ No newline at end of file + Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java Tue May 1 04:35:26 2007 @@ -0,0 +1,278 @@ +/* + * 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.cocoon.maven.deployer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.cocoon.maven.deployer.monolithic.DeploymentException; +import org.apache.cocoon.maven.deployer.monolithic.RuleBasedZipExtractor; +import org.apache.cocoon.maven.deployer.monolithic.XPatchDeployer; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.SystemUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactResolver; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugin.war.AbstractWarMojo; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.artifact.MavenMetadataSource; + +/** + * Create a Cocoon web application based on a block deployment descriptor. + * + * @version $Id$ + */ +public abstract class AbstractDeployMojo extends AbstractWarMojo { + + /** + * Artifact factory, needed to download source jars for inclusion in + * classpath. + * + * @component role="org.apache.maven.artifact.factory.ArtifactFactory" + * @required + * @readonly + */ + private ArtifactFactory artifactFactory; + + /** + * Artifact resolver, needed to download source jars for inclusion in + * classpath. + * + * @component role="org.apache.maven.artifact.resolver.ArtifactResolver" + * @required + * @readonly + */ + private ArtifactResolver artifactResolver; + + /** + * Artifact resolver, needed to download source jars for inclusion in + * classpath. + * + * @component role="org.apache.maven.artifact.metadata.ArtifactMetadataSource" + * @required + * @readonly + */ + private MavenMetadataSource metadataSource; + + /** + * Local maven repository. + * + * @parameter expression="${localRepository}" + * @required + * @readonly + */ + private ArtifactRepository localRepository; + + /** + * Remote repositories which will be searched for blocks. + * + * @parameter expression="${project.remoteArtifactRepositories}" + * @required + * @readonly + */ + private List remoteArtifactRepositories; + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // set properties: necessary because DeployMojo is not in the same package + // as AbstractWarMojo + + /** + * The project whose project files to create. + * + * @parameter expression="${project}" + * @required + */ + private MavenProject project; + + /** + * The directory containing generated classes. + * + * @parameter expression="${project.build.outputDirectory}" + * @required + * @readonly + */ + private File classesDirectory; + + /** + * The directory where the webapp is built. + * + * @parameter expression="${project.build.directory}/${project.build.finalName}" + * @required + */ + private File webappDirectory; + + /** + * Single directory for extra files to include in the WAR. + * + * @parameter expression="${basedir}/src/main/webapp" + * @required + */ + private File warSourceDirectory; + + /** + * The path to the web.xml file to use. + * + * @parameter expression="${maven.war.webxml}" + */ + private String webXml; + + /** + * Use shielded classloading + * + * @parameter expression="${maven.war.shieldingclassloader}" + */ + private boolean useShieldingClassLoader = false; + + /** + * Move jars for shielded classloading + * + * @parameter expression="${maven.war.shieldingrepository}" + */ + private boolean useShieldingRepository = false; + + + /** + * Deploy a monolithic Cocoon web application. This means it doesn't use the + * features that the blocks-fw offers. + */ + protected void deployWebapp() throws MojoExecutionException, MojoFailureException { + + this.buildExplodedWebapp(getWebappDirectory()); + + try { + super.copyResources(getWarSourceDirectory(), getWebappDirectory()); + } catch (IOException e) { + throw new MojoExecutionException("A problem occurred while copying webapp resources.", e); + } + + xpatch(getBlockArtifactsAsMap(this.getProject(), this.getLog()), new File[0], getWebappDirectory(), this.getLog()); + + // take care of shielded classloading + if (this.useShieldingClassLoader) { + WebApplicationRewriter.shieldWebapp(new File(getWebappDirectory(), "WEB-INF"), getLog(), this.useShieldingRepository); + } + } + + public static void xpatch(final Map libraries, File[] xpatchFiles, final File basedir, Log log) throws DeploymentException { + XPatchDeployer xwebPatcher = new XPatchDeployer("WEB-INF"); + xwebPatcher.setBasedir(basedir); + xwebPatcher.setLogger(log); + // iterate over all blocks that need to be installed into a J2EE web + // application + for (Iterator it = libraries.entrySet().iterator(); it.hasNext();) { + final Map.Entry entry = (Map.Entry) it.next(); + final Object id = entry.getKey(); + File lib = (File) entry.getValue(); + try { + log.debug("Scanning " + id); + RuleBasedZipExtractor zipExtractor = new RuleBasedZipExtractor(basedir, log); + // add the matching/execution rules + zipExtractor.addRule("META-INF/cocoon/xpatch/*.xweb", xwebPatcher); + // extract all configurations files + zipExtractor.extract(lib); + } catch (IOException e) { + throw new DeploymentException("Can't deploy '" + lib.getAbsolutePath() + "'.", e); + } + } + + for (int i = 0; i < xpatchFiles.length; i++ ) { + File patch = xpatchFiles[i]; + try { + xwebPatcher.addPatch(patch); + log.info("Adding xpatch: " + patch); + } catch (IOException e) { + throw new DeploymentException("Can't use patches '" + patch + "'.", e); + } + } + + InputStream sourceWebXmlFile = null; + File webXml = new File(basedir, "WEB-INF/web.xml"); + System.out.println("webXml.getAbsolutePath=" + webXml.getAbsolutePath()); + try { + sourceWebXmlFile = new FileInputStream(webXml); + xwebPatcher.applyPatches(sourceWebXmlFile, "WEB-INF/web.xml"); + } catch (FileNotFoundException e) { + throw new DeploymentException("Can't apply patches on " + webXml + ".", e); + } finally { + IOUtils.closeQuietly(sourceWebXmlFile); + } + + } + + /** + * Create a <code>Map</code> of <code>java.io.File</code> objects + * pointing to artifacts. + */ + public static Map getBlockArtifactsAsMap(MavenProject project, Log log) throws MojoExecutionException { + Map files = new HashMap(); + for (Iterator it = project.getArtifacts().iterator(); it.hasNext();) { + Artifact artifact = (Artifact) it.next(); + String id = artifact.getArtifactId(); + if (files.containsKey(id)) { + // Now search for all artifacts and print their dependency trail + StringBuffer msg = new StringBuffer("There are at least two artifacts with the ID '"); + msg.append(id); + msg.append("':"); + msg.append(SystemUtils.LINE_SEPARATOR); + for (Iterator ai = project.getArtifacts().iterator(); ai.hasNext();) { + final Artifact current = (Artifact) ai.next(); + if (current.getArtifactId().equals(id)) { + msg.append(artifact); + msg.append(SystemUtils.LINE_SEPARATOR); + final List l = current.getDependencyTrail(); + final Iterator i = l.iterator(); + while (i.hasNext()) { + msg.append(" "); + msg.append(i.next().toString()); + msg.append(SystemUtils.LINE_SEPARATOR); + } + } + } + throw new MojoExecutionException(msg.toString()); + } + + + files.put(id, artifact.getFile()); + if (log.isDebugEnabled()) { + StringBuffer msg = new StringBuffer("Deploying " + artifact); + final List l = artifact.getDependencyTrail(); + final Iterator i = l.iterator(); + while (i.hasNext()) { + msg.append(" "); + msg.append(i.next().toString()); + msg.append(SystemUtils.LINE_SEPARATOR); + } + log.debug(msg.toString()); + } + + } + return files; + } +} Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployExplodedMojo.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployExplodedMojo.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployExplodedMojo.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployExplodedMojo.java Tue May 1 04:35:26 2007 @@ -0,0 +1,45 @@ +/* + * 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.cocoon.maven.deployer; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +/** + * Create a web application that makes use of Cocoon blocks. In the case of a + * web application module, (packaging: war) all referenced blocks are added, in + * the case of block (packaging: jar) additionally a minimal Cocoon environemt + * is created and it is also possible to reference <i>other</i> locally + * available blocks and to set custom properties to make development highly + * dynamic. + * + * @goal deploy + * @requiresProject true + * @phase package + * @requiresDependencyResolution runtime + */ +public class DeployExplodedMojo extends AbstractDeployMojo { + + public void execute() throws MojoExecutionException, MojoFailureException { + if (this.getProject().getPackaging().equals("war")) { + this.deployWebapp(); + } else { + throw new MojoExecutionException("This goal requires a project of packaging type 'war'."); + } + } + +} \ No newline at end of file Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployExplodedMojo.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployExplodedMojo.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployExplodedMojo.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployWarMojo.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployWarMojo.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployWarMojo.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployWarMojo.java Tue May 1 04:35:26 2007 @@ -0,0 +1,111 @@ +/* + * 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.cocoon.maven.deployer; + +import java.io.File; +import java.io.IOException; + +import org.apache.maven.archiver.MavenArchiveConfiguration; +import org.apache.maven.archiver.MavenArchiver; +import org.apache.maven.artifact.DependencyResolutionRequiredException; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.codehaus.plexus.archiver.ArchiverException; +import org.codehaus.plexus.archiver.jar.ManifestException; +import org.codehaus.plexus.archiver.war.WarArchiver; + +/** + * Create a packaged Cocoon web application (.war file) based on a block + * deployment descriptor. + * + * @goal deploy-war + * @requiresProject true + * @phase package + * @description Create a packaged Cocoon web application (.war file) based on a + * block deployment descriptor. + */ +public class DeployWarMojo extends AbstractDeployMojo { + + /** + * The directory for the generated WAR. + * + * @parameter expression="${project.build.directory}" + * @required + */ + private String outputDirectory; + + /** + * The name of the generated war. + * + * @parameter expression="${project.build.finalName}" + * @required + */ + private String warName; + + /** + * The Jar archiver. + * + * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#war}" + * @required + */ + private WarArchiver warArchiver; + + /** + * The maven archive configuration to use. + * + * @parameter + */ + private MavenArchiveConfiguration archive = new MavenArchiveConfiguration(); + + public void execute() throws MojoExecutionException, MojoFailureException { + File warFile = new File(outputDirectory, warName + ".war"); + this.deployWebapp(); + + try { + performPackaging(warFile); + } catch (Exception e) { + // TODO: improve error handling + throw new MojoExecutionException("Error assembling WAR", e); + } + } + + /** + * Generates the webapp according to the <tt>mode</tt> attribute. + * + * @param warFile + * the target war file + * @throws IOException + * @throws ArchiverException + * @throws ManifestException + * @throws DependencyResolutionRequiredException + */ + private void performPackaging(File warFile) throws IOException, ArchiverException, ManifestException, + DependencyResolutionRequiredException, MojoExecutionException { + getLog().info("Generating war " + warFile.getAbsolutePath()); + + MavenArchiver archiver = new MavenArchiver(); + archiver.setArchiver(warArchiver); + archiver.setOutputFile(warFile); + warArchiver.addDirectory(getWebappDirectory(), getIncludes(), getExcludes()); + warArchiver.setWebxml(new File(getWebappDirectory(), "WEB-INF/web.xml")); + + // create archive + archiver.createArchive(getProject(), archive); + getProject().getArtifact().setFile(warFile); + } + +} \ No newline at end of file Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployWarMojo.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployWarMojo.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/DeployWarMojo.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java Tue May 1 04:35:26 2007 @@ -0,0 +1,348 @@ +/* + * 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.cocoon.maven.deployer; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.JarURLConnection; +import java.net.URL; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; + +import org.apache.cocoon.maven.deployer.servlet.ShieldedClassLoaderManager; +import org.apache.cocoon.maven.deployer.servlet.ShieldingListener; +import org.apache.cocoon.maven.deployer.servlet.ShieldingServlet; +import org.apache.cocoon.maven.deployer.servlet.ShieldingServletFilter; +import org.apache.cocoon.maven.deployer.utils.XMLUtils; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.IOUtil; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * @version $Id$ + */ +public class WebApplicationRewriter { + + protected static final String SERVLET_CLASS = ShieldingServlet.class.getName(); + + protected static final String LISTENER_CLASS = ShieldingListener.class.getName(); + + protected static final String FILTER_CLASS = ShieldingServletFilter.class.getName(); + + protected static final String CLASSLOADER_JAR = "cocoon-deployer-plugin-classloading.jar"; + + protected static final String JAR_ENTRY_PREFIX = ShieldedClassLoaderManager.class.getPackage().getName().replace('.', '/'); + + /** + * Prepare the web application to use the shielded class loader. + * The web.xml will be rewritten: all servlets, filters etc. are wrapped + * by a wrapper which uses the shielded class loader. + * In addition all libs are moved from WEB-INF/lib to WEB-INF/shielded/lib + * and all files from WEB-INF/classes are moved to WEB-INF/shielded/classes. + */ + public static void shieldWebapp(File webInfDir, Log log, boolean useShieldingRepository) + throws MojoExecutionException { + if ( log.isDebugEnabled() ) { + log.debug("Shielding web application in " + webInfDir); + } + final String webInfSlashWebXml = webInfDir.getPath() + File.separatorChar + "web.xml"; + + if (!new File(webInfSlashWebXml).exists()) { + throw new MojoExecutionException("No web.xml present - can't add shielded class loading"); + } + log.info("Adding shielded classloader configuration to web application configuration."); + if ( log.isDebugEnabled() ) { + log.debug("Reading web.xml: " + webInfSlashWebXml); + } + + // load web.xml + InputStream is = null; + final Document webAppDoc; + try { + is = new BufferedInputStream(new FileInputStream(new File(webInfSlashWebXml))); + webAppDoc = XMLUtils.parseXml(is); + } catch (Exception e) { + throw new MojoExecutionException("Unable to read web.xml from " + webInfSlashWebXml, e); + } finally { + if ( is != null ) { + try { + is.close(); + } catch (IOException ignore) { + // ignore + } + } + } + + // rewrite + if ( WebApplicationRewriter.rewrite(webAppDoc, useShieldingRepository) ) { + + // save web.xml + try { + if ( log.isDebugEnabled() ) { + log.debug("Writing web.xml: " + webInfSlashWebXml); + } + XMLUtils.write(webAppDoc, new FileOutputStream(webInfSlashWebXml)); + } catch (Exception e) { + throw new MojoExecutionException("Unable to write web.xml to " + webInfSlashWebXml, e); + } + } + + // move classes and libs + if (useShieldingRepository) { + log.info("Moving classes and libs to shielded location."); + try { + move(webInfDir, "lib", ShieldedClassLoaderManager.WEB_INF_SHIELDED_LIB, log); + move(webInfDir, "classes", ShieldedClassLoaderManager.WEB_INF_SHIELDED_CLASSES, log); + } catch (IOException e) { + throw new MojoExecutionException("unable to shield classes/libs", e); + } + } + + // add classloading stuff to WEB-INF/lib + // let's search our jar + final String rsrc = ShieldedClassLoaderManager.class.getName().replace('.', '/') + ".class"; + if ( log.isDebugEnabled() ) { + log.debug("Searching class file for: " + rsrc); + } + try { + final Enumeration e = WebApplicationRewriter.class.getClassLoader().getResources(rsrc); + boolean found = false; + while ( e.hasMoreElements() ) { + final URL url = (URL)e.nextElement(); + if ( log.isDebugEnabled() ) { + log.debug("Found class in " + url); + } + if ( url.getProtocol().equals("jar")) { + String jarUrlString = url.toExternalForm(); + int pos = jarUrlString.indexOf('!'); + // include !/ + jarUrlString = jarUrlString.substring(0, pos + 2); + final URL jarUrl = new URL(jarUrlString); + final JarURLConnection connection = (JarURLConnection)jarUrl.openConnection(); + final JarFile jarFile = connection.getJarFile(); + final File destFile = new File(webInfDir, "lib" + File.separator + CLASSLOADER_JAR); + final JarOutputStream jos = new JarOutputStream(new FileOutputStream(destFile)); + final Enumeration entries = jarFile.entries(); + while ( entries.hasMoreElements() ) { + final JarEntry current = (JarEntry)entries.nextElement(); + // only include classes from the shielded class loader package + if ( current.getName().startsWith(JAR_ENTRY_PREFIX) ) { + jos.putNextEntry(current); + IOUtil.copy(jarFile.getInputStream(current), jos); + jos.closeEntry(); + } + } + jos.close(); + found = true; + } + } + if (!found) { + throw new MojoExecutionException("Unable to find jar file for shielded class loading classes."); + } + } catch (IOException ioe) { + throw new MojoExecutionException("unable to find classes for shielded class loading.", ioe); + } + } + + private static void move(File parentDir, String srcDir, String destDirOrig, Log log) throws IOException { + String destDir = destDirOrig; + // use correct separators on windows + if ( File.separatorChar != '/' ) { + destDir = destDir.replace('/', File.separatorChar); + } + final File srcDirectory = new File(parentDir, srcDir); + if (srcDirectory.exists() && srcDirectory.isDirectory()) { + File destDirectory = new File(parentDir, destDir); + if (log.isDebugEnabled()) { + log.debug("Deleting directory " + destDirectory); + } + FileUtils.deleteDirectory(destDirectory); + destDirectory = new File(parentDir, destDir); + if (log.isDebugEnabled()) { + log.debug("Recreating directory " + destDirectory); + } + destDirectory.mkdirs(); + final File[] files = srcDirectory.listFiles(); + if (files != null && files.length > 0) { + for (int i = 0; i < files.length; i++) { + // move everything but our own jar + if ( !files[i].getName().equals(CLASSLOADER_JAR) ) { + if (log.isDebugEnabled()) { + log.debug("Moving " + files[i] + " to " + destDirectory); + } + files[i].renameTo(new File(destDirectory, files[i].getName())); + } + } + } + } + } + + public static boolean rewrite(Document webAppDoc, boolean useShieldingRepository) { + boolean rewritten = false; + final Element rootElement = webAppDoc.getDocumentElement(); + // first rewrite servlets + final List servlets = XMLUtils.getChildNodes(rootElement, "servlet"); + Iterator i = servlets.iterator(); + while ( i.hasNext() ) { + final Element servletElement = (Element)i.next(); + final Element servletClassElement = XMLUtils.getChildNode(servletElement, "servlet-class"); + if ( servletClassElement != null ) { + final String className = XMLUtils.getValue(servletClassElement); + XMLUtils.setValue(servletClassElement, SERVLET_CLASS); + // create init-param with real servlet class + final Element initParamElem = webAppDoc.createElementNS(null, "init-param"); + final Element initParamNameElem = webAppDoc.createElementNS(null, "param-name"); + final Element initParamValueElem = webAppDoc.createElementNS(null, "param-value"); + initParamElem.appendChild(initParamNameElem); + initParamElem.appendChild(initParamValueElem); + XMLUtils.setValue(initParamNameElem, "servlet-class"); + XMLUtils.setValue(initParamValueElem, className); + Element beforeElement = XMLUtils.getChildNode(servletElement, "load-on-startup"); + if ( beforeElement == null ) { + beforeElement = XMLUtils.getChildNode(servletElement, "run-as"); + if ( beforeElement == null ) { + beforeElement = XMLUtils.getChildNode(servletElement, "security-role-ref"); + } + } + if ( beforeElement == null ) { + servletElement.appendChild(initParamElem); + } else { + servletElement.insertBefore(initParamElem, beforeElement); + } + rewritten = true; + } + } + + // now rewrite listeners + final List listeners = XMLUtils.getChildNodes(rootElement, "listener"); + i = listeners.iterator(); + boolean hasListener = false; + final StringBuffer rewrittenListeners = new StringBuffer(); + while ( i.hasNext() ) { + final Element listenerElement = (Element)i.next(); + final Element listenerClassElement = XMLUtils.getChildNode(listenerElement, "listener-class"); + if ( listenerClassElement != null ) { + final String className = XMLUtils.getValue(listenerClassElement); + if ( rewrittenListeners.length() > 0 ) { + rewrittenListeners.append(','); + } + rewrittenListeners.append(className); + if ( hasListener ) { + rootElement.removeChild(listenerElement); + } else { + XMLUtils.setValue(listenerClassElement, LISTENER_CLASS); + hasListener = true; + } + rewritten = true; + } + } + // remove old parameter + i = XMLUtils.getChildNodes(rootElement, "context-param").iterator(); + while ( i.hasNext() ) { + final Element child = (Element)i.next(); + if ( LISTENER_CLASS.equals(XMLUtils.getValue(XMLUtils.getChildNode(child, "param-name")))) { + rootElement.removeChild(child); + } + } + if ( hasListener ) { + addContextParameter(rootElement, LISTENER_CLASS, rewrittenListeners.toString()); + } + + // and now filters + i = XMLUtils.getChildNodes(rootElement, "filter").iterator(); + while ( i.hasNext() ) { + final Element filterElement = (Element)i.next(); + final Element filterClassElement = XMLUtils.getChildNode(filterElement, "filter-class"); + if ( filterClassElement != null ) { + final String className = XMLUtils.getValue(filterClassElement); + XMLUtils.setValue(filterClassElement, FILTER_CLASS); + // create init-param with real servlet class + final Element initParamElem = webAppDoc.createElementNS(null, "init-param"); + final Element initParamNameElem = webAppDoc.createElementNS(null, "param-name"); + final Element initParamValueElem = webAppDoc.createElementNS(null, "param-value"); + initParamElem.appendChild(initParamNameElem); + initParamElem.appendChild(initParamValueElem); + XMLUtils.setValue(initParamNameElem, "filter-class"); + XMLUtils.setValue(initParamValueElem, className); + filterElement.appendChild(initParamElem); + rewritten = true; + } + } + + if ( !useShieldingRepository ) { + addContextParameter(rootElement, + ShieldedClassLoaderManager.SHIELDED_CLASSLOADER_USE_REPOSITORY, + "false"); + rewritten = true; + } else { + if ( removeContextParameter(rootElement, ShieldedClassLoaderManager.SHIELDED_CLASSLOADER_USE_REPOSITORY) ) { + rewritten = true; + } + } + + return rewritten; + } + + protected static boolean removeContextParameter(Element root, String name) { + boolean removed = false; + final Iterator i = XMLUtils.getChildNodes(root, "context-param").iterator(); + while ( !removed && i.hasNext() ) { + final Element parameterElement = (Element)i.next(); + final String paramName = XMLUtils.getValue(XMLUtils.getChildNode(parameterElement, "param-name")); + if ( name.equals(paramName) ) { + parameterElement.getParentNode().removeChild(parameterElement); + removed = true; + } + } + return removed; + } + + protected static void addContextParameter(Element root, String name, String value) { + removeContextParameter(root, name); + // search the element where we have to put the new context parameter before! + // we know that we have listeners so this is the last element to search for + Element searchElement = XMLUtils.getChildNode(root, "context-param"); + if ( searchElement == null ) { + searchElement = XMLUtils.getChildNode(root, "filter"); + if ( searchElement == null ) { + searchElement = XMLUtils.getChildNode(root, "filter-mapping"); + if ( searchElement == null ) { + searchElement = XMLUtils.getChildNode(root, "listener"); + } + } + } + final Element contextParamElement = root.getOwnerDocument().createElementNS(null, "context-param"); + final Element contextParamNameElement = root.getOwnerDocument().createElementNS(null, "param-name"); + final Element contextParamValueElement = root.getOwnerDocument().createElementNS(null, "param-value"); + contextParamElement.appendChild(contextParamNameElement); + contextParamElement.appendChild(contextParamValueElement); + XMLUtils.setValue(contextParamNameElement, name); + XMLUtils.setValue(contextParamValueElement, value); + root.insertBefore(contextParamElement, searchElement); + } +} \ No newline at end of file Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/DeploymentException.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/DeploymentException.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/DeploymentException.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/DeploymentException.java Tue May 1 04:35:26 2007 @@ -0,0 +1,33 @@ +/* + * 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.cocoon.maven.deployer.monolithic; + + +/** + * Unchecked exception that signals a problem at block deployment. + */ +public class DeploymentException extends RuntimeException { + + public DeploymentException(String message) { + super(message); + } + + public DeploymentException(String message, Exception ex) { + super(message, ex); + } + +} Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/DeploymentException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/DeploymentException.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/DeploymentException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileAlreadyDeployedException.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileAlreadyDeployedException.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileAlreadyDeployedException.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileAlreadyDeployedException.java Tue May 1 04:35:26 2007 @@ -0,0 +1,30 @@ +/* + * 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.cocoon.maven.deployer.monolithic; + +/** + * Use it to indicate that a file has already been deployed. + * + * @version $Id$ + */ +public class FileAlreadyDeployedException extends DeploymentException { + + public FileAlreadyDeployedException(String message) { + super(message); + } + +} Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileAlreadyDeployedException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileAlreadyDeployedException.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileAlreadyDeployedException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileDeployer.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileDeployer.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileDeployer.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileDeployer.java Tue May 1 04:35:26 2007 @@ -0,0 +1,44 @@ +/* + * 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.cocoon.maven.deployer.monolithic; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Set; + +import org.apache.maven.plugin.logging.Log; + +/** + * Use this interface for classes that are used by the @link org.apache.cocoon.maven.deployer.monolithic.ZipExtractor + * to extract ZIP files. Classes implementing this interface can be added together with a rule to the + * @link org.apache.cocoon.maven.deployer.monolithic.ZipExtractor and when the rule matches, the execute method + * is called. + * + * @version $Id$ + */ +public interface FileDeployer { + + OutputStream writeResource(String documentName) throws IOException; + + void setBasedir(File file); + + void setLogger(Log logger); + + void setAlreadyDeployedFilesSet(Set alreadyDeployedFilesSet); + +} Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileDeployer.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileDeployer.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/FileDeployer.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/MonolithicCocoonDeployer.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/MonolithicCocoonDeployer.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/MonolithicCocoonDeployer.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/MonolithicCocoonDeployer.java Tue May 1 04:35:26 2007 @@ -0,0 +1,85 @@ +/* + * 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.cocoon.maven.deployer.monolithic; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.Map; + +import org.apache.commons.io.IOUtils; +import org.apache.maven.plugin.logging.Log; + +/** + * Deploy blocks to a monolithic Cocoon web application. The files contained by + * a block are copied based on rules to the right places. + * + * @version $Id: MonolithicCocoonDeployer.java 438198 2006-08-29 20:38:09Z + * lgawron $ + */ +public class MonolithicCocoonDeployer { + + private Log logger; + + public MonolithicCocoonDeployer(Log logger) { + this.logger = logger; + } + + public void deploy(final Map libraries, final File basedir) throws DeploymentException { + XPatchDeployer xwebPatcher = new XPatchDeployer("WEB-INF"); + xwebPatcher.setLogger(logger); + // iterate over all blocks that need to be installed into a J2EE web + // application + for (Iterator it = libraries.entrySet().iterator(); it.hasNext();) { + final Map.Entry entry = (Map.Entry) it.next(); + final Object id = entry.getKey(); + File lib = (File) entry.getValue(); + try { + this.logger.info("Deploying " + id); + RuleBasedZipExtractor zipExtractor = new RuleBasedZipExtractor(basedir, logger); + + // TODO clearly a hack, there should be a parameter what part of + // source path should be removed, the rest should stay + // preserving directory structure (currently only filename + // stays) + zipExtractor.addRule("WEB-INF/db/**", new SingleFileDeployer("WEB-INF/db")); + zipExtractor.addRule("META-INF/xpatch/*.xweb", xwebPatcher); + + // extract all configurations files + zipExtractor.extract(lib); + } catch (IOException e) { + throw new DeploymentException("Can't deploy '" + lib.getAbsolutePath() + "'.", e); + } + } + + InputStream sourceWebXmlFile = null; + File webXml = new File(basedir, "WEB-INF/web.xml"); + try { + sourceWebXmlFile = new FileInputStream(webXml); + xwebPatcher.applyPatches(sourceWebXmlFile, "WEB-INF/web.xml"); + } catch (FileNotFoundException e) { + throw new DeploymentException("Can't apply patches on " + webXml + ".", e); + } finally { + IOUtils.closeQuietly(sourceWebXmlFile); + } + + } + +} Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/MonolithicCocoonDeployer.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/MonolithicCocoonDeployer.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/MonolithicCocoonDeployer.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/RuleBasedZipExtractor.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/RuleBasedZipExtractor.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/RuleBasedZipExtractor.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/RuleBasedZipExtractor.java Tue May 1 04:35:26 2007 @@ -0,0 +1,130 @@ +/* + * 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.cocoon.maven.deployer.monolithic; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.apache.cocoon.maven.deployer.utils.WildcardHelper; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.Validate; +import org.apache.maven.plugin.logging.Log; + +/** + * This class performs the actual deployment based on rules. A rule is mapped to + * a <code>FileDeployer</code> and when the rule is executed and returns true, + * the file deployer is executed. + * + * @version $Id$ + */ +public class RuleBasedZipExtractor { + private Log logger; + private File basedir; + private List rules = new ArrayList(); + private Set alreadyDeployedFilesSet = new HashSet(); + + public RuleBasedZipExtractor(File basedir, Log logger) { + Validate.notNull(basedir, "The basedir of the server mustn't be null."); + Validate.notNull(logger, "A logger must be set."); + this.basedir = basedir; + this.logger = logger; + this.logger.debug("Basedir: " + basedir.getAbsolutePath()); + } + + public void addRule(String pattern, FileDeployer fileDeployer) { + fileDeployer.setBasedir(this.basedir); + fileDeployer.setLogger(this.logger); + fileDeployer.setAlreadyDeployedFilesSet(alreadyDeployedFilesSet); + rules.add(new Rule(pattern, fileDeployer)); + } + + public void extract(File zipFile) throws IOException { + ZipInputStream zipStream = new ZipInputStream(new FileInputStream(zipFile)); + ZipEntry document = null; + try { + do { + document = zipStream.getNextEntry(); + if (document != null) { + // skip directories (only files have to be written) + if (document.isDirectory()) { + zipStream.closeEntry(); + continue; + } + OutputStream out = null; + try { + FileDeployer fileDeployer = findFileDeployer(document.getName()); + if (fileDeployer == null) { + continue; + } + + out = new BufferedOutputStream(fileDeployer.writeResource(document.getName())); + IOUtils.copy(zipStream, out); + } finally { + if (out != null) { + out.close(); + } + } + // go to next entry + zipStream.closeEntry(); + } + } while (document != null); + } finally { + zipStream.close(); + } + } + + /** + * Loop over all rules and if one matches, the corresponding + * + * @link FileDeployer is returned. + */ + protected FileDeployer findFileDeployer(String name) { + for (Iterator it = this.rules.iterator(); it.hasNext();) { + Rule rule = (Rule) it.next(); + HashMap resultMap = new HashMap(); + if (WildcardHelper.match(resultMap, name, rule.compiledPattern)) { + logger.debug("findFileDeployer: " + name + " matched with pattern '" + rule.patternString); + return rule.fileDeployer; + } + } + return null; + } + + private static class Rule { + String patternString; + int[] compiledPattern; + FileDeployer fileDeployer; + + public Rule(String pattern, FileDeployer fileDeployer) { + this.patternString = pattern; + this.compiledPattern = WildcardHelper.compilePattern(pattern); + this.fileDeployer = fileDeployer; + } + } + +} Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/RuleBasedZipExtractor.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/RuleBasedZipExtractor.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/RuleBasedZipExtractor.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/SingleFileDeployer.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/SingleFileDeployer.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/SingleFileDeployer.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/SingleFileDeployer.java Tue May 1 04:35:26 2007 @@ -0,0 +1,112 @@ +/* + * 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.cocoon.maven.deployer.monolithic; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Set; + +import org.apache.cocoon.maven.deployer.utils.FileUtils; +import org.apache.commons.lang.Validate; +import org.apache.maven.plugin.logging.Log; + +/** + * Deploy a single file. + * + * @version $Id$ + */ +public class SingleFileDeployer implements FileDeployer { + private File basedir; + private Log logger; + private String outputDir; + private boolean skipRootDirectory; + private Set alreadyDeployedFilesSet; + + public SingleFileDeployer(final String outputDir, final boolean skipRootDirectory) { + Validate.notNull(outputDir, "An outputDir has to be set."); + this.outputDir = outputDir; + this.skipRootDirectory = skipRootDirectory; + } + + public SingleFileDeployer(final String outputDir) { + this(outputDir, false); + } + + public void setBasedir(final File basedir) { + this.basedir = basedir; + } + + protected File getBasedir() { + return this.basedir; + } + + public void setLogger(final Log logger) { + this.logger = logger; + } + + protected Log getLogger() { + return this.logger; + } + + public void setAlreadyDeployedFilesSet(Set alreadyDeployedFilesSet) { + this.alreadyDeployedFilesSet = alreadyDeployedFilesSet; + } + + protected String getFileName(final String documentName) { + return documentName.substring(documentName.lastIndexOf('/') + 1); + } + + protected String getOutputDir() { + return this.outputDir; + } + + public OutputStream writeResource(final String documentName) throws IOException { + File outDir = new File(this.getBasedir(), getOutputDir()); + if (!outDir.exists()) { + outDir.mkdirs(); + } + + String outputDocumentName = documentName; + // if the root directory is has to be skipped, the remaining path will + // be used + if (this.skipRootDirectory) { + outputDocumentName = removeRootDirectory(documentName); + this.logger.debug("Changing output document name from '" + documentName + "', to '" + outputDocumentName + + "'."); + } + // only take the filename + else { + outputDocumentName = this.getFileName(documentName); + } + + File targetFile = FileUtils.createPath(new File(outDir, outputDocumentName)); + if (this.alreadyDeployedFilesSet.contains(targetFile.getCanonicalFile())) { + throw new FileAlreadyDeployedException("File '" + targetFile + "' already exists!"); + } + + this.alreadyDeployedFilesSet.add(targetFile.getCanonicalFile()); + this.logger.debug("Deploying block resource to " + getOutputDir() + "/" + outputDocumentName); + + return new FileOutputStream(FileUtils.createPath(targetFile)); + } + + protected String removeRootDirectory(final String documentName) { + return documentName.substring(documentName.indexOf('/') + 1); + } +} Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/SingleFileDeployer.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/SingleFileDeployer.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/SingleFileDeployer.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/XPatchDeployer.java URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/XPatchDeployer.java?view=auto&rev=534014 ============================================================================== --- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/XPatchDeployer.java (added) +++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/XPatchDeployer.java Tue May 1 04:35:26 2007 @@ -0,0 +1,232 @@ +/* + * 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.cocoon.maven.deployer.monolithic; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.cocoon.maven.deployer.utils.CopyUtils; +import org.apache.cocoon.maven.deployer.utils.FileUtils; +import org.apache.cocoon.maven.deployer.utils.XMLUtils; +import org.apache.commons.io.IOUtils; +import org.apache.xpath.XPathAPI; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +// TODO should this extend SingleFileDeployer at all? +// TODO decouple patch collecting from logic that applies patches +public class XPatchDeployer extends SingleFileDeployer { + final List patches = new Vector(); + + public XPatchDeployer(String outputDir) { + super(outputDir, false); + } + + public OutputStream writeResource(String documentName) throws IOException { + getLogger().debug("catching patch: " + documentName); + PatchCachingOutputStream out = new PatchCachingOutputStream(documentName); + patches.add(out); + return out; + } + + public void addPatch(File file) throws IOException { + getLogger().debug("catching patch: " + file.getAbsolutePath()); + PatchCachingOutputStream pcis = new PatchCachingOutputStream(file.getCanonicalPath()); + CopyUtils.copy(new FileInputStream(file), pcis); + patches.add(pcis); + } + + public void applyPatches(InputStream source, final String fileName) { + if (patches.size() == 0) { + // TODO should just copy the file without any transform + } + try { + getLogger().info("Applying patches to: " + fileName); + Document original = XMLUtils.parseXml(source); + File outFile = FileUtils.createPath(new File(getBasedir(), fileName)); + + Iterator it = patches.iterator(); + while (it.hasNext()) { + PatchCachingOutputStream pcis = (PatchCachingOutputStream) it.next(); + Document component = (pcis).getPatch(); + + Element elem = component.getDocumentElement(); + if (!elem.getTagName().equals("xweb")) { + throw new DeploymentException("not a valid xweb patch file: " + pcis.getDocumentName()); + } + + String xpath = elem.getAttribute("xpath"); + if (xpath == null) { + throw new DeploymentException("no xpath parameter in patch file: " + pcis.getDocumentName()); + } + + NodeList nodes = XPathAPI.selectNodeList(original, xpath); + + if (nodes.getLength() == 0) { + throw new DeploymentException("no matches for xpath: [" + xpath + "] in patch file: " + + pcis.getDocumentName()); + } + if (nodes.getLength() > 1) { + throw new DeploymentException("multiple matches for xpath: [" + xpath + "] in patch file: " + + pcis.getDocumentName()); + } + + Node root = nodes.item(0); + // Test that 'root' node satisfies 'component' + // insertion criteria + String testPath = elem.getAttribute("unless-path"); + if (testPath == null || testPath.length() == 0) { + // only look for old "unless" attr if + // unless-path is not present + testPath = elem.getAttribute("unless"); + } + + if (testPath != null && testPath.length() > 0 && XPathAPI.eval(root, testPath).bool()) { + // no test path or 'unless' condition is satisfied + getLogger().debug("skipping application of patch file: " + pcis.getDocumentName()); + } else { + // Test if component wants us to remove + // a list of nodes first + xpath = elem.getAttribute("remove"); + if (xpath != null && xpath.length() > 0) { + nodes = XPathAPI.selectNodeList(original, xpath); + for (int i = 0, length = nodes.getLength(); i < length; i++) { + Node node = nodes.item(i); + Node parent = node.getParentNode(); + parent.removeChild(node); + } + } + // Test for an attribute that needs to be + // added to an element + String name = elem.getAttribute("add-attribute"); + String value = elem.getAttribute("value"); + + if (name != null && name.length() > 0 && value != null && root instanceof Element) { + ((Element) root).setAttribute(name, value); + } + + // Allow multiple attributes to be added or + // modified + if (root instanceof Element) { + NamedNodeMap attrMap = elem.getAttributes(); + for (int i = 0; i < attrMap.getLength(); ++i) { + Attr attr = (Attr) attrMap.item(i); + final String addAttr = "add-attribute-"; + if (attr.getName().startsWith(addAttr)) { + String key = attr.getName().substring(addAttr.length()); + ((Element) root).setAttribute(key, attr.getValue()); + } + } + } + + // Test if 'component' provides desired + // insertion point + xpath = elem.getAttribute("insert-before"); + Node before = null; + + if (xpath != null && xpath.length() > 0) { + nodes = XPathAPI.selectNodeList(root, xpath); + if (nodes.getLength() != 0) { + before = nodes.item(0); + } + } else { + xpath = elem.getAttribute("insert-after"); + if (xpath != null && xpath.length() > 0) { + nodes = XPathAPI.selectNodeList(root, xpath); + if (nodes.getLength() != 0) { + before = nodes.item(nodes.getLength() - 1).getNextSibling(); + } + } + } + + NodeList componentNodes = component.getDocumentElement().getChildNodes(); + for (int i = 0; i < componentNodes.getLength(); i++) { + Node node = original.importNode(componentNodes.item(i), true); + + if (before == null) { + root.appendChild(node); + } else { + root.insertBefore(node, before); + } + } + } + } + + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer = tFactory.newTransformer(); + OutputStream os = new BufferedOutputStream(new FileOutputStream(outFile)); + try { + getLogger().debug("Deploying resource file to " + fileName); + transformer.transform(new DOMSource(original), new StreamResult(os)); + } finally { + IOUtils.closeQuietly(os); + } + } catch (FileNotFoundException e) { + throw new DeploymentException("Can't write to nonexistant file " + fileName, e); + } catch (IOException e) { + throw new DeploymentException("Can't write to " + fileName, e); + } catch (ParserConfigurationException e) { + throw new DeploymentException("Unable to configure parser " + fileName, e); + } catch (SAXException e) { + throw new DeploymentException("Unable to parse XML " + fileName, e); + } catch (TransformerConfigurationException e) { + throw new DeploymentException("Unable to configure transformer " + fileName, e); + } catch (TransformerException e) { + throw new DeploymentException("Unable to transform XML " + fileName, e); + } + } + + private class PatchCachingOutputStream extends ByteArrayOutputStream { + private String documentName; + + public String getDocumentName() { + return documentName; + } + + public PatchCachingOutputStream(String documentName) { + this.documentName = documentName; + } + + public Document getPatch() throws SAXException, IOException, ParserConfigurationException { + return XMLUtils.parseXml(new ByteArrayInputStream(this.buf, 0, this.count)); + } + } +} Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/XPatchDeployer.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/XPatchDeployer.java ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/monolithic/XPatchDeployer.java ------------------------------------------------------------------------------ svn:mime-type = text/plain From carolyn93@example.net Tue May 01 11:36:00 2007 Return-Path: <carolyn93@example.net> Delivered-To: carolyn93@example.net Received: (qmail 87841 invoked from network); 1 May 2007 11:35:52 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 1 May 2007 11:35:52 -0000 Received: (qmail 91437 invoked by uid 500); 1 May 2007 11:35:58 -0000 Delivered-To: carolyn93@example.net Received: (qmail 91380 invoked by uid 500); 1 May 2007 11:35:58 -0000 Mailing-List: contact carolyn93@example.net; run by ezmlm Precedence: bulk Reply-To: carolyn93@example.net list-help: <mailto:carolyn93@example.net> list-unsubscribe: <mailto:carolyn93@example.net> List-Post: <mailto:carolyn93@example.net> List-Id: <cvs.cocoon.apache.org> Delivered-To: mailing list carolyn93@example.net Received: (qmail 91368 invoked by uid 99); 1 May 2007 11:35:58 -0000 Received: from herse.apache.org (HELO herse.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 May 2007 04:35:58 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP;
{'source': 'Apache Software Foundation Public Mail Archives'}