[ https://issues.apache.org/jira/browse/MNG-7622?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17645821#comment-17645821 ]
ASF GitHub Bot commented on MNG-7622: ------------------------------------- michael-o commented on code in PR #907: URL: https://github.com/apache/maven/pull/907#discussion_r1045275559 ########## maven-core/src/main/java/org/apache/maven/internal/transformation/ConsumerPomArtifactTransformer.java: ########## @@ -0,0 +1,146 @@ +/* + * 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.maven.internal.transformation; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Collection; +import java.util.function.BiConsumer; +import javax.inject.Named; +import javax.inject.Singleton; +import org.apache.maven.feature.Features; +import org.apache.maven.model.building.TransformerContext; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.artifact.ProjectArtifact; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.deployment.DeployRequest; +import org.eclipse.aether.installation.InstallRequest; + +/** + * Consumer POM transformer. + * + * @since TBD + */ +@Singleton +@Named("consumer-pom") +public final class ConsumerPomArtifactTransformer implements ArtifactTransformer { + private static final String CLASSIFIER = "maven-consumer-pom"; Review Comment: here as well ########## maven-core/src/main/java/org/apache/maven/internal/transformation/ConsumerPomArtifactTransformer.java: ########## @@ -0,0 +1,146 @@ +/* + * 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.maven.internal.transformation; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Collection; +import java.util.function.BiConsumer; +import javax.inject.Named; +import javax.inject.Singleton; +import org.apache.maven.feature.Features; +import org.apache.maven.model.building.TransformerContext; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.artifact.ProjectArtifact; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.deployment.DeployRequest; +import org.eclipse.aether.installation.InstallRequest; + +/** + * Consumer POM transformer. + * + * @since TBD + */ +@Singleton +@Named("consumer-pom") +public final class ConsumerPomArtifactTransformer implements ArtifactTransformer { + private static final String CLASSIFIER = "maven-consumer-pom"; + + private static final String EXTENSION = "pom"; + + @Override + public void injectTransformedArtifacts(MavenProject project, RepositorySystemSession session) throws IOException { + if (isActive(session)) { + Path generatedFile; + String buildDirectory = + project.getBuild() != null ? project.getBuild().getDirectory() : null; + if (buildDirectory == null) { + generatedFile = Files.createTempFile(CLASSIFIER, EXTENSION); + } else { + Path buildDir = Paths.get(buildDirectory); + Files.createDirectories(buildDir); + generatedFile = Files.createTempFile(buildDir, CLASSIFIER, EXTENSION); + } + project.addAttachedArtifact(new ConsumerPomArtifact(project, generatedFile, session)); + } + } + + @Override + public InstallRequest remapInstallArtifacts(RepositorySystemSession session, InstallRequest request) { + if (isActive(session) && consumerPomPresent(request.getArtifacts())) { + request.setArtifacts(replacePom(request.getArtifacts())); + } + return request; + } + + @Override + public DeployRequest remapDeployArtifacts(RepositorySystemSession session, DeployRequest request) { + if (isActive(session) && consumerPomPresent(request.getArtifacts())) { + request.setArtifacts(replacePom(request.getArtifacts())); + } + return request; + } + + private boolean isActive(RepositorySystemSession session) { + return Features.buildConsumer(session.getUserProperties()).isActive(); + } + + private boolean consumerPomPresent(Collection<Artifact> artifacts) { + return artifacts.stream() + .anyMatch(a -> CLASSIFIER.equals(a.getClassifier()) && EXTENSION.equals(a.getExtension())); + } + + private Collection<Artifact> replacePom(Collection<Artifact> artifacts) { + ArrayList<Artifact> result = new ArrayList<>(artifacts.size()); + for (Artifact artifact : artifacts) { + if (CLASSIFIER.equals(artifact.getClassifier()) + && artifact.getExtension().startsWith(EXTENSION)) { + DefaultArtifact remapped = new DefaultArtifact( + artifact.getGroupId(), + artifact.getArtifactId(), + "", + artifact.getExtension(), + artifact.getVersion(), + artifact.getProperties(), + artifact.getFile()); + result.add(remapped); + } else if (!("".equals(artifact.getClassifier()) Review Comment: why not `isEmpty()`? ########## maven-core/src/main/java/org/apache/maven/internal/transformation/OnChangeTransformer.java: ########## @@ -0,0 +1,103 @@ +/* + * 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.maven.internal.transformation; + +import static java.util.Objects.requireNonNull; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Keeps transformed file up-to-date relative to its source file. It manages state (i.e. hashing the content) using + * passed in stateFunction, and transforms when needed using passed in transformer bi-consumer. + * <p> + * Covered cases: + * <ul> + * <li>when source supplier returns {@code null}, this class will return {@code null}.</li> + * <li>when source supplier returns non existing path, this class will return non existing path.</li> Review Comment: Why not `null` here? ########## maven-core/src/main/java/org/apache/maven/internal/transformation/OnChangeTransformer.java: ########## @@ -0,0 +1,103 @@ +/* + * 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.maven.internal.transformation; + +import static java.util.Objects.requireNonNull; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Keeps transformed file up-to-date relative to its source file. It manages state (i.e. hashing the content) using + * passed in stateFunction, and transforms when needed using passed in transformer bi-consumer. + * <p> + * Covered cases: + * <ul> + * <li>when source supplier returns {@code null}, this class will return {@code null}.</li> + * <li>when source supplier returns non existing path, this class will return non existing path.</li> + * <li>when source supplier returns existing path, this class will ensure transformation is in sync.</li> + * </ul> + * + * @since TBD + */ +public final class OnChangeTransformer implements Supplier<Path> { + private final Supplier<Path> source; Review Comment: here as well ########## maven-core/src/main/java/org/apache/maven/internal/transformation/ConsumerPomArtifactTransformer.java: ########## @@ -0,0 +1,146 @@ +/* + * 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.maven.internal.transformation; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Collection; +import java.util.function.BiConsumer; +import javax.inject.Named; +import javax.inject.Singleton; +import org.apache.maven.feature.Features; +import org.apache.maven.model.building.TransformerContext; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.artifact.ProjectArtifact; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.deployment.DeployRequest; +import org.eclipse.aether.installation.InstallRequest; + +/** + * Consumer POM transformer. + * + * @since TBD + */ +@Singleton +@Named("consumer-pom") +public final class ConsumerPomArtifactTransformer implements ArtifactTransformer { + private static final String CLASSIFIER = "maven-consumer-pom"; + + private static final String EXTENSION = "pom"; + + @Override + public void injectTransformedArtifacts(MavenProject project, RepositorySystemSession session) throws IOException { + if (isActive(session)) { + Path generatedFile; + String buildDirectory = + project.getBuild() != null ? project.getBuild().getDirectory() : null; + if (buildDirectory == null) { + generatedFile = Files.createTempFile(CLASSIFIER, EXTENSION); + } else { + Path buildDir = Paths.get(buildDirectory); + Files.createDirectories(buildDir); + generatedFile = Files.createTempFile(buildDir, CLASSIFIER, EXTENSION); + } + project.addAttachedArtifact(new ConsumerPomArtifact(project, generatedFile, session)); + } + } + + @Override + public InstallRequest remapInstallArtifacts(RepositorySystemSession session, InstallRequest request) { + if (isActive(session) && consumerPomPresent(request.getArtifacts())) { + request.setArtifacts(replacePom(request.getArtifacts())); + } + return request; + } + + @Override + public DeployRequest remapDeployArtifacts(RepositorySystemSession session, DeployRequest request) { + if (isActive(session) && consumerPomPresent(request.getArtifacts())) { + request.setArtifacts(replacePom(request.getArtifacts())); + } + return request; + } + + private boolean isActive(RepositorySystemSession session) { + return Features.buildConsumer(session.getUserProperties()).isActive(); + } + + private boolean consumerPomPresent(Collection<Artifact> artifacts) { + return artifacts.stream() + .anyMatch(a -> CLASSIFIER.equals(a.getClassifier()) && EXTENSION.equals(a.getExtension())); + } + + private Collection<Artifact> replacePom(Collection<Artifact> artifacts) { + ArrayList<Artifact> result = new ArrayList<>(artifacts.size()); + for (Artifact artifact : artifacts) { + if (CLASSIFIER.equals(artifact.getClassifier()) + && artifact.getExtension().startsWith(EXTENSION)) { + DefaultArtifact remapped = new DefaultArtifact( + artifact.getGroupId(), + artifact.getArtifactId(), + "", + artifact.getExtension(), + artifact.getVersion(), + artifact.getProperties(), + artifact.getFile()); + result.add(remapped); + } else if (!("".equals(artifact.getClassifier()) + && artifact.getExtension().startsWith("pom"))) { Review Comment: `EXTENSION`? ########## maven-core/src/main/java/org/apache/maven/internal/transformation/OnChangeTransformer.java: ########## @@ -0,0 +1,103 @@ +/* + * 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.maven.internal.transformation; + +import static java.util.Objects.requireNonNull; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Keeps transformed file up-to-date relative to its source file. It manages state (i.e. hashing the content) using + * passed in stateFunction, and transforms when needed using passed in transformer bi-consumer. + * <p> + * Covered cases: + * <ul> + * <li>when source supplier returns {@code null}, this class will return {@code null}.</li> + * <li>when source supplier returns non existing path, this class will return non existing path.</li> + * <li>when source supplier returns existing path, this class will ensure transformation is in sync.</li> + * </ul> + * + * @since TBD + */ +public final class OnChangeTransformer implements Supplier<Path> { + private final Supplier<Path> source; + + private final Path target; + + private final Function<Path, String> stateFunction; + + private final BiConsumer<Path, Path> transformerConsumer; + + private final AtomicReference<String> sourceState; + + public OnChangeTransformer( + Supplier<Path> source, + Path target, + Function<Path, String> stateFunction, + BiConsumer<Path, Path> transformerConsumer) { + this.source = requireNonNull(source); + this.target = requireNonNull(target); + this.stateFunction = requireNonNull(stateFunction); + this.transformerConsumer = requireNonNull(transformerConsumer); + this.sourceState = new AtomicReference<>(null); + } + + @Override + public synchronized Path get() { + String state = mayUpdate(); + if (state == null) { + return null; + } + return target; + } + + private String mayUpdate() { + String result; + try { + Path src = source.get(); + if (src == null) { + Files.deleteIfExists(target); + result = null; + } else if (!Files.exists(src)) { + Files.deleteIfExists(target); + result = ""; + } else { + String current = stateFunction.apply(src); + String existing = sourceState.get(); + if (!Objects.equals(current, existing)) { + transformerConsumer.accept(src, target); + Files.setLastModifiedTime(target, Files.getLastModifiedTime(src)); Review Comment: Would it make sense to copy all attributes? ########## maven-core/src/main/java/org/apache/maven/internal/transformation/ArtifactTransformer.java: ########## @@ -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.maven.internal.transformation; + +import java.io.IOException; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.deployment.DeployRequest; +import org.eclipse.aether.installation.InstallRequest; + +/** + * Artifact transformer component. + * <p> + * Note: this interface is Maven internal component, subject to change or removal without notice. + * + * @since TBD + */ +public interface ArtifactTransformer { + void injectTransformedArtifacts(MavenProject project, RepositorySystemSession session) throws IOException; Review Comment: Add an empty line for readability. ########## maven-core/src/main/java/org/apache/maven/internal/transformation/TransformedArtifact.java: ########## @@ -0,0 +1,145 @@ +/* + * 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.maven.internal.transformation; + +import static java.util.Objects.requireNonNull; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.util.function.BiConsumer; +import java.util.function.Supplier; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.ArtifactHandler; + +/** + * Transformed artifact is derived with some transformation from source artifact. + * + * @since TBD + */ +public abstract class TransformedArtifact extends DefaultArtifact { + private final OnChangeTransformer onChangeTransformer; + + public TransformedArtifact( + Artifact source, + Supplier<Path> sourcePathProvider, + String classifier, + String extension, + Path targetPath, + BiConsumer<Path, Path> transformerConsumer) { + super( + source.getGroupId(), + source.getArtifactId(), + source.getVersionRange(), + source.getScope(), + extension, + classifier, + new TransformedArtifactHandler( + classifier, extension, source.getArtifactHandler().getPackaging())); + this.onChangeTransformer = + new OnChangeTransformer(sourcePathProvider, targetPath, TransformedArtifact::sha1, transformerConsumer); + } + + @Override + public boolean isResolved() { + return getFile() != null; + } + + @Override + public void setFile(File file) { + throw new IllegalStateException("transformed artifact file cannot be set"); + } + + @Override + public File getFile() { + Path result = onChangeTransformer.get(); + if (result == null) { + return null; + } + return result.toFile(); + } + + private static final int BUFFER_SIZE = 8192; + + private static String sha1(Path path) { + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + try (InputStream fis = new BufferedInputStream(Files.newInputStream(path), BUFFER_SIZE)) { + byte[] buffer = new byte[BUFFER_SIZE]; + int read; + while ((read = fis.read(buffer)) != -1) { + md.update(buffer, 0, read); + } + } + StringBuilder result = new StringBuilder(); + for (byte b : md.digest()) { + result.append(String.format("%02x", b)); + } + return result.toString(); Review Comment: Ouch, we have done this over and over :-( ########## maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java: ########## @@ -110,24 +107,6 @@ public MavenExecutionPlan resolveBuildPlan( lifecycleDebugLogger.debugProjectPlan(project, executionPlan); - // With Maven 4's build/consumer the POM will always rewrite during distribution. - // The maven-gpg-plugin uses the original POM, causing an invalid signature. - // Fail as long as there's no solution available yet - Properties userProperties = session.getUserProperties(); - if (Features.buildConsumer(userProperties).isActive()) { - Optional<MojoExecution> gpgMojo = executionPlan.getMojoExecutions().stream() - .filter(m -> "maven-gpg-plugin".equals(m.getArtifactId()) - && "org.apache.maven.plugins".equals(m.getGroupId())) - .findAny(); - - if (gpgMojo.isPresent()) { - throw new LifecycleExecutionException("The maven-gpg-plugin is not supported by Maven 4." - + " Verify if there is a compatible signing solution," - + " add -D" + Features.buildConsumer(userProperties).propertyName() + "=false" - + " or use Maven 3."); - } - } Review Comment: This now works because it uses a temp file which GPG can use? ########## maven-core/src/main/java/org/apache/maven/internal/transformation/TransformedArtifact.java: ########## @@ -0,0 +1,145 @@ +/* + * 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.maven.internal.transformation; + +import static java.util.Objects.requireNonNull; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.util.function.BiConsumer; +import java.util.function.Supplier; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.ArtifactHandler; + +/** + * Transformed artifact is derived with some transformation from source artifact. + * + * @since TBD + */ +public abstract class TransformedArtifact extends DefaultArtifact { + private final OnChangeTransformer onChangeTransformer; Review Comment: here as well ########## maven-core/src/main/java/org/apache/maven/internal/transformation/TransformedArtifact.java: ########## @@ -0,0 +1,145 @@ +/* + * 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.maven.internal.transformation; + +import static java.util.Objects.requireNonNull; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.util.function.BiConsumer; +import java.util.function.Supplier; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.ArtifactHandler; + +/** + * Transformed artifact is derived with some transformation from source artifact. + * + * @since TBD + */ +public abstract class TransformedArtifact extends DefaultArtifact { + private final OnChangeTransformer onChangeTransformer; + + public TransformedArtifact( + Artifact source, + Supplier<Path> sourcePathProvider, + String classifier, + String extension, + Path targetPath, + BiConsumer<Path, Path> transformerConsumer) { + super( + source.getGroupId(), + source.getArtifactId(), + source.getVersionRange(), + source.getScope(), + extension, + classifier, + new TransformedArtifactHandler( + classifier, extension, source.getArtifactHandler().getPackaging())); + this.onChangeTransformer = + new OnChangeTransformer(sourcePathProvider, targetPath, TransformedArtifact::sha1, transformerConsumer); + } + + @Override + public boolean isResolved() { + return getFile() != null; + } + + @Override + public void setFile(File file) { + throw new IllegalStateException("transformed artifact file cannot be set"); + } + + @Override + public File getFile() { + Path result = onChangeTransformer.get(); + if (result == null) { + return null; + } + return result.toFile(); + } + + private static final int BUFFER_SIZE = 8192; + + private static String sha1(Path path) { + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + try (InputStream fis = new BufferedInputStream(Files.newInputStream(path), BUFFER_SIZE)) { + byte[] buffer = new byte[BUFFER_SIZE]; + int read; + while ((read = fis.read(buffer)) != -1) { + md.update(buffer, 0, read); + } + } + StringBuilder result = new StringBuilder(); + for (byte b : md.digest()) { + result.append(String.format("%02x", b)); + } + return result.toString(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static class TransformedArtifactHandler implements ArtifactHandler { + private final String classifier; Review Comment: here as well > Reimplement Consumer POM feature > -------------------------------- > > Key: MNG-7622 > URL: https://issues.apache.org/jira/browse/MNG-7622 > Project: Maven > Issue Type: Task > Components: build/consumer > Reporter: Tamas Cservenak > Priority: Major > Fix For: 4.0.x-candidate > > > Current implementation relies on deprecated resolver API (is deprecated as it > is OOM prone), and also renders use cases like m-gpg-p but also checksum-m-p > broken. > Reimplement consumer POM feature that: > * does not use FileTransformer API > * allows use cases like m-gpg-p -- This message was sent by Atlassian Jira (v8.20.10#820010)