diff --git a/src/it/process-project-file/common2.txt b/src/it/process-project-file/common2.txt new file mode 100644 index 0000000..8cc47b8 --- /dev/null +++ b/src/it/process-project-file/common2.txt @@ -0,0 +1,18 @@ +# 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. + +using project's workspace file diff --git a/src/it/process-project-file/invoker.properties b/src/it/process-project-file/invoker.properties new file mode 100644 index 0000000..0097f00 --- /dev/null +++ b/src/it/process-project-file/invoker.properties @@ -0,0 +1,18 @@ +# 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. + +invoker.goals = generate-resources diff --git a/src/it/process-project-file/pom.xml b/src/it/process-project-file/pom.xml new file mode 100644 index 0000000..a1621ff --- /dev/null +++ b/src/it/process-project-file/pom.xml @@ -0,0 +1,56 @@ + + + + + 4.0.0 + + org.apache.maven.its + mrrp-process + 1.0-SNAPSHOT + pom + + + UTF-8 + + + + + + org.apache.maven.plugins + maven-remote-resources-plugin + @project.version@ + + + org.apache.maven.its:mrrp-bundle-a:1.0-SNAPSHOT + + true + + + + + process + + + + + + + diff --git a/src/it/process-project-file/verify.groovy b/src/it/process-project-file/verify.groovy new file mode 100644 index 0000000..baab203 --- /dev/null +++ b/src/it/process-project-file/verify.groovy @@ -0,0 +1,28 @@ +/* + * 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. + */ + +dir = new File( basedir, 'target/maven-shared-archive-resources' ) + +assert new File( dir, 'a/a.txt' ).text.contains( 'mrrp-bundle-a' ) + +assert new File( dir, 'common.txt' ).text.contains( 'mrrp-bundle-a' ) // bundle a is first in classpath +assert new File( dir, 'common-vm.txt' ).text.contains( 'mrrp-bundle-a org.apache.maven.its:mrrp-process' ) + +// bundle content overridden by local project's workspace file +assert new File( dir, 'common2.txt' ).text.contains( 'using project\'s workspace file' ) diff --git a/src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java b/src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java index 1aa5255..f57f6d1 100644 --- a/src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java +++ b/src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java @@ -21,12 +21,10 @@ import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; -import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; import java.io.Writer; @@ -350,6 +348,14 @@ public abstract class AbstractProcessRemoteResourcesMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.outputTimestamp}") private String outputTimestamp; + /** + * Indicate if project workspace files with the same name should be used instead of the ones from the bundle. + * + * @since 3.3.0 + */ + @Parameter(defaultValue = "false") + private boolean useProjectFiles; + /** * Map of artifacts to supplemental project object models. */ @@ -605,7 +611,8 @@ protected Map> getProjectsSortedByOrganization( return organizations; } - protected boolean copyResourceIfExists(File file, String relFileName, VelocityContext context) + protected boolean copyResourceIfExists( + File outputFile, String bundleResourceName, VelocityContext context, String encoding) throws IOException, MojoExecutionException { for (Resource resource : project.getResources()) { File resourceDirectory = new File(resource.getDirectory()); @@ -615,26 +622,27 @@ protected boolean copyResourceIfExists(File file, String relFileName, VelocityCo } // TODO - really should use the resource includes/excludes and name mapping - File source = new File(resourceDirectory, relFileName); - File templateSource = new File(resourceDirectory, relFileName + TEMPLATE_SUFFIX); + File source = new File(resourceDirectory, bundleResourceName); + File templateSource = new File(resourceDirectory, bundleResourceName + TEMPLATE_SUFFIX); if (!source.exists() && templateSource.exists()) { source = templateSource; } - if (source.exists() && !source.equals(file)) { + if (source.exists() && !source.equals(outputFile)) { if (source == templateSource) { - try (CachingOutputStream os = new CachingOutputStream(file)) { - try (Reader reader = getReader(source); - Writer writer = getWriter(os)) { - velocity.evaluate(context, writer, "", reader); - } catch (ParseErrorException | MethodInvocationException | ResourceNotFoundException e) { - throw new MojoExecutionException("Error rendering velocity resource: " + source, e); - } + getLog().debug("Use project resource '" + source + "' as resource with Velocity"); + try (CachingOutputStream os = new CachingOutputStream(outputFile); + Writer writer = getWriter(encoding, os); + Reader reader = getReader(encoding, source)) { + velocity.evaluate(context, writer, "", reader); + } catch (ParseErrorException | MethodInvocationException | ResourceNotFoundException e) { + throw new MojoExecutionException("Error rendering velocity resource: " + source, e); } } else if (resource.isFiltering()) { + getLog().debug("Use project resource '" + source + "' as resource with filtering"); - MavenFileFilterRequest req = setupRequest(resource, source, file); + MavenFileFilterRequest req = setupRequest(resource, source, outputFile); try { fileFilter.copyFile(req); @@ -642,11 +650,12 @@ protected boolean copyResourceIfExists(File file, String relFileName, VelocityCo throw new MojoExecutionException("Error filtering resource: " + source, e); } } else { - FilteringUtils.copyFile(source, file, null, null); + getLog().debug("Use project resource '" + source + "' as resource"); + FilteringUtils.copyFile(source, outputFile, null, null); } // exclude the original (so eclipse doesn't complain about duplicate resources) - resource.addExclude(relFileName); + resource.addExclude(bundleResourceName); return true; } @@ -654,12 +663,28 @@ protected boolean copyResourceIfExists(File file, String relFileName, VelocityCo return false; } - private Reader getReader(File source) throws IOException { - return Files.newBufferedReader(source.toPath(), Charset.forName(encoding)); + private boolean copyProjectRootIfExists(File outputFile, String bundleResourceName) throws IOException { + if (!useProjectFiles) { + return false; + } + + File source = new File(project.getBasedir(), bundleResourceName); + if (source.exists()) { + getLog().debug("Use project file '" + source + "' as resource"); + FilteringUtils.copyFile(source, outputFile, null, null); + return true; + } + + return false; + } + + private Reader getReader(String readerEncoding, File file) throws IOException { + return Files.newBufferedReader( + file.toPath(), Charset.forName(readerEncoding != null ? readerEncoding : encoding)); } - private Writer getWriter(OutputStream os) throws IOException { - return new OutputStreamWriter(os, encoding); + private Writer getWriter(String writerEncoding, OutputStream outputStream) throws IOException { + return new OutputStreamWriter(outputStream, writerEncoding != null ? writerEncoding : encoding); } private MavenFileFilterRequest setupRequest(Resource resource, File source, File file) { @@ -908,46 +933,54 @@ protected void processResourceBundles(ClassLoader classLoader, VelocityContext c // Don't overwrite resource that are already being provided. - File f = new File(outputDirectory, projectResource); + File outputFile = new File(outputDirectory, projectResource); - FileUtils.mkdir(f.getParentFile().getAbsolutePath()); + FileUtils.mkdir(outputFile.getParentFile().getAbsolutePath()); - if (!copyResourceIfExists(f, projectResource, context)) { - if (doVelocity) { - try (CachingOutputStream os = new CachingOutputStream(f)) { - String bundleEncoding = bundle.getSourceEncoding(); - if (bundleEncoding == null) { - bundleEncoding = encoding; - } - try (Writer writer = new OutputStreamWriter(os, bundleEncoding)) { - velocity.mergeTemplate(bundleResource, bundleEncoding, context, writer); - } - } - } else { - URL resUrl = classLoader.getResource(bundleResource); - if (resUrl != null) { - FileUtils.copyURLToFile(resUrl, f); - } + // resource exists in project resources + if (copyResourceIfExists(outputFile, projectResource, context, bundle.getSourceEncoding())) { + continue; + } + + if (copyProjectRootIfExists(outputFile, projectResource)) { + continue; + } + + if (doVelocity) { + String bundleEncoding = bundle.getSourceEncoding(); + if (bundleEncoding == null) { + bundleEncoding = encoding; } - File appendedResourceFile = new File(appendedResourcesDirectory, projectResource); - File appendedVmResourceFile = new File(appendedResourcesDirectory, projectResource + ".vm"); + try (CachingOutputStream os = new CachingOutputStream(outputFile); + Writer writer = getWriter(bundleEncoding, os)) { + velocity.mergeTemplate(bundleResource, bundleEncoding, context, writer); + } + } else { + URL bundleResourceUrl = classLoader.getResource(bundleResource); + if (bundleResourceUrl != null) { + FileUtils.copyURLToFile(bundleResourceUrl, outputFile); + } + } - if (appendedResourceFile.exists()) { - getLog().info("Copying appended resource: " + projectResource); - try (InputStream in = Files.newInputStream(appendedResourceFile.toPath()); - OutputStream out = new FileOutputStream(f, true)) { - IOUtil.copy(in, out); - } + File appendedResourceFile = new File(appendedResourcesDirectory, projectResource); + File appendedVmResourceFile = new File(appendedResourcesDirectory, projectResource + ".vm"); - } else if (appendedVmResourceFile.exists()) { - getLog().info("Filtering appended resource: " + projectResource + ".vm"); + if (appendedResourceFile.exists()) { + getLog().info("Copying appended resource: " + projectResource); + try (InputStream in = Files.newInputStream(appendedResourceFile.toPath()); + OutputStream out = new FileOutputStream(outputFile, true)) { + IOUtil.copy(in, out); + } - try (Reader reader = new FileReader(appendedVmResourceFile); - Writer writer = getWriter(bundle, f)) { - Velocity.init(); - Velocity.evaluate(context, writer, "remote-resources", reader); - } + } else if (appendedVmResourceFile.exists()) { + getLog().info("Filtering appended resource: " + projectResource + ".vm"); + + try (CachingOutputStream os = new CachingOutputStream(outputFile); + Reader reader = getReader(bundle.getSourceEncoding(), appendedVmResourceFile); + Writer writer = getWriter(bundle.getSourceEncoding(), os)) { + Velocity.init(); + Velocity.evaluate(context, writer, "remote-resources", reader); } } } @@ -972,16 +1005,6 @@ private void verifyRequiredProperties(RemoteResourcesBundle bundle, URL url) thr } } - private Writer getWriter(RemoteResourcesBundle bundle, File f) throws IOException { - Writer writer; - if (bundle.getSourceEncoding() == null) { - writer = new PrintWriter(new FileWriter(f, true)); - } else { - writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(f, true), bundle.getSourceEncoding())); - } - return writer; - } - protected Model getSupplement(Xpp3Dom supplementModelXml) throws MojoExecutionException { MavenXpp3Reader modelReader = new MavenXpp3Reader(); Model model = null;