Skip to content

Commit

Permalink
Fix filtering of web resources using system properties and escaping (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jtnord committed Mar 17, 2023
1 parent ef62610 commit cf6507d
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 133 deletions.
6 changes: 5 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@
<artifactId>maven-artifact-transfer</artifactId>
<version>0.13.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-filtering</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-dependency-tree</artifactId>
Expand All @@ -212,7 +217,6 @@
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<!-- generated help mojo has a dependency on plexus utils -->
<version>3.5.1</version>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
</p>
<p>
You can also filter using interpolation like:
\${prop1\} ${prop1}
\${prop1} ${prop1}
or
\@prop2\@ @prop2@
and these will be replaced at build time
it is even possible to use system properties
\@java.class.version\@ ${java.class.version}
\@java.vendor.url\@ ${java.vendor.url}
</p>

</div>
10 changes: 4 additions & 6 deletions src/it/warResources/verify.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@
* under the License.
*/
globalConfigHelp = new File(basedir, 'target/war-resources-it/help-globalConfig.html').text;
// code uses plexus not maven so escapes are not supported.
assert globalConfigHelp.contains("\\\${prop1\\} hello");
assert globalConfigHelp.contains("\\@prop2\\@ goodbye");
// code claims to add System properties but this fails
// assert globalConfigHelp.contains("\\@java.class.version\\@ 55.0");
assert globalConfigHelp.contains('${prop1} hello');
assert globalConfigHelp.contains('@prop2@ goodbye');
assert globalConfigHelp.contains('@java.vendor.url@ https://');


return true;
return true;
144 changes: 20 additions & 124 deletions src/main/java/org/jenkinsci/maven/plugins/hpi/AbstractHpiMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,17 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import jenkins.YesNoMaybe;
Expand All @@ -47,19 +45,23 @@
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.maven.shared.filtering.MavenResourcesExecution;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.InterpolationFilterReader;
import org.codehaus.plexus.util.PropertyUtils;
import org.codehaus.plexus.util.StringUtils;
import org.jenkinsci.maven.plugins.hp.util.Utils;

public abstract class AbstractHpiMojo extends AbstractJenkinsMojo {

@Component(role = MavenResourcesFiltering.class, hint = "default" )
protected MavenResourcesFiltering mavenResourcesFiltering;

/**
* The directory for the generated WAR.
*/
Expand Down Expand Up @@ -351,10 +353,7 @@ public void buildExplodedWebapp(File webappDirectory, File jarFile)
try {
List<Resource> webResources = this.webResources != null ? List.of(this.webResources) : null;
if (webResources != null && webResources.size() > 0) {
Properties filterProperties = getBuildFilterProperties();
for (Resource resource : webResources) {
copyResources(resource, webappDirectory, filterProperties);
}
copyResourcesWithFiltering(webResources, webappDirectory);
}

copyResources(warSourceDirectory, webappDirectory);
Expand All @@ -371,30 +370,11 @@ public void buildExplodedWebapp(File webappDirectory, File jarFile)
}
catch (IOException e) {
throw new MojoExecutionException("Could not explode webapp...", e);
} catch (MavenFilteringException e) {
throw new MojoExecutionException("Could not copy webResources...", e);
}
}

private Properties getBuildFilterProperties()
throws MojoExecutionException {
// System properties
Properties filterProperties = new Properties(System.getProperties());

// Project properties
filterProperties.putAll(project.getProperties());

for (String filter : filters) {
try {
Properties properties = PropertyUtils.loadProperties(new File(filter));

filterProperties.putAll(properties);
}
catch (IOException e) {
throw new MojoExecutionException("Error loading property file '" + filter + "'", e);
}
}
return filterProperties;
}

/**
* Copies webapp webResources from the specified directory.
* <p>
Expand All @@ -403,28 +383,16 @@ private Properties getBuildFilterProperties()
* exists, it will be copied to the {@code META-INF} directory and
* renamed accordingly.
*
* @param resource the resource to copy
* @param resources the resources to copy
* @param webappDirectory the target directory
* @throws java.io.IOException if an error occurred while copying webResources
*/
public void copyResources(Resource resource, File webappDirectory, Properties filterProperties)
throws IOException {
if (!resource.getDirectory().equals(webappDirectory.getPath())) {
getLog().info("Copy webapp webResources to " + webappDirectory.getAbsolutePath());
if (webappDirectory.exists()) {
String[] fileNames = getWarFiles(resource);
for (String fileName : fileNames) {
if (resource.isFiltering()) {
copyFilteredFile(new File(resource.getDirectory(), fileName),
new File(webappDirectory, fileName), null, getFilterWrappers(),
filterProperties);
} else {
FileUtils.copyFileIfModified(new File(resource.getDirectory(), fileName),
new File(webappDirectory, fileName));
}
}
}
}
* @throws MavenFilteringException if an error occurred while copying webResources
*/
public void copyResourcesWithFiltering(List<Resource> resources, File webappDirectory) throws MavenFilteringException {
MavenResourcesExecution mavenResourcesExecution =
new MavenResourcesExecution(resources, webappDirectory, project, StandardCharsets.UTF_8.name(), filters,
Collections.emptyList(), session);
mavenResourcesExecution.setEscapeString("\\");
mavenResourcesFiltering.filterResources( mavenResourcesExecution);
}

/**
Expand Down Expand Up @@ -736,71 +704,6 @@ private String[] getWarFiles(File sourceDir) {
return scanner.getIncludedFiles();
}

/**
* Returns a list of filenames that should be copied
* over to the destination directory.
*
* @param resource the resource to be scanned
* @return the array of filenames, relative to the sourceDir
*/
private String[] getWarFiles(Resource resource) {
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir(resource.getDirectory());
if (resource.getIncludes() != null && !resource.getIncludes().isEmpty()) {
scanner.setIncludes(resource.getIncludes().toArray(EMPTY_STRING_ARRAY));
} else {
scanner.setIncludes(DEFAULT_INCLUDES);
}
if (resource.getExcludes() != null && !resource.getExcludes().isEmpty()) {
scanner.setExcludes(resource.getExcludes().toArray(EMPTY_STRING_ARRAY));
}

scanner.addDefaultExcludes();

scanner.scan();

return scanner.getIncludedFiles();
}

private FilterWrapper[] getFilterWrappers() {
return new FilterWrapper[]{
// support ${token}
new FilterWrapper() {
@Override
public Reader getReader(Reader fileReader, Properties filterProperties) {
return new InterpolationFilterReader(fileReader, filterProperties, "${", "}");
}
},
// support @token@
new FilterWrapper() {
@Override
public Reader getReader(Reader fileReader, Properties filterProperties) {
return new InterpolationFilterReader(fileReader, filterProperties, "@", "@");
}
}};
}

/**
* @throws IOException TO DO: Remove this method when Maven moves to plexus-utils version 1.4
*/
private static void copyFilteredFile(File from, File to, String encoding, FilterWrapper[] wrappers,
Properties filterProperties)
throws IOException {
// fix for MWAR-36, ensures that the parent dir are created first
Files.createDirectories(to.toPath().getParent());

Charset cs = (encoding == null || encoding.length() < 1) ? StandardCharsets.UTF_8 : Charset.forName(encoding);
try (Reader fileReader = Files.newBufferedReader(from.toPath(), cs);
Writer fileWriter = Files.newBufferedWriter(to.toPath(), cs)) {

Reader reader = fileReader;
for (FilterWrapper wrapper : wrappers) {
reader = wrapper.getReader(reader, filterProperties);
}
IOUtil.copy(reader, fileWriter);
}
}

/**
* If the project is on Git, figure out Git SHA1.
*
Expand Down Expand Up @@ -836,13 +739,6 @@ public String getGitHeadSha1() {
}
}

/**
* TO DO: Remove this interface when Maven moves to plexus-utils version 1.4
*/
private interface FilterWrapper {
Reader getReader(Reader fileReader, Properties filterProperties);
}

/**
* Is the dynamic loading supported?
*
Expand Down

0 comments on commit cf6507d

Please sign in to comment.