package org.apache.maven.plugins.war; /* * 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. */ import org.apache.maven.plugin.testing.stubs.ArtifactStub; import org.apache.maven.plugins.war.Overlay; import org.apache.maven.plugins.war.overlay.DefaultOverlay; import org.codehaus.plexus.util.FileUtils; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; /** * @author Stephane Nicoll */ public class WarOverlaysTest extends AbstractWarExplodedMojoTest { private static File pomFile = new File( getBasedir(), "target/test-classes/unit/waroverlays/default.xml" ); public void setUp() throws Exception { super.setUp(); generateFullOverlayWar( "overlay-full-1" ); generateFullOverlayWar( "overlay-full-2" ); generateFullOverlayWar( "overlay-full-3" ); } protected File getPomFile() { return pomFile; } protected File getTestDirectory() { return new File( getBasedir(), "target/test-classes/unit/waroverlays" ); } public void testEnvironment() throws Exception { // see setup } public void testNoOverlay() throws Exception { // setup test data final String testId = "no-overlay"; final File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } ); final File webAppDirectory = setUpMojo( testId, null ); try { mojo.setWebXml( new File( xmlSource, "web.xml" ) ); mojo.execute(); // Validate content of the webapp assertDefaultContent( webAppDirectory ); assertWebXml( webAppDirectory ); } finally { cleanDirectory( webAppDirectory ); } } public void testDefaultOverlay() throws Exception { // setup test data final String testId = "default-overlay"; // Add an overlay final ArtifactStub overlay = buildWarOverlayStub( "overlay-one" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay } ); final List<File> assertedFiles = new ArrayList<File>(); try { mojo.execute(); assertedFiles.addAll( assertDefaultContent( webAppDirectory ) ); assertedFiles.addAll( assertWebXml( webAppDirectory ) ); assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "index.jsp", "login.jsp" }, "overlay file not found" ) ); // index and login come from overlay1 assertOverlayedFile( webAppDirectory, "overlay-one", "index.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-one", "login.jsp" ); // Ok now check that there is no more files/directories final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } ); assertWebAppContent( webAppDirectory, assertedFiles, filter ); } finally { cleanDirectory( webAppDirectory ); } } public void testDefaultOverlays() throws Exception { // setup test data final String testId = "default-overlays"; // Add an overlay final ArtifactStub overlay = buildWarOverlayStub( "overlay-one" ); final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-two" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay, overlay2 } ); final List<File> assertedFiles = new ArrayList<File>(); try { mojo.execute(); assertedFiles.addAll( assertDefaultContent( webAppDirectory ) ); assertedFiles.addAll( assertWebXml( webAppDirectory ) ); assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "index.jsp", "login.jsp", "admin.jsp" }, "overlay file not found" ) ); // index and login come from overlay1 assertOverlayedFile( webAppDirectory, "overlay-one", "index.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-one", "login.jsp" ); // admin comes from overlay2 // index and login comes from overlay1 assertOverlayedFile( webAppDirectory, "overlay-two", "admin.jsp" ); // Ok now check that there is no more files/directories final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } ); assertWebAppContent( webAppDirectory, assertedFiles, filter ); } finally { cleanDirectory( webAppDirectory ); } } /** * Merge a dependent WAR when a file in the war source directory overrides one found in the WAR. * * It also tests completeness of the resulting war as well as the proper order of dependencies. * * @throws Exception if any error occurs */ public void testScenarioOneWithDefaulSettings() throws Exception { // setup test data final String testId = "scenario-one-default-settings"; // Add an overlay final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" ); final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" ); final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] { "org/sample/company/test.jsp", "jsp/b.jsp" } ); assertScenariOne( testId, webAppDirectory ); } /** * Tests that specifying the overlay explicitely has the same behavior as the default (i.e. order, etc). * * The default project is not specified in this case so it is processed first by default * * @throws Exception if an error occurs */ public void testScenarioOneWithOverlaySettings() throws Exception { // setup test data final String testId = "scenario-one-overlay-settings"; // Add an overlay final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" ); final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" ); final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] { "org/sample/company/test.jsp", "jsp/b.jsp" } ); // Add the tags final List<Overlay> overlays = new ArrayList<Overlay>(); overlays.add( new DefaultOverlay( overlay1 ) ); overlays.add( new DefaultOverlay( overlay2 ) ); overlays.add( new DefaultOverlay( overlay3 ) ); mojo.setOverlays( overlays ); // current project ignored. Should be on top of the list assertScenariOne( testId, webAppDirectory ); } /** * Tests that specifying the overlay explicitely has the same behavior as the default (i.e. order, etc). * * The default project is explicitely specified so this should match the default. * * @throws Exception if an error occurs */ public void testScenarioOneWithFullSettings() throws Exception { // setup test data final String testId = "scenario-one-full-settings"; // Add an overlay final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" ); final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" ); final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] { "org/sample/company/test.jsp", "jsp/b.jsp" } ); // Add the tags final List<Overlay> overlays = new ArrayList<Overlay>(); // Add the default project explicitely overlays.add( mojo.getCurrentProjectOverlay() ); // Other overlays overlays.add( new DefaultOverlay( overlay1 ) ); overlays.add( new DefaultOverlay( overlay2 ) ); overlays.add( new DefaultOverlay( overlay3 ) ); mojo.setOverlays( overlays ); // current project ignored. Should be on top of the list assertScenariOne( testId, webAppDirectory ); } /** * Runs the mojo and asserts a scenerio with 3 overlays and no includes/excludes settings. * * @param testId thie id of the test * @param webAppDirectory the webapp directory * @throws Exception if an exception occurs */ private void assertScenariOne( String testId, File webAppDirectory ) throws Exception { final List<File> assertedFiles = new ArrayList<File>(); try { mojo.execute(); assertedFiles.addAll( assertWebXml( webAppDirectory ) ); assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "jsp/a.jsp", "jsp/b.jsp", "jsp/c.jsp", "jsp/d/a.jsp", "jsp/d/b.jsp", "jsp/d/c.jsp", "org/sample/company/test.jsp", "WEB-INF/classes/a.class", "WEB-INF/classes/b.class", "WEB-INF/classes/c.class", "WEB-INF/lib/a.jar", "WEB-INF/lib/b.jar", "WEB-INF/lib/c.jar" }, "overlay file not found" ) ); // Those files should come from the source webapp without any config assertDefaultFileContent( testId, webAppDirectory, "jsp/b.jsp" ); assertDefaultFileContent( testId, webAppDirectory, "org/sample/company/test.jsp" ); // Everything else comes from overlay1 (order of addition in the dependencies) assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/a.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/c.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/a.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/b.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/c.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/web.xml" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/classes/a.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/classes/b.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/classes/c.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/lib/a.jar" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/lib/b.jar" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/lib/c.jar" ); // Ok now check that there is no more files/directories final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } ); assertWebAppContent( webAppDirectory, assertedFiles, filter ); } finally { cleanDirectory( webAppDirectory ); } } public void testOverlaysIncludesExcludesWithMultipleDefinitions() throws Exception { // setup test data final String testId = "overlays-includes-excludes-multiple-defs"; // Add an overlay final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" ); final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" ); final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] { "org/sample/company/test.jsp", "jsp/b.jsp" } ); Overlay over1 = new DefaultOverlay( overlay3 ); over1.setExcludes( "**/a.*,**/c.*,**/*.xml" ); Overlay over2 = new DefaultOverlay( overlay1 ); over2.setIncludes( "jsp/d/*" ); over2.setExcludes( "jsp/d/a.jsp" ); Overlay over3 = new DefaultOverlay( overlay3 ); over3.setIncludes( "**/*.jsp" ); Overlay over4 = new DefaultOverlay( overlay2 ); mojo.setOverlays( new LinkedList<Overlay>() ); mojo.addOverlay( over1 ); mojo.addOverlay( over2 ); mojo.addOverlay( over3 ); mojo.addOverlay( mojo.getCurrentProjectOverlay() ); mojo.addOverlay( over4 ); final List<File> assertedFiles = new ArrayList<File>(); try { mojo.execute(); assertedFiles.addAll( assertWebXml( webAppDirectory ) ); assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "jsp/a.jsp", "jsp/b.jsp", "jsp/c.jsp", "jsp/d/a.jsp", "jsp/d/b.jsp", "jsp/d/c.jsp", "org/sample/company/test.jsp", "WEB-INF/classes/a.class", "WEB-INF/classes/b.class", "WEB-INF/classes/c.class", "WEB-INF/lib/a.jar", "WEB-INF/lib/b.jar", "WEB-INF/lib/c.jar" }, "overlay file not found" ) ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/a.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/b.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/c.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/d/a.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/d/b.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/c.jsp" ); assertDefaultFileContent( testId, webAppDirectory, "org/sample/company/test.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/web.xml" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/classes/a.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "WEB-INF/classes/b.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/classes/c.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/lib/a.jar" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "WEB-INF/lib/b.jar" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/lib/c.jar" ); // Ok now check that there is no more files/directories final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } ); assertWebAppContent( webAppDirectory, assertedFiles, filter ); } finally { cleanDirectory( webAppDirectory ); } } public void testOverlaysIncludesExcludesWithMultipleDefinitions2() throws Exception { // setup test data final String testId = "overlays-includes-excludes-multiple-defs2"; // Add an overlay final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" ); final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" ); final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] { "org/sample/company/test.jsp", "jsp/b.jsp" } ); Overlay over1 = new DefaultOverlay( overlay3 ); over1.setExcludes( "**/a.*,**/c.*,**/*.xml,jsp/b.jsp" ); Overlay over2 = new DefaultOverlay( overlay1 ); over2.setIncludes( "jsp/d/*" ); over2.setExcludes( "jsp/d/a.jsp" ); Overlay over3 = new DefaultOverlay( overlay3 ); over3.setIncludes( "**/*.jsp" ); over3.setExcludes( "jsp/b.jsp" ); Overlay over4 = new DefaultOverlay( overlay2 ); mojo.setOverlays( new LinkedList<Overlay>() ); mojo.addOverlay( over1 ); mojo.addOverlay( over2 ); mojo.addOverlay( over3 ); mojo.addOverlay( mojo.getCurrentProjectOverlay() ); mojo.addOverlay( over4 ); final List<File> assertedFiles = new ArrayList<File>(); try { mojo.execute(); assertedFiles.addAll( assertWebXml( webAppDirectory ) ); assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "jsp/a.jsp", "jsp/b.jsp", "jsp/c.jsp", "jsp/d/a.jsp", "jsp/d/b.jsp", "jsp/d/c.jsp", "org/sample/company/test.jsp", "WEB-INF/classes/a.class", "WEB-INF/classes/b.class", "WEB-INF/classes/c.class", "WEB-INF/lib/a.jar", "WEB-INF/lib/b.jar", "WEB-INF/lib/c.jar" }, "overlay file not found" ) ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/a.jsp" ); assertDefaultFileContent( testId, webAppDirectory, "jsp/b.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/c.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/d/a.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/d/b.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/c.jsp" ); assertDefaultFileContent( testId, webAppDirectory, "org/sample/company/test.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/web.xml" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/classes/a.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "WEB-INF/classes/b.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/classes/c.class" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/lib/a.jar" ); assertOverlayedFile( webAppDirectory, "overlay-full-3", "WEB-INF/lib/b.jar" ); assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/lib/c.jar" ); // Ok now check that there is no more files/directories final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } ); assertWebAppContent( webAppDirectory, assertedFiles, filter ); } finally { cleanDirectory( webAppDirectory ); } } public void testCacheWithUpdatedOverlay() throws Exception { // setup test data final String testId = "cache-updated-overlay"; // Add an overlay final ArtifactStub overlay = buildWarOverlayStub( "overlay-one" ); final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-two" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay, overlay2 } ); final List<File> assertedFiles = new ArrayList<File>(); try { // Use the cache setVariableValueToObject( mojo, "useCache", Boolean.TRUE ); setVariableValueToObject( mojo, "cacheFile", new File( mojo.getWorkDirectory(), "cache.xml" ) ); final LinkedList<Overlay> overlays = new LinkedList<Overlay>(); overlays.add( new DefaultOverlay( overlay ) ); overlays.add( new DefaultOverlay( overlay2 ) ); mojo.setOverlays( overlays ); mojo.execute(); // Now change the overlay order and make sure the right file is overwritten final LinkedList<Overlay> updatedOverlays = new LinkedList<Overlay>(); updatedOverlays.add( new DefaultOverlay( overlay2 ) ); updatedOverlays.add( new DefaultOverlay( overlay ) ); mojo.setOverlays( updatedOverlays ); mojo.execute(); assertedFiles.addAll( assertDefaultContent( webAppDirectory ) ); assertedFiles.addAll( assertWebXml( webAppDirectory ) ); assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "index.jsp", "login.jsp", "admin.jsp" }, "overlay file not found" ) ); // index and login come from overlay2 now assertOverlayedFile( webAppDirectory, "overlay-two", "index.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-one", "login.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-two", "admin.jsp" ); // Ok now check that there is no more files/directories final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } ); assertWebAppContent( webAppDirectory, assertedFiles, filter ); } finally { cleanDirectory( webAppDirectory ); } } public void testCacheWithRemovedOverlay() throws Exception { // setup test data final String testId = "cache-removed-overlay"; // Add an overlay final ArtifactStub overlay = buildWarOverlayStub( "overlay-one" ); final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-two" ); final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay, overlay2 } ); final List<File> assertedFiles = new ArrayList<File>(); try { // Use the cache setVariableValueToObject( mojo, "useCache", Boolean.TRUE ); setVariableValueToObject( mojo, "cacheFile", new File( mojo.getWorkDirectory(), "cache.xml" ) ); final LinkedList<Overlay> overlays = new LinkedList<Overlay>(); overlays.add( new DefaultOverlay( overlay ) ); overlays.add( new DefaultOverlay( overlay2 ) ); mojo.setOverlays( overlays ); mojo.execute(); // Now remove overlay one the right file is overwritten final LinkedList<Overlay> updatedOverlays = new LinkedList<Overlay>(); updatedOverlays.add( new DefaultOverlay( overlay2 ) ); mojo.setOverlays( updatedOverlays ); // Remove overlay one as a dep mojo.getProject().getArtifacts().remove( overlay ); mojo.execute(); assertedFiles.addAll( assertDefaultContent( webAppDirectory ) ); assertedFiles.addAll( assertWebXml( webAppDirectory ) ); assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "index.jsp", "login.jsp", "admin.jsp" }, "overlay file not found" ) ); // index and login come from overlay2 now assertOverlayedFile( webAppDirectory, "overlay-two", "index.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-one", "login.jsp" ); assertOverlayedFile( webAppDirectory, "overlay-two", "admin.jsp" ); // Ok now check that there is no more files/directories final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } ); assertWebAppContent( webAppDirectory, assertedFiles, filter ); } finally { cleanDirectory( webAppDirectory ); } } // Helpers /** * Asserts that the content of an overlayed file is correct. * * Note that the <tt>filePath</tt> is relative to both the webapp directory and the overlayed directory, defined by * the <tt>overlayId</tt>. * * @param webAppDirectory the webapp directory * @param overlayId the id of the overlay * @param filePath the relative path * @throws IOException if an error occurred while reading the files */ protected void assertOverlayedFile( File webAppDirectory, String overlayId, String filePath ) throws IOException { final File webAppFile = new File( webAppDirectory, filePath ); final File overlayFile = getOverlayFile( overlayId, filePath ); assertEquals( "Wrong content for overlayed file " + filePath, FileUtils.fileRead( overlayFile ), FileUtils.fileRead( webAppFile ) ); } /** * Asserts that the content of an overlayed file is correct. * * Note that the <tt>filePath</tt> is relative to both the webapp directory and the overlayed directory, defined by * the <tt>overlayId</tt>. * * @param testId te id of the test * @param webAppDirectory the webapp directory * @param filePath the relative path * @throws IOException if an error occurred while reading the files */ protected void assertDefaultFileContent( String testId, File webAppDirectory, String filePath ) throws Exception { final File webAppFile = new File( webAppDirectory, filePath ); final File sourceFile = new File( getWebAppSource( testId ), filePath ); final String expectedContent = sourceFile.toString(); assertEquals( "Wrong content for file " + filePath, expectedContent, FileUtils.fileRead( webAppFile ) ); } protected ArtifactStub generateSimpleWarArtifactStub( String id ) throws Exception { return buildWarOverlayStub( id ); } }