* Please understand that the source shading feature is not meant as a source code generator anyway, merely as a
* tool creating reasonably plausible source code when navigating to a relocated library class from an IDE,
* hopefully displaying source code which makes 95% sense - no more, no less.
*/
@Parameter(property = "shadeSourcesContent", defaultValue = "false")
private boolean shadeSourcesContent;
/**
* When true, dependencies will be stripped down on the class level to only the transitive hull required for the
* artifact. See also {@link #entryPoints}, if you wish to further optimize JAR minimization.
*
entryPoints;
/**
* The path to the output file for the shaded artifact. When this parameter is set, the created archive will neither
* replace the project's main artifact nor will it be attached. Hence, this parameter causes the parameters
* {@link #finalName}, {@link #shadedArtifactAttached}, {@link #shadedClassifierName} and
* {@link #createDependencyReducedPom} to be ignored when used.
*
* @since 1.3
*/
@Parameter
private File outputFile;
/**
* You can pass here the roleHint about your own Shader implementation plexus component.
*
* @since 1.6
*/
@Parameter
private String shaderHint;
/**
* When true, the version of each dependency of the reduced pom will be based on the baseVersion of the original
* dependency instead of its resolved version. For example, if the original pom (transitively) depends on
* a:a:2.7-SNAPSHOT, if useBaseVersion is set to false, the reduced pom will depend on a:a:2.7-20130312.222222-12
* whereas if useBaseVersion is set to true, the reduced pom will depend on a:a:2.7-SNAPSHOT
*
* @since 3.0
*/
@Parameter(defaultValue = "false")
private boolean useBaseVersion;
/**
* When true, creates a shaded test-jar artifact as well.
*/
@Parameter(defaultValue = "false")
private boolean shadeTestJar;
/**
* When true, skips the execution of this MOJO.
* @since 3.3.0
*/
@Parameter(defaultValue = "false")
private boolean skip;
/**
* Extra JAR files to infuse into shaded result. Accepts list of files that must exists. If any of specified
* files does not exist (or is not a file), Mojo will fail.
*
* Extra JARs will be processed in same way as main JAR (if any) is: applied relocation, resource transformers
* but not filtering.
*
* Note: this feature should be used lightly, is not meant as ability to replace dependency hull! It is more
* just a feature to be able to slightly "differentiate" shaded JAR from main only.
*
* @since 3.6.0
*/
@Parameter
private List extraJars;
/**
* Extra Artifacts to infuse into shaded result. Accepts list of GAVs in form of
* {@code :[:[:]]:} that will be resolved. If any of them
* cannot be resolved, Mojo will fail.
*
* The artifacts will be resolved (not transitively), and will be processed in same way as dependency JARs
* are (if any): applied relocation, resource transformers and filtering.
*
* Note: this feature should be used lightly, is not meant as ability to replace dependency hull! It is more
* just a feature to be able to slightly "differentiate" shaded JAR from main only.
*
* @since 3.6.0
*/
@Parameter
private List extraArtifacts;
@Inject
private MavenProjectHelper projectHelper;
@Inject
private Shader shader;
@Inject
private RepositorySystem repositorySystem;
/**
* ProjectBuilder, needed to create projects from the artifacts.
*/
@Inject
private ProjectBuilder projectBuilder;
/**
* All the present Shaders.
*/
@Inject
private Map shaders;
/**
* @throws MojoExecutionException in case of an error.
*/
@SuppressWarnings("checkstyle:methodlength")
@Override
public void execute() throws MojoExecutionException {
if (skip) {
getLog().info("Shading has been skipped.");
return;
}
setupHintedShader();
Set artifacts = new LinkedHashSet<>();
Set artifactIds = new LinkedHashSet<>();
Set sourceArtifacts = new LinkedHashSet<>();
Set testArtifacts = new LinkedHashSet<>();
Set testSourceArtifacts = new LinkedHashSet<>();
ArtifactSelector artifactSelector = new ArtifactSelector(project.getArtifact(), artifactSet, shadedGroupFilter);
if (artifactSelector.isSelected(project.getArtifact())
&& !"pom".equals(project.getArtifact().getType())) {
if (invalidMainArtifact()) {
createErrorOutput();
throw new MojoExecutionException(
"Failed to create shaded artifact, " + "project main artifact does not exist.");
}
artifacts.add(project.getArtifact().getFile());
if (extraJars != null && !extraJars.isEmpty()) {
for (File extraJar : extraJars) {
if (!Files.isRegularFile(extraJar.toPath())) {
throw new MojoExecutionException(
"Failed to create shaded artifact: parameter extraJars contains path " + extraJar
+ " that is not a file (does not exist or is not a file)");
}
artifacts.add(extraJar);
}
}
if (createSourcesJar) {
File file = shadedSourcesArtifactFile();
if (file.isFile()) {
sourceArtifacts.add(file);
}
}
if (shadeTestJar) {
File file = shadedTestArtifactFile();
if (file.isFile()) {
testArtifacts.add(file);
}
}
if (createTestSourcesJar) {
File file = shadedTestSourcesArtifactFile();
if (file.isFile()) {
testSourceArtifacts.add(file);
}
}
}
List processedArtifacts = processArtifactSelectors(
artifacts, artifactIds, sourceArtifacts, testArtifacts, testSourceArtifacts, artifactSelector);
File outputJar = (outputFile != null) ? outputFile : shadedArtifactFileWithClassifier();
File sourcesJar = shadedSourceArtifactFileWithClassifier();
File testJar = shadedTestArtifactFileWithClassifier();
File testSourcesJar = shadedTestSourceArtifactFileWithClassifier();
// Now add our extra resources
try {
List filters = getFilters(processedArtifacts);
List relocators = getRelocators();
List resourceTransformers = getResourceTransformers();
if (createDependencyReducedPom) {
createDependencyReducedPom(artifactIds);
if (useDependencyReducedPomInJar) {
// In some cases the used implementation of the resourceTransformers is immutable.
resourceTransformers = new ArrayList<>(resourceTransformers);
resourceTransformers.addAll(createPomReplaceTransformers(project, dependencyReducedPomLocation));
}
}
ShadeRequest shadeRequest =
shadeRequest("jar", artifacts, outputJar, filters, relocators, resourceTransformers);
shader.shade(shadeRequest);
if (createSourcesJar) {
ShadeRequest shadeSourcesRequest = createShadeSourcesRequest(
"sources-jar", sourceArtifacts, sourcesJar, filters, relocators, resourceTransformers);
shader.shade(shadeSourcesRequest);
}
if (shadeTestJar) {
ShadeRequest shadeTestRequest =
shadeRequest("test-jar", testArtifacts, testJar, filters, relocators, resourceTransformers);
shader.shade(shadeTestRequest);
}
if (createTestSourcesJar) {
ShadeRequest shadeTestSourcesRequest = createShadeSourcesRequest(
"test-sources-jar",
testSourceArtifacts,
testSourcesJar,
filters,
relocators,
resourceTransformers);
shader.shade(shadeTestSourcesRequest);
}
if (outputFile == null) {
boolean renamed = false;
// rename the output file if a specific finalName is set
// but don't rename if the finalName is the
// because this will be handled implicitly later
if (finalName != null
&& finalName.length() > 0 //
&& !finalName.equals(project.getBuild().getFinalName())) {
String finalFileName = finalName + "."
+ project.getArtifact().getArtifactHandler().getExtension();
File finalFile = new File(outputDirectory, finalFileName);
replaceFile(finalFile, outputJar);
outputJar = finalFile;
// Also support the sources JAR
if (createSourcesJar) {
finalFileName = finalName + "-sources.jar";
finalFile = new File(outputDirectory, finalFileName);
replaceFile(finalFile, sourcesJar);
sourcesJar = finalFile;
}
// Also support the test JAR
if (shadeTestJar) {
finalFileName = finalName + "-tests.jar";
finalFile = new File(outputDirectory, finalFileName);
replaceFile(finalFile, testJar);
testJar = finalFile;
}
if (createTestSourcesJar) {
finalFileName = finalName + "-test-sources.jar";
finalFile = new File(outputDirectory, finalFileName);
replaceFile(finalFile, testSourcesJar);
testSourcesJar = finalFile;
}
renamed = true;
}
if (shadedArtifactAttached) {
getLog().info("Attaching shaded artifact.");
projectHelper.attachArtifact(
project, project.getArtifact().getType(), shadedClassifierName, outputJar);
if (createSourcesJar) {
projectHelper.attachArtifact(
project, "java-source", shadedClassifierName + "-sources", sourcesJar);
}
if (shadeTestJar) {
projectHelper.attachArtifact(project, "test-jar", shadedClassifierName + "-tests", testJar);
}
if (createTestSourcesJar) {
projectHelper.attachArtifact(
project, "java-source", shadedClassifierName + "-test-sources", testSourcesJar);
}
} else if (!renamed) {
getLog().info("Replacing original artifact with shaded artifact.");
File originalArtifact = project.getArtifact().getFile();
if (originalArtifact != null) {
replaceFile(originalArtifact, outputJar);
if (createSourcesJar) {
getLog().info("Replacing original source artifact with shaded source artifact.");
File shadedSources = shadedSourcesArtifactFile();
replaceFile(shadedSources, sourcesJar);
projectHelper.attachArtifact(project, "java-source", "sources", shadedSources);
}
if (shadeTestJar) {
getLog().info("Replacing original test artifact with shaded test artifact.");
File shadedTests = shadedTestArtifactFile();
replaceFile(shadedTests, testJar);
projectHelper.attachArtifact(project, "test-jar", shadedTests);
}
if (createTestSourcesJar) {
getLog().info("Replacing original test source artifact "
+ "with shaded test source artifact.");
File shadedTestSources = shadedTestSourcesArtifactFile();
replaceFile(shadedTestSources, testSourcesJar);
projectHelper.attachArtifact(project, "java-source", "test-sources", shadedTestSources);
}
}
}
}
} catch (Exception e) {
throw new MojoExecutionException("Error creating shaded jar: " + e.getMessage(), e);
}
}
private void createErrorOutput() {
getLog().error("The project main artifact does not exist. This could have the following");
getLog().error("reasons:");
getLog().error("- You have invoked the goal directly from the command line. This is not");
getLog().error(" supported. Please add the goal to the default lifecycle via an");
getLog().error(" element in your POM and use \"mvn package\" to have it run.");
getLog().error("- You have bound the goal to a lifecycle phase before \"package\". Please");
getLog().error(" remove this binding from your POM such that the goal will be run in");
getLog().error(" the proper phase.");
getLog().error("- You removed the configuration of the maven-jar-plugin that produces the main artifact.");
}
private ShadeRequest shadeRequest(
String shade,
Set artifacts,
File outputJar,
List filters,
List relocators,
List resourceTransformers) {
ShadeRequest shadeRequest = new ShadeRequest();
shadeRequest.setJars(artifacts);
shadeRequest.setUberJar(outputJar);
shadeRequest.setFilters(filters);
shadeRequest.setRelocators(relocators);
shadeRequest.setResourceTransformers(toResourceTransformers(shade, resourceTransformers));
return shadeRequest;
}
private ShadeRequest createShadeSourcesRequest(
String shade,
Set testArtifacts,
File testJar,
List filters,
List relocators,
List resourceTransformers) {
ShadeRequest shadeSourcesRequest =
shadeRequest(shade, testArtifacts, testJar, filters, relocators, resourceTransformers);
shadeSourcesRequest.setShadeSourcesContent(shadeSourcesContent);
return shadeSourcesRequest;
}
private void setupHintedShader() throws MojoExecutionException {
if (shaderHint != null) {
shader = shaders.get(shaderHint);
if (shader == null) {
throw new MojoExecutionException(
"unable to lookup own Shader implementation with hint: '" + shaderHint + "'");
}
}
}
private List processArtifactSelectors(
Set artifacts,
Set artifactIds,
Set sourceArtifacts,
Set testArtifacts,
Set testSourceArtifacts,
ArtifactSelector artifactSelector)
throws MojoExecutionException {
List excludedArtifacts = new ArrayList<>();
List pomArtifacts = new ArrayList<>();
List emptySourceArtifacts = new ArrayList<>();
List emptyTestArtifacts = new ArrayList<>();
List emptyTestSourceArtifacts = new ArrayList<>();
ArrayList processedArtifacts = new ArrayList<>();
if (extraArtifacts != null && !extraArtifacts.isEmpty()) {
processedArtifacts.addAll(extraArtifacts.stream()
.map(org.eclipse.aether.artifact.DefaultArtifact::new)
.map(RepositoryUtils::toArtifact)
.collect(Collectors.toList()));
for (Artifact artifact : processedArtifacts) {
try {
org.eclipse.aether.artifact.Artifact resolved =
resolveArtifact(RepositoryUtils.toArtifact(artifact));
if (resolved.getFile() != null) {
artifact.setFile(resolved.getFile());
}
} catch (ArtifactResolutionException e) {
throw new MojoExecutionException(
"Failed to create shaded artifact: parameter extraArtifacts contains artifact "
+ artifact.getId() + " that is not resolvable",
e);
}
}
}
processedArtifacts.addAll(project.getArtifacts());
// for loop over COPY; as we add to the list in this loop
for (Artifact artifact : new ArrayList<>(processedArtifacts)) {
if (!artifactSelector.isSelected(artifact)) {
excludedArtifacts.add(artifact);
continue;
}
if ("pom".equals(artifact.getType())) {
pomArtifacts.add(artifact);
continue;
}
getLog().debug("Including " + artifact.getId() + " in the shaded jar.");
artifacts.add(artifact.getFile());
artifactIds.add(getId(artifact));
if (createSourcesJar) {
Artifact sources = resolveArtifactForClassifier(artifact, "sources");
if (sources != null) {
if (sources.getFile().length() > 0) {
sourceArtifacts.add(sources.getFile());
processedArtifacts.add(sources);
} else {
emptySourceArtifacts.add(artifact);
}
}
}
if (shadeTestJar) {
Artifact tests = resolveArtifactForClassifier(artifact, "tests");
if (tests != null) {
if (tests.getFile().length() > 0) {
testArtifacts.add(tests.getFile());
processedArtifacts.add(tests);
} else {
emptyTestArtifacts.add(artifact);
}
}
}
if (createTestSourcesJar) {
Artifact testSources = resolveArtifactForClassifier(artifact, "test-sources");
if (testSources != null) {
testSourceArtifacts.add(testSources.getFile());
processedArtifacts.add(testSources);
} else {
emptyTestSourceArtifacts.add(artifact);
}
}
}
processedArtifacts.removeAll(excludedArtifacts);
processedArtifacts.removeAll(pomArtifacts);
processedArtifacts.removeAll(emptySourceArtifacts);
processedArtifacts.removeAll(emptyTestArtifacts);
processedArtifacts.removeAll(emptyTestSourceArtifacts);
for (Artifact artifact : excludedArtifacts) {
getLog().debug("Excluding " + artifact.getId() + " from the shaded jar.");
}
for (Artifact artifact : pomArtifacts) {
getLog().debug("Skipping pom dependency " + artifact.getId() + " in the shaded jar.");
}
for (Artifact artifact : emptySourceArtifacts) {
getLog().warn("Skipping empty source jar " + artifact.getId() + ".");
}
for (Artifact artifact : emptyTestArtifacts) {
getLog().warn("Skipping empty test jar " + artifact.getId() + ".");
}
for (Artifact artifact : emptyTestSourceArtifacts) {
getLog().warn("Skipping empty test source jar " + artifact.getId() + ".");
}
return processedArtifacts;
}
private boolean invalidMainArtifact() {
return project.getArtifact().getFile() == null
|| !project.getArtifact().getFile().isFile();
}
private void replaceFile(File oldFile, File newFile) throws MojoExecutionException {
getLog().debug("Replacing " + oldFile + " with " + newFile);
File origFile = new File(outputDirectory, "original-" + oldFile.getName());
if (oldFile.exists() && !oldFile.renameTo(origFile)) {
// try a gc to see if an unclosed stream needs garbage collecting
System.gc();
System.gc();
if (!oldFile.renameTo(origFile)) {
// Still didn't work. We'll do a copy
try {
copyFiles(oldFile, origFile);
} catch (IOException ex) {
// kind of ignorable here. We're just trying to save the original
getLog().warn(ex);
}
}
}
if (!newFile.renameTo(oldFile)) {
// try a gc to see if an unclosed stream needs garbage collecting
System.gc();
System.gc();
if (!newFile.renameTo(oldFile)) {
// Still didn't work. We'll do a copy
try {
copyFiles(newFile, oldFile);
} catch (IOException ex) {
throw new MojoExecutionException("Could not replace original artifact with shaded artifact!", ex);
}
}
}
}
private void copyFiles(File source, File target) throws IOException {
try (InputStream in = Files.newInputStream(source.toPath());
OutputStream out = Files.newOutputStream(target.toPath())) {
IOUtil.copy(in, out);
}
}
private Artifact resolveArtifactForClassifier(Artifact artifact, String classifier) {
Artifact toResolve = new DefaultArtifact(
artifact.getGroupId(),
artifact.getArtifactId(),
artifact.getVersionRange() == null
? VersionRange.createFromVersion(artifact.getVersion())
: artifact.getVersionRange(),
artifact.getScope(),
artifact.getType(),
classifier,
artifact.getArtifactHandler(),
artifact.isOptional());
try {
org.eclipse.aether.artifact.Artifact resolved = resolveArtifact(RepositoryUtils.toArtifact(toResolve));
if (resolved.getFile() != null) {
toResolve.setFile(resolved.getFile());
return toResolve;
}
return null;
} catch (ArtifactResolutionException e) {
getLog().warn("Could not get " + classifier + " for " + artifact);
return null;
}
}
private org.eclipse.aether.artifact.Artifact resolveArtifact(org.eclipse.aether.artifact.Artifact artifact)
throws ArtifactResolutionException {
return repositorySystem
.resolveArtifact(
session.getRepositorySession(),
new ArtifactRequest(artifact, project.getRemoteProjectRepositories(), "shade"))
.getArtifact();
}
private List getRelocators() {
List relocators = new ArrayList<>();
if (relocations == null) {
return relocators;
}
for (PackageRelocation r : relocations) {
relocators.add(new SimpleRelocator(
r.getPattern(), r.getShadedPattern(), r.getIncludes(), r.getExcludes(), r.isRawString()));
if (r.isShadeSerializedLambda()) {
relocators.add(new SerializedLambdaRelocator(
r.getPattern(), r.getShadedPattern(), r.getIncludes(), r.getExcludes(), r.isRawString()));
}
}
return relocators;
}
private List getResourceTransformers() throws MojoExecutionException {
if (transformers == null) {
return Collections.emptyList();
}
for (ResourceTransformer transformer : transformers) {
if (transformer == null) {
throw new MojoExecutionException(
"Failed to create shaded artifact: parameter transformers contains null (double-check XML attribute)");
}
}
return Arrays.asList(transformers);
}
private List getFilters(List artifactCollection) throws MojoExecutionException {
List filters = new ArrayList<>();
List simpleFilters = new ArrayList<>();
if (this.filters != null && this.filters.length > 0) {
Map artifacts = new HashMap<>();
// artifactCollection does not contain project; that must also be subjected to filtering
artifacts.put(project.getArtifact(), new ArtifactId(project.getArtifact()));
for (Artifact artifact : artifactCollection) {
artifacts.put(artifact, new ArtifactId(artifact));
}
for (ArchiveFilter filter : this.filters) {
ArtifactId pattern = new ArtifactId(filter.getArtifact());
Set jars = new HashSet<>();
for (Map.Entry entry : artifacts.entrySet()) {
if (entry.getValue().matches(pattern)) {
Artifact artifact = entry.getKey();
jars.add(artifact.getFile());
if (createSourcesJar) {
Artifact sources = resolveArtifactForClassifier(artifact, "sources");
if (sources != null) {
jars.add(sources.getFile());
}
}
if (shadeTestJar) {
Artifact tests = resolveArtifactForClassifier(artifact, "tests");
if (tests != null) {
jars.add(tests.getFile());
}
}
}
}
if (jars.isEmpty()) {
getLog().debug("No artifact matching filter " + filter.getArtifact());
continue;
}
simpleFilters.add(new SimpleFilter(jars, filter));
}
}
filters.addAll(simpleFilters);
if (minimizeJar) {
if (entryPoints == null) {
entryPoints = new HashSet<>();
}
getLog().info("Minimizing jar " + project.getArtifact()
+ (entryPoints.isEmpty() ? "" : " with entry points"));
try {
filters.add(new MinijarFilter(project, getLog(), simpleFilters, entryPoints));
} catch (IOException e) {
throw new MojoExecutionException("Failed to analyze class dependencies", e);
}
}
return filters;
}
private File shadedArtifactFileWithClassifier() {
Artifact artifact = project.getArtifact();
final String shadedName = shadedArtifactId + "-" + artifact.getVersion() + "-" + shadedClassifierName + "."
+ artifact.getArtifactHandler().getExtension();
return new File(outputDirectory, shadedName);
}
private File shadedSourceArtifactFileWithClassifier() {
return shadedArtifactFileWithClassifier("sources");
}
private File shadedTestSourceArtifactFileWithClassifier() {
return shadedArtifactFileWithClassifier("test-sources");
}
private File shadedArtifactFileWithClassifier(String classifier) {
Artifact artifact = project.getArtifact();
final String shadedName = shadedArtifactId + "-" + artifact.getVersion() + "-" + shadedClassifierName + "-"
+ classifier + "." + artifact.getArtifactHandler().getExtension();
return new File(outputDirectory, shadedName);
}
private File shadedTestArtifactFileWithClassifier() {
return shadedArtifactFileWithClassifier("tests");
}
private File shadedSourcesArtifactFile() {
return shadedArtifactFile("sources");
}
private File shadedTestSourcesArtifactFile() {
return shadedArtifactFile("test-sources");
}
private File shadedArtifactFile(String classifier) {
Artifact artifact = project.getArtifact();
String shadedName;
if (project.getBuild().getFinalName() != null) {
shadedName = project.getBuild().getFinalName() + "-" + classifier + "."
+ artifact.getArtifactHandler().getExtension();
} else {
shadedName = shadedArtifactId + "-" + artifact.getVersion() + "-" + classifier + "."
+ artifact.getArtifactHandler().getExtension();
}
return new File(outputDirectory, shadedName);
}
private File shadedTestArtifactFile() {
return shadedArtifactFile("tests");
}
// We need to find the direct dependencies that have been included in the uber JAR so that we can modify the
// POM accordingly.
private void createDependencyReducedPom(Set artifactsToRemove)
throws IOException, ProjectBuildingException, DependencyCollectionException {
List transitiveDeps = new ArrayList<>();
// NOTE: By using the getArtifacts() we get the completely evaluated artifacts
// including the system scoped artifacts with expanded values of properties used.
for (Artifact artifact : project.getArtifacts()) {
if ("pom".equals(artifact.getType())) {
// don't include pom type dependencies in dependency reduced pom
continue;
}
// promote
Dependency dep = createDependency(artifact);
// we'll figure out the exclusions in a bit.
transitiveDeps.add(dep);
}
Model model = project.getOriginalModel();
// MSHADE-413: Must not use objects (for example `Model` or `Dependency`) that are "owned
// by Maven" and being used by other projects/plugins. Modifying those will break the
// correctness of the build - or cause an endless loop.
List origDeps = new ArrayList<>();
List source = promoteTransitiveDependencies ? transitiveDeps : project.getDependencies();
for (Dependency d : source) {
origDeps.add(d.clone());
}
model = model.clone();
// MSHADE-185: We will remove all system scoped dependencies which usually
// have some kind of property usage. At this time the properties within
// such things are already evaluated.
List originalDependencies = model.getDependencies();
removeSystemScopedDependencies(artifactsToRemove, originalDependencies);
List dependencies = new ArrayList<>();
boolean modified = false;
for (Dependency d : origDeps) {
if (artifactsToRemove.contains(getId(d))) {
if (keepDependenciesWithProvidedScope) {
if (!"provided".equals(d.getScope())) {
modified = true;
d.setScope("provided");
}
} else {
modified = true;
continue;
}
}
dependencies.add(d);
}
// MSHADE-155
model.setArtifactId(shadedArtifactId);
// MSHADE-185: We will add those system scoped dependencies
// from the non interpolated original pom file. So we keep
// things like this: ${tools.jar} intact.
addSystemScopedDependencyFromNonInterpolatedPom(dependencies, originalDependencies);
// Check to see if we have a reduction and if so rewrite the POM.
rewriteDependencyReducedPomIfWeHaveReduction(dependencies, modified, transitiveDeps, model);
}
private void rewriteDependencyReducedPomIfWeHaveReduction(
List dependencies, boolean modified, List transitiveDeps, Model model)
throws IOException, ProjectBuildingException, DependencyCollectionException {
if (modified) {
for (int loopCounter = 0; modified; loopCounter++) {
model.setDependencies(dependencies);
if (generateUniqueDependencyReducedPom) {
dependencyReducedPomLocation = Files.createTempFile(
project.getBasedir().toPath(), "dependency-reduced-pom-", ".xml")
.toFile();
project.getProperties()
.setProperty(
"maven.shade.dependency-reduced-pom",
dependencyReducedPomLocation.getAbsolutePath());
} else {
if (dependencyReducedPomLocation == null) {
// MSHADE-123: We can't default to 'target' because it messes up uses of ${project.basedir}
dependencyReducedPomLocation = new File(project.getBasedir(), "dependency-reduced-pom.xml");
}
}
File f = dependencyReducedPomLocation;
// MSHADE-225
// Works for now, maybe there's a better algorithm where no for-loop is required
if (loopCounter == 0) {
getLog().info("Dependency-reduced POM written at: " + f.getAbsolutePath());
}
if (f.exists()) {
// noinspection ResultOfMethodCallIgnored
f.delete();
}
Writer w = WriterFactory.newXmlWriter(f);
String replaceRelativePath = null;
if (model.getParent() != null) {
replaceRelativePath = model.getParent().getRelativePath();
}
if (model.getParent() != null) {
File parentFile =
new File(project.getBasedir(), model.getParent().getRelativePath()).getCanonicalFile();
if (!parentFile.isFile()) {
parentFile = new File(parentFile, "pom.xml");
}
parentFile = parentFile.getCanonicalFile();
String relPath = RelativizePath.convertToRelativePath(parentFile, f);
model.getParent().setRelativePath(relPath);
}
try {
PomWriter.write(w, model, true);
} finally {
if (model.getParent() != null) {
model.getParent().setRelativePath(replaceRelativePath);
}
w.close();
}
synchronized (session.getProjectBuildingRequest()) { // Lock critical section to fix MSHADE-467
ProjectBuildingRequest projectBuildingRequest =
new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
projectBuildingRequest.setLocalRepository(session.getLocalRepository());
projectBuildingRequest.setRemoteRepositories(project.getRemoteArtifactRepositories());
ProjectBuildingResult result = projectBuilder.build(f, projectBuildingRequest);
getLog().debug("updateExcludesInDeps()");
modified = updateExcludesInDeps(result.getProject(), dependencies, transitiveDeps);
}
}
project.setFile(dependencyReducedPomLocation);
}
}
private void removeSystemScopedDependencies(Set artifactsToRemove, List originalDependencies) {
for (Dependency dependency : originalDependencies) {
if (dependency.getScope() != null && dependency.getScope().equalsIgnoreCase("system")) {
artifactsToRemove.add(getId(dependency));
}
}
}
private void addSystemScopedDependencyFromNonInterpolatedPom(
List dependencies, List originalDependencies) {
for (Dependency dependency : originalDependencies) {
if (dependency.getScope() != null && dependency.getScope().equalsIgnoreCase("system")) {
dependencies.add(dependency);
}
}
}
private Dependency createDependency(Artifact artifact) {
Dependency dep = new Dependency();
dep.setArtifactId(artifact.getArtifactId());
if (artifact.hasClassifier()) {
dep.setClassifier(artifact.getClassifier());
}
dep.setGroupId(artifact.getGroupId());
dep.setOptional(artifact.isOptional());
dep.setScope(artifact.getScope());
dep.setType(artifact.getType());
if (useBaseVersion) {
dep.setVersion(artifact.getBaseVersion());
} else {
dep.setVersion(artifact.getVersion());
}
return dep;
}
private String getId(Artifact artifact) {
return getId(artifact.getGroupId(), artifact.getArtifactId(), artifact.getType(), artifact.getClassifier());
}
private String getId(Dependency dependency) {
return getId(
dependency.getGroupId(), dependency.getArtifactId(), dependency.getType(), dependency.getClassifier());
}
private String getId(String groupId, String artifactId, String type, String classifier) {
return groupId + ":" + artifactId + ":" + type + ":" + ((classifier != null) ? classifier : "");
}
public boolean updateExcludesInDeps(
MavenProject project, List dependencies, List transitiveDeps)
throws DependencyCollectionException {
CollectRequest collectRequest = new CollectRequest();
collectRequest.setRootArtifact(RepositoryUtils.toArtifact(project.getArtifact()));
collectRequest.setRepositories(project.getRemoteProjectRepositories());
collectRequest.setDependencies(project.getDependencies().stream()
.map(d -> RepositoryUtils.toDependency(
d, session.getRepositorySession().getArtifactTypeRegistry()))
.collect(Collectors.toList()));
if (project.getDependencyManagement() != null) {
collectRequest.setManagedDependencies(project.getDependencyManagement().getDependencies().stream()
.map(d -> RepositoryUtils.toDependency(
d, session.getRepositorySession().getArtifactTypeRegistry()))
.collect(Collectors.toList()));
}
CollectResult result = repositorySystem.collectDependencies(session.getRepositorySession(), collectRequest);
boolean modified = false;
if (result.getRoot() != null) {
for (DependencyNode n2 : result.getRoot().getChildren()) {
String artifactId2 = getId(RepositoryUtils.toArtifact(n2.getArtifact()));
for (DependencyNode n3 : n2.getChildren()) {
// stupid m-a Artifact that has no idea what it is: dependency or artifact?
Artifact artifact3 = RepositoryUtils.toArtifact(n3.getArtifact());
artifact3.setScope(n3.getDependency().getScope());
String artifactId3 = getId(artifact3);
// check if it really isn't in the list of original dependencies. Maven
// prior to 2.0.8 may grab versions from transients instead of
// from the direct deps in which case they would be marked included
// instead of OMITTED_FOR_DUPLICATE
// also, if not promoting the transitives, level 2's would be included
boolean found = false;
for (Dependency dep : transitiveDeps) {
if (getId(dep).equals(artifactId3)) {
found = true;
break;
}
}
// MSHADE-311: do not add exclusion for provided transitive dep
// note: MSHADE-31 introduced the exclusion logic for promoteTransitiveDependencies=true,
// but as of 3.2.1 promoteTransitiveDependencies has no effect for provided deps,
// which makes this fix even possible (see also MSHADE-181)
if (!found && !"provided".equals(artifact3.getScope())) {
getLog().debug(String.format(
"dependency %s (scope %s) not found in transitive dependencies",
artifactId3, artifact3.getScope()));
for (Dependency dep : dependencies) {
if (getId(dep).equals(artifactId2)) {
// MSHADE-413: First check whether the exclusion has already been added,
// because it's meaningless to add it more than once. Certain cases
// can end up adding the exclusion "forever" and cause an endless loop
// rewriting the whole dependency-reduced-pom.xml file.
if (!dependencyHasExclusion(dep, artifact3)) {
getLog().debug(String.format(
"Adding exclusion for dependency %s (scope %s) " + "to %s (scope %s)",
artifactId3, artifact3.getScope(), getId(dep), dep.getScope()));
Exclusion exclusion = new Exclusion();
exclusion.setArtifactId(artifact3.getArtifactId());
exclusion.setGroupId(artifact3.getGroupId());
dep.addExclusion(exclusion);
modified = true;
break;
}
}
}
}
}
}
}
return modified;
}
private boolean dependencyHasExclusion(Dependency dep, Artifact exclusionToCheck) {
boolean containsExclusion = false;
for (Exclusion existingExclusion : dep.getExclusions()) {
if (existingExclusion.getGroupId().equals(exclusionToCheck.getGroupId())
&& existingExclusion.getArtifactId().equals(exclusionToCheck.getArtifactId())) {
containsExclusion = true;
break;
}
}
return containsExclusion;
}
private List toResourceTransformers(
String shade, List resourceTransformers) {
List forShade = new ArrayList<>();
ManifestResourceTransformer lastMt = null;
for (ResourceTransformer transformer : resourceTransformers) {
if (!(transformer instanceof ManifestResourceTransformer)) {
forShade.add(transformer);
} else if (((ManifestResourceTransformer) transformer).isForShade(shade)) {
final ManifestResourceTransformer mt = (ManifestResourceTransformer) transformer;
if (mt.isUsedForDefaultShading() && lastMt != null && !lastMt.isUsedForDefaultShading()) {
continue; // skip, we already have a specific transformer
}
if (!mt.isUsedForDefaultShading() && lastMt != null && lastMt.isUsedForDefaultShading()) {
forShade.remove(lastMt);
} else if (!mt.isUsedForDefaultShading() && lastMt != null) {
getLog().warn("Ambiguous manifest transformer definition for '" + shade + "': " + mt + " / "
+ lastMt);
}
if (lastMt == null || !mt.isUsedForDefaultShading()) {
lastMt = mt;
}
forShade.add(transformer);
}
}
return forShade;
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/pom/Counter.java
================================================
/*
* 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.plugins.shade.pom;
/**
* Separate class for counter.
*/
public class Counter {
// --------------------------/
// - Class/Member Variables -/
// --------------------------/
/**
* Field currentIndex
*/
private int currentIndex = 0;
/**
* Field level
*/
private int level;
// ----------------/
// - Constructors -/
// ----------------/
public Counter(int depthLevel) {
level = depthLevel;
} // -- org.apache.maven.model.io.jdom.Counter(int)
// -----------/
// - Methods -/
// -----------/
/**
* Method getCurrentIndex
*/
public int getCurrentIndex() {
return currentIndex;
} // -- int getCurrentIndex()
/**
* Method getDepth
* @return {@link #level}
*/
public int getDepth() {
return level;
} // -- int getDepth()
/**
* Method increaseCount
*/
public void increaseCount() {
currentIndex = currentIndex + 1;
} // -- void increaseCount()
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/pom/MavenJDOMWriter.java
================================================
/*
* 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.plugins.shade.pom;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.maven.model.ActivationFile;
import org.apache.maven.model.ActivationOS;
import org.apache.maven.model.ActivationProperty;
import org.apache.maven.model.Build;
import org.apache.maven.model.BuildBase;
import org.apache.maven.model.CiManagement;
import org.apache.maven.model.ConfigurationContainer;
import org.apache.maven.model.Contributor;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.DeploymentRepository;
import org.apache.maven.model.Developer;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Exclusion;
import org.apache.maven.model.Extension;
import org.apache.maven.model.FileSet;
import org.apache.maven.model.IssueManagement;
import org.apache.maven.model.License;
import org.apache.maven.model.MailingList;
import org.apache.maven.model.Model;
import org.apache.maven.model.ModelBase;
import org.apache.maven.model.Notifier;
import org.apache.maven.model.Organization;
import org.apache.maven.model.Parent;
import org.apache.maven.model.PatternSet;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginConfiguration;
import org.apache.maven.model.PluginContainer;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.PluginManagement;
import org.apache.maven.model.Prerequisites;
import org.apache.maven.model.Profile;
import org.apache.maven.model.Relocation;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.Repository;
import org.apache.maven.model.RepositoryBase;
import org.apache.maven.model.RepositoryPolicy;
import org.apache.maven.model.Resource;
import org.apache.maven.model.Scm;
import org.apache.maven.model.Site;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.jdom2.Content;
import org.jdom2.DefaultJDOMFactory;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Text;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
/**
* Class MavenJDOMWriter.
*
*/
public class MavenJDOMWriter {
/**
* Field factory
*/
private final DefaultJDOMFactory factory;
/**
* Field lineSeparator
*/
private final String lineSeparator;
public MavenJDOMWriter() {
this("\n");
}
public MavenJDOMWriter(final String lineSeparator) {
this.factory = new DefaultJDOMFactory();
this.lineSeparator = Objects.requireNonNull(lineSeparator);
}
/**
* Method findAndReplaceProperties
*
* @param counter {@link Counter}
* @param props {@link Map}
* @param name The name.
* @param parent {@link Element}
* @return {@link Element}
*/
protected Element findAndReplaceProperties(Counter counter, Element parent, String name, Map props) {
Map properties = props;
boolean shouldExist = properties != null && !properties.isEmpty();
Element element = updateElement(counter, parent, name, shouldExist);
if (shouldExist) {
Counter innerCounter = new Counter(counter.getDepth() + 1);
for (Map.Entry entry : properties.entrySet()) {
String key = entry.getKey();
findAndReplaceSimpleElement(innerCounter, element, key, entry.getValue(), null);
}
List lst = new ArrayList<>(properties.keySet());
Iterator it = element.getChildren().iterator();
while (it.hasNext()) {
Element elem = it.next();
String key = elem.getName();
if (!lst.contains(key)) {
it.remove();
}
}
}
return element;
}
/**
* Method findAndReplaceSimpleElement
*
* @param counter {@link Counter}
* @param defaultValue The default value.
* @param text The text.
* @param name The name.
* @param parent The parent.
* @return {@link Element}
*/
protected Element findAndReplaceSimpleElement(
Counter counter, Element parent, String name, String text, String defaultValue) {
if (defaultValue != null && text != null && defaultValue.equals(text)) {
Element element = parent.getChild(name, parent.getNamespace());
// if exist and is default value or if doesn't exist.. just keep the way it is..
if (element == null || defaultValue.equals(element.getText())) {
return element;
}
}
boolean shouldExist = text != null && text.trim().length() > 0;
Element element = updateElement(counter, parent, name, shouldExist);
if (shouldExist) {
element.setText(text);
}
return element;
}
/**
* Method findAndReplaceSimpleLists
*
* @param counter {@link Counter}
* @param childName The childName
* @param parentName The parentName
* @param list The list of elements.
* @param parent The parent.
* @return {@link Element}
*/
protected Element findAndReplaceSimpleLists(
Counter counter, Element parent, Collection list, String parentName, String childName) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentName, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childName, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (String value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childName, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
el.setText(value);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
return element;
}
/**
* Method findAndReplaceXpp3DOM
*
* @param counter {@link Counter}
* @param dom {@link Xpp3Dom}
* @param name The name.
* @param parent The parent.
* @return {@link Element}
*/
protected Element findAndReplaceXpp3DOM(Counter counter, Element parent, String name, Xpp3Dom dom) {
boolean shouldExist = dom != null && (dom.getChildCount() > 0 || dom.getValue() != null);
Element element = updateElement(counter, parent, name, shouldExist);
if (shouldExist) {
replaceXpp3DOM(element, dom, new Counter(counter.getDepth() + 1));
}
return element;
}
/**
* Method insertAtPreferredLocation
*
* @param parent The parent.
* @param counter {@link Counter}
* @param child {@link Element}
*/
protected void insertAtPreferredLocation(Element parent, Element child, Counter counter) {
int contentIndex = 0;
int elementCounter = 0;
Iterator it = parent.getContent().iterator();
Text lastText = null;
int offset = 0;
while (it.hasNext() && elementCounter <= counter.getCurrentIndex()) {
Object next = it.next();
offset = offset + 1;
if (next instanceof Element) {
elementCounter = elementCounter + 1;
contentIndex = contentIndex + offset;
offset = 0;
}
if (next instanceof Text && it.hasNext()) {
lastText = (Text) next;
}
}
if (lastText != null && lastText.getTextTrim().length() == 0) {
lastText = lastText.clone();
} else {
StringBuilder starter = new StringBuilder(lineSeparator);
for (int i = 0; i < counter.getDepth(); i++) {
starter.append(" "); // TODO make settable?
}
lastText = factory.text(starter.toString());
}
if (parent.getContentSize() == 0) {
Text finalText = lastText.clone();
finalText.setText(
finalText.getText().substring(0, finalText.getText().length() - " ".length()));
parent.addContent(contentIndex, finalText);
}
parent.addContent(contentIndex, child);
parent.addContent(contentIndex, lastText);
}
/**
* Method iterateContributor
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateContributor(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Contributor value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateContributor(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateDependency
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateDependency(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Dependency value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateDependency(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateDeveloper
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateDeveloper(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Developer value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateDeveloper(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateExclusion
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateExclusion(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Exclusion value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateExclusion(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateExtension
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateExtension(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Extension value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateExtension(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateLicense
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateLicense(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (License value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateLicense(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateMailingList
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateMailingList(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (MailingList value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateMailingList(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateNotifier
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateNotifier(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Notifier value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateNotifier(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iteratePlugin
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iteratePlugin(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Plugin value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updatePlugin(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iteratePluginExecution
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iteratePluginExecution(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (PluginExecution value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updatePluginExecution(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateProfile
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateProfile(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Profile value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateProfile(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateReportPlugin
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateReportPlugin(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (ReportPlugin value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateReportPlugin(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateReportSet
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateReportSet(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (ReportSet value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateReportSet(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateRepository
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateRepository(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Repository value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateRepository(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method iterateResource
*
* @param counter {@link Counter}
* @param childTag The childTag
* @param parentTag The parentTag
* @param list The list of elements.
* @param parent The parent.
*/
protected void iterateResource(
Counter counter, Element parent, Collection list, String parentTag, String childTag) {
boolean shouldExist = list != null && list.size() > 0;
Element element = updateElement(counter, parent, parentTag, shouldExist);
if (shouldExist) {
Iterator elIt =
element.getChildren(childTag, element.getNamespace()).iterator();
if (!elIt.hasNext()) {
elIt = null;
}
Counter innerCount = new Counter(counter.getDepth() + 1);
for (Resource value : list) {
Element el;
if (elIt != null && elIt.hasNext()) {
el = elIt.next();
if (!elIt.hasNext()) {
elIt = null;
}
} else {
el = factory.element(childTag, element.getNamespace());
insertAtPreferredLocation(element, el, innerCount);
}
updateResource(value, childTag, innerCount, el);
innerCount.increaseCount();
}
if (elIt != null) {
while (elIt.hasNext()) {
elIt.next();
elIt.remove();
}
}
}
}
/**
* Method replaceXpp3DOM
*
* @param parent The parent.
* @param counter {@link Counter}
* @param parentDom {@link Element}
*/
protected void replaceXpp3DOM(Element parent, Xpp3Dom parentDom, Counter counter) {
if (parentDom.getChildCount() > 0) {
Xpp3Dom[] childs = parentDom.getChildren();
Collection domChilds = new ArrayList<>();
Collections.addAll(domChilds, childs);
// int domIndex = 0;
for (Element elem : parent.getChildren()) {
Xpp3Dom corrDom = null;
for (Xpp3Dom dm : domChilds) {
if (dm.getName().equals(elem.getName())) {
corrDom = dm;
break;
}
}
if (corrDom != null) {
domChilds.remove(corrDom);
replaceXpp3DOM(elem, corrDom, new Counter(counter.getDepth() + 1));
counter.increaseCount();
} else {
parent.removeContent(elem);
}
}
for (Xpp3Dom dm : domChilds) {
Element elem = factory.element(dm.getName(), parent.getNamespace());
insertAtPreferredLocation(parent, elem, counter);
counter.increaseCount();
replaceXpp3DOM(elem, dm, new Counter(counter.getDepth() + 1));
}
} else if (parentDom.getValue() != null) {
parent.setText(parentDom.getValue());
}
}
/**
* Method updateActivationFile
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateActivationFile(ActivationFile value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "missing", value.getMissing(), null);
findAndReplaceSimpleElement(innerCount, root, "exists", value.getExists(), null);
}
}
/**
* Method updateActivationOS
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateActivationOS(ActivationOS value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "family", value.getFamily(), null);
findAndReplaceSimpleElement(innerCount, root, "arch", value.getArch(), null);
findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
}
}
/**
* Method updateActivationProperty
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateActivationProperty(ActivationProperty value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "value", value.getValue(), null);
}
}
/**
* Method updateBuild
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
// CHECKSTYLE_OFF: LineLength
protected void updateBuild(Build value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "sourceDirectory", value.getSourceDirectory(), null);
findAndReplaceSimpleElement(
innerCount, root, "scriptSourceDirectory", value.getScriptSourceDirectory(), null);
findAndReplaceSimpleElement(innerCount, root, "testSourceDirectory", value.getTestSourceDirectory(), null);
findAndReplaceSimpleElement(innerCount, root, "outputDirectory", value.getOutputDirectory(), null);
findAndReplaceSimpleElement(innerCount, root, "testOutputDirectory", value.getTestOutputDirectory(), null);
iterateExtension(innerCount, root, value.getExtensions(), "extensions", "extension");
findAndReplaceSimpleElement(innerCount, root, "defaultGoal", value.getDefaultGoal(), null);
iterateResource(innerCount, root, value.getResources(), "resources", "resource");
iterateResource(innerCount, root, value.getTestResources(), "testResources", "testResource");
findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null);
findAndReplaceSimpleElement(innerCount, root, "finalName", value.getFinalName(), null);
findAndReplaceSimpleLists(innerCount, root, value.getFilters(), "filters", "filter");
updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root);
iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
}
}
// CHECKSTYLE_ON: LineLength
/**
* Method updateBuildBase
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateBuildBase(BuildBase value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "defaultGoal", value.getDefaultGoal(), null);
iterateResource(innerCount, root, value.getResources(), "resources", "resource");
iterateResource(innerCount, root, value.getTestResources(), "testResources", "testResource");
findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null);
findAndReplaceSimpleElement(innerCount, root, "finalName", value.getFinalName(), null);
findAndReplaceSimpleLists(innerCount, root, value.getFilters(), "filters", "filter");
updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root);
iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
}
}
/**
* Method updateCiManagement
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateCiManagement(CiManagement value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "system", value.getSystem(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
iterateNotifier(innerCount, root, value.getNotifiers(), "notifiers", "notifier");
}
}
/**
* Method updateConfigurationContainer
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateConfigurationContainer(
ConfigurationContainer value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
}
}
/**
* Method updateContributor
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateContributor(Contributor value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "email", value.getEmail(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
findAndReplaceSimpleElement(innerCount, root, "organization", value.getOrganization(), null);
findAndReplaceSimpleElement(innerCount, root, "organizationUrl", value.getOrganizationUrl(), null);
findAndReplaceSimpleLists(innerCount, root, value.getRoles(), "roles", "role");
findAndReplaceSimpleElement(innerCount, root, "timezone", value.getTimezone(), null);
findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
}
/**
* Method updateDependency
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateDependency(Dependency value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
findAndReplaceSimpleElement(innerCount, root, "type", value.getType(), "jar");
findAndReplaceSimpleElement(innerCount, root, "classifier", value.getClassifier(), null);
findAndReplaceSimpleElement(innerCount, root, "scope", value.getScope(), null);
findAndReplaceSimpleElement(innerCount, root, "systemPath", value.getSystemPath(), null);
iterateExclusion(innerCount, root, value.getExclusions(), "exclusions", "exclusion");
findAndReplaceSimpleElement(
innerCount, root, "optional", !value.isOptional() ? null : String.valueOf(value.isOptional()), "false");
}
/**
* Method updateDependencyManagement
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateDependencyManagement(
DependencyManagement value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
}
}
/**
* Method updateDeploymentRepository
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateDeploymentRepository(
DeploymentRepository value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(
innerCount,
root,
"uniqueVersion",
value.isUniqueVersion() ? null : String.valueOf(value.isUniqueVersion()),
"true");
findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default");
}
}
/**
* Method updateDeveloper
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateDeveloper(Developer value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "email", value.getEmail(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
findAndReplaceSimpleElement(innerCount, root, "organization", value.getOrganization(), null);
findAndReplaceSimpleElement(innerCount, root, "organizationUrl", value.getOrganizationUrl(), null);
findAndReplaceSimpleLists(innerCount, root, value.getRoles(), "roles", "role");
findAndReplaceSimpleElement(innerCount, root, "timezone", value.getTimezone(), null);
findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
}
/**
* Method updateDistributionManagement
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateDistributionManagement(
DistributionManagement value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
updateDeploymentRepository(value.getRepository(), "repository", innerCount, root);
updateDeploymentRepository(value.getSnapshotRepository(), "snapshotRepository", innerCount, root);
updateSite(value.getSite(), "site", innerCount, root);
findAndReplaceSimpleElement(innerCount, root, "downloadUrl", value.getDownloadUrl(), null);
updateRelocation(value.getRelocation(), "relocation", innerCount, root);
findAndReplaceSimpleElement(innerCount, root, "status", value.getStatus(), null);
}
}
/**
* Method updateElement
*
* @param counter {@link Counter}
* @param shouldExist should exist.
* @param name The name.
* @param parent The parent.
* @return {@link Element}
*/
protected Element updateElement(Counter counter, Element parent, String name, boolean shouldExist) {
Element element = parent.getChild(name, parent.getNamespace());
if (element != null && shouldExist) {
counter.increaseCount();
}
if (element == null && shouldExist) {
element = factory.element(name, parent.getNamespace());
insertAtPreferredLocation(parent, element, counter);
counter.increaseCount();
}
if (!shouldExist && element != null) {
int index = parent.indexOf(element);
if (index > 0) {
Content previous = parent.getContent(index - 1);
if (previous instanceof Text) {
Text txt = (Text) previous;
if (txt.getTextTrim().length() == 0) {
parent.removeContent(txt);
}
}
}
parent.removeContent(element);
}
return element;
}
/**
* Method updateExclusion
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateExclusion(Exclusion value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
}
/**
* Method updateExtension
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateExtension(Extension value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
}
/**
* Method updateFileSet
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateFileSet(FileSet value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null);
findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include");
findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude");
}
}
/**
* Method updateIssueManagement
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateIssueManagement(IssueManagement value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "system", value.getSystem(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
}
}
/**
* Method updateLicense
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateLicense(License value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
findAndReplaceSimpleElement(innerCount, root, "distribution", value.getDistribution(), null);
findAndReplaceSimpleElement(innerCount, root, "comments", value.getComments(), null);
}
/**
* Method updateMailingList
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateMailingList(MailingList value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "subscribe", value.getSubscribe(), null);
findAndReplaceSimpleElement(innerCount, root, "unsubscribe", value.getUnsubscribe(), null);
findAndReplaceSimpleElement(innerCount, root, "post", value.getPost(), null);
findAndReplaceSimpleElement(innerCount, root, "archive", value.getArchive(), null);
findAndReplaceSimpleLists(innerCount, root, value.getOtherArchives(), "otherArchives", "otherArchive");
}
/**
* Method updateModel
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateModel(Model value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
updateParent(value.getParent(), "parent", innerCount, root);
findAndReplaceSimpleElement(innerCount, root, "modelVersion", value.getModelVersion(), null);
findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
findAndReplaceSimpleElement(innerCount, root, "packaging", value.getPackaging(), "jar");
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
findAndReplaceSimpleElement(innerCount, root, "description", value.getDescription(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
updatePrerequisites(value.getPrerequisites(), "prerequisites", innerCount, root);
updateIssueManagement(value.getIssueManagement(), "issueManagement", innerCount, root);
updateCiManagement(value.getCiManagement(), "ciManagement", innerCount, root);
findAndReplaceSimpleElement(innerCount, root, "inceptionYear", value.getInceptionYear(), null);
iterateMailingList(innerCount, root, value.getMailingLists(), "mailingLists", "mailingList");
iterateDeveloper(innerCount, root, value.getDevelopers(), "developers", "developer");
iterateContributor(innerCount, root, value.getContributors(), "contributors", "contributor");
iterateLicense(innerCount, root, value.getLicenses(), "licenses", "license");
updateScm(value.getScm(), "scm", innerCount, root);
updateOrganization(value.getOrganization(), "organization", innerCount, root);
updateBuild(value.getBuild(), "build", innerCount, root);
iterateProfile(innerCount, root, value.getProfiles(), "profiles", "profile");
findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module");
iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository");
iterateRepository(innerCount, root, value.getPluginRepositories(), "pluginRepositories", "pluginRepository");
iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
updateReporting(value.getReporting(), "reporting", innerCount, root);
updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root);
updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root);
findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
}
/**
* Method updateModelBase
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
// CHECKSTYLE_OFF: LineLength
protected void updateModelBase(ModelBase value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module");
iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository");
iterateRepository(
innerCount, root, value.getPluginRepositories(), "pluginRepositories", "pluginRepository");
iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
updateReporting(value.getReporting(), "reporting", innerCount, root);
updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root);
updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root);
findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
}
}
// CHECKSTYLE_ON: LineLength
/**
* Method updateNotifier
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
// CHECKSTYLE_OFF: LineLength
protected void updateNotifier(Notifier value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "type", value.getType(), "mail");
findAndReplaceSimpleElement(
innerCount,
root,
"sendOnError",
value.isSendOnError() ? null : String.valueOf(value.isSendOnError()),
"true");
findAndReplaceSimpleElement(
innerCount,
root,
"sendOnFailure",
value.isSendOnFailure() ? null : String.valueOf(value.isSendOnFailure()),
"true");
findAndReplaceSimpleElement(
innerCount,
root,
"sendOnSuccess",
value.isSendOnSuccess() ? null : String.valueOf(value.isSendOnSuccess()),
"true");
findAndReplaceSimpleElement(
innerCount,
root,
"sendOnWarning",
value.isSendOnWarning() ? null : String.valueOf(value.isSendOnWarning()),
"true");
findAndReplaceSimpleElement(innerCount, root, "address", value.getAddress(), null);
findAndReplaceProperties(innerCount, root, "configuration", value.getConfiguration());
}
// CHECKSTYLE_ON: LineLength
/**
* Method updateOrganization
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateOrganization(Organization value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
}
}
/**
* Method updateParent
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateParent(Parent value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
findAndReplaceSimpleElement(innerCount, root, "relativePath", value.getRelativePath(), "../pom.xml");
}
}
/**
* Method updatePatternSet
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updatePatternSet(PatternSet value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include");
findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude");
}
}
/**
* Method updatePlugin
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updatePlugin(Plugin value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), "org.apache.maven.plugins");
findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
findAndReplaceSimpleElement(
innerCount,
root,
"extensions",
!value.isExtensions() ? null : String.valueOf(value.isExtensions()),
"false");
iteratePluginExecution(innerCount, root, value.getExecutions(), "executions", "execution");
iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
}
/**
* Method updatePluginConfiguration
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
// CHECKSTYLE_OFF: LineLength
protected void updatePluginConfiguration(
PluginConfiguration value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root);
iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
}
}
// CHECKSTYLE_ON: LineLength
/**
* Method updatePluginContainer
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updatePluginContainer(PluginContainer value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
}
}
/**
* Method updatePluginExecution
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updatePluginExecution(PluginExecution value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), "default");
findAndReplaceSimpleElement(innerCount, root, "phase", value.getPhase(), null);
findAndReplaceSimpleLists(innerCount, root, value.getGoals(), "goals", "goal");
findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
}
/**
* Method updatePluginManagement
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updatePluginManagement(PluginManagement value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
}
}
/**
* Method updatePrerequisites
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updatePrerequisites(Prerequisites value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "maven", value.getMaven(), "2.0");
}
}
/**
* Method updateProfile
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateProfile(Profile value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), "default");
// updateActivation( value.getActivation(), "activation", innerCount, root);
updateBuildBase(value.getBuild(), "build", innerCount, root);
findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module");
iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository");
iterateRepository(innerCount, root, value.getPluginRepositories(), "pluginRepositories", "pluginRepository");
iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
updateReporting(value.getReporting(), "reporting", innerCount, root);
updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root);
updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root);
findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
}
/**
* Method updateRelocation
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateRelocation(Relocation value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
findAndReplaceSimpleElement(innerCount, root, "message", value.getMessage(), null);
}
}
/**
* Method updateReportPlugin
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateReportPlugin(ReportPlugin value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), "org.apache.maven.plugins");
findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
iterateReportSet(innerCount, root, value.getReportSets(), "reportSets", "reportSet");
}
/**
* Method updateReportSet
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateReportSet(ReportSet value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), "default");
findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
findAndReplaceSimpleLists(innerCount, root, value.getReports(), "reports", "report");
}
/**
* Method updateReporting
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateReporting(Reporting value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(
innerCount,
root,
"excludeDefaults",
!value.isExcludeDefaults() ? null : String.valueOf(value.isExcludeDefaults()),
"false");
findAndReplaceSimpleElement(innerCount, root, "outputDirectory", value.getOutputDirectory(), null);
iterateReportPlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
}
}
/**
* Method updateRepository
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateRepository(Repository value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
updateRepositoryPolicy(value.getReleases(), "releases", innerCount, root);
updateRepositoryPolicy(value.getSnapshots(), "snapshots", innerCount, root);
findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default");
}
/**
* Method updateRepositoryBase
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateRepositoryBase(RepositoryBase value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default");
}
}
/**
* Method updateRepositoryPolicy
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateRepositoryPolicy(RepositoryPolicy value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(
innerCount, root, "enabled", value.isEnabled() ? null : String.valueOf(value.isEnabled()), "true");
findAndReplaceSimpleElement(innerCount, root, "updatePolicy", value.getUpdatePolicy(), null);
findAndReplaceSimpleElement(innerCount, root, "checksumPolicy", value.getChecksumPolicy(), null);
}
}
/**
* Method updateResource
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateResource(Resource value, String xmlTag, Counter counter, Element element) {
Element root = element;
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "targetPath", value.getTargetPath(), null);
findAndReplaceSimpleElement(
innerCount,
root,
"filtering",
!value.isFiltering() ? null : String.valueOf(value.isFiltering()),
"false");
findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null);
findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include");
findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude");
}
/**
* Method updateScm
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateScm(Scm value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
// CHECKSTYLE_OFF: LineLength
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "connection", value.getConnection(), null);
findAndReplaceSimpleElement(innerCount, root, "developerConnection", value.getDeveloperConnection(), null);
findAndReplaceSimpleElement(innerCount, root, "tag", value.getTag(), "HEAD");
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
// CHECKSTYLE_ON: LineLength
}
}
/**
* Method updateSite
*
* @param value The value.
* @param element {@link Element}
* @param counter {@link Counter}
* @param xmlTag The XMLTag.
*/
protected void updateSite(Site value, String xmlTag, Counter counter, Element element) {
boolean shouldExist = value != null;
Element root = updateElement(counter, element, xmlTag, shouldExist);
if (shouldExist) {
Counter innerCount = new Counter(counter.getDepth() + 1);
findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
}
}
/**
* Method write
*
* @param project {@link Model}
* @param stream {@link OutputStream}
* @param document {@link Document}
* @deprecated
* @throws IOException in case of an error.
*/
public void write(Model project, Document document, OutputStream stream) throws IOException {
updateModel(project, "project", new Counter(0), document.getRootElement());
XMLOutputter outputter = new XMLOutputter();
Format format = Format.getPrettyFormat();
format.setIndent(" ").setLineSeparator(lineSeparator);
outputter.setFormat(format);
outputter.output(document, stream);
}
/**
* Method write
*
* @param project {@link Model}
* @param writer {@link OutputStreamWriter}
* @param document {@link Document}
* @throws IOException in case of an error.
*/
public void write(Model project, Document document, OutputStreamWriter writer) throws IOException {
Format format = Format.getRawFormat();
format.setEncoding(writer.getEncoding()).setLineSeparator(lineSeparator);
write(project, document, writer, format);
}
/**
* Method write
*
* @param project {@link Model}
* @param jdomFormat {@link Format}
* @param writer {@link Writer}
* @param document {@link Document}
* @throws IOException in case of an error.
*/
public void write(Model project, Document document, Writer writer, Format jdomFormat) throws IOException {
updateModel(project, "project", new Counter(0), document.getRootElement());
XMLOutputter outputter = new XMLOutputter();
outputter.setFormat(jdomFormat);
outputter.output(document, writer);
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/pom/PomWriter.java
================================================
/*
* 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.plugins.shade.pom;
import java.io.IOException;
import java.io.Writer;
import org.apache.maven.model.Model;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.jdom2.output.Format;
/**
* @author Jason van Zyl
*/
public class PomWriter {
public static void write(Writer w, Model newModel) throws IOException {
write(w, newModel, false);
}
public static void write(Writer w, Model newModel, boolean namespaceDeclaration) throws IOException {
Element root = new Element("project");
if (namespaceDeclaration) {
String modelVersion = newModel.getModelVersion();
Namespace pomNamespace = Namespace.getNamespace("", "http://maven.apache.org/POM/" + modelVersion);
root.setNamespace(pomNamespace);
Namespace xsiNamespace = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
root.addNamespaceDeclaration(xsiNamespace);
if (root.getAttribute("schemaLocation", xsiNamespace) == null) {
root.setAttribute(
"schemaLocation",
"http://maven.apache.org/POM/" + modelVersion + " http://maven.apache.org/maven-v"
+ modelVersion.replace('.', '_') + ".xsd",
xsiNamespace);
}
}
Document doc = new Document(root);
MavenJDOMWriter writer = new MavenJDOMWriter();
String encoding = newModel.getModelEncoding() != null ? newModel.getModelEncoding() : "UTF-8";
Format format = Format.getPrettyFormat().setEncoding(encoding);
writer.write(newModel, doc, w, format);
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/relocation/Relocator.java
================================================
/*
* 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.plugins.shade.relocation;
/** @author Jason van Zyl */
public interface Relocator {
String ROLE = Relocator.class.getName();
boolean canRelocatePath(String clazz);
String relocatePath(String clazz);
boolean canRelocateClass(String clazz);
/**
* Replace the first class pattern match in the given string
* @see #relocateAllClasses(String)
*/
String relocateClass(String input);
String applyToSourceContent(String sourceContent);
/**
* Replace all class pattern matches in the given input.
* @see #relocateClass(String)
*/
String relocateAllClasses(String input);
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/relocation/SerializedLambdaRelocator.java
================================================
/*
* 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.plugins.shade.relocation;
import java.util.List;
import java.util.regex.Pattern;
/** @author Kamil Wójcik */
public class SerializedLambdaRelocator extends SimpleRelocator {
private final Pattern serializedLambdaDefinitionPattern =
Pattern.compile("\\(([BCDFIJSZ]|\\[+[BCDFIJSZ]|\\[*L[^;]+;)*\\)([BCDFIJSZ]|V|\\[+[BCDFIJSZ]|\\[*L[^;]+;)");
private final Pattern clazzInsideFunctionDefintionPattern;
private final String shadedPathPattern;
private boolean shouldRelocate = true;
public SerializedLambdaRelocator(
String pattern, String shadedPattern, List includes, List excludes, boolean rawString) {
super(pattern, shadedPattern, includes, excludes, rawString);
if (shadedPattern != null && pattern != null) {
this.shadedPathPattern = shadedPattern.replace('.', '/');
String pathPattern = pattern.replace('.', '/');
this.clazzInsideFunctionDefintionPattern = Pattern.compile("(?<=[(;)]L)" + Pattern.quote(pathPattern));
} else {
this.clazzInsideFunctionDefintionPattern = null;
this.shadedPathPattern = null;
this.shouldRelocate = false;
}
}
@Override
public boolean canRelocatePath(String path) {
return shouldRelocate && serializedLambdaDefinitionPattern.matcher(path).matches();
}
@Override
public boolean canRelocateClass(String clazz) {
return false;
}
@Override
public String relocatePath(String path) {
return !shouldRelocate
? path
: clazzInsideFunctionDefintionPattern.matcher(path).replaceAll(shadedPathPattern);
}
@Override
public String relocateClass(String input) {
return input;
}
@Override
public String relocateAllClasses(String input) {
return input;
}
@Override
public String applyToSourceContent(String sourceContent) {
return sourceContent;
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java
================================================
/*
* 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.plugins.shade.relocation;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.codehaus.plexus.util.SelectorUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Jason van Zyl
* @author Mauro Talevi
*/
public class SimpleRelocator implements Relocator {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleRelocator.class);
/**
* Match dot, slash or space at end of string
*/
private static final Pattern RX_ENDS_WITH_DOT_SLASH_SPACE = Pattern.compile("[./ ]$");
/**
* Match
* - certain Java keywords + space
* - beginning of Javadoc link + optional line breaks and continuations with '*'
* - (opening curly brace / opening parenthesis / comma / equals / semicolon) + space
* - (closing curly brace / closing multi-line comment) + space
*
* at end of string
*/
private static final Pattern RX_ENDS_WITH_JAVA_KEYWORD = Pattern.compile(
"\\b(import|package|public|protected|private|static|final|synchronized|abstract|volatile|extends|implements|throws) $"
+ "|"
+ "\\{@link( \\*)* $"
+ "|"
+ "([{}(=;,]|\\*/) $");
/** plain text, no wildcards, always refers to fully qualified package names, may be {@code null} when rawString is {@code true}. */
private final String originalPattern;
/** plain text, no wildcards, always refers to paths with "/" separator, never {@code null}. */
private final String originalPathPattern;
/**
* May be {@code null} when {@link #rawString} is true
*/
private final Pattern regExPattern;
private final Pattern regExPathPattern;
/**
* Replacement (no wildcards) for {@link #originalPattern}, may be {@code null} when {@link #rawString} is true.
*/
private final String shadedPattern;
/**
* Replacement (no wildcards) for {@link #originalPathPattern}.
*/
private final String shadedPathPattern;
/**
* Patterns to include in relocation.
* Only Ant-based patterns (used with SelectorUtils.matchPath), must not start with "%ant[" prefix. Include both forms with dots and slashes, e.g. "my/package/**" and "my/package/*" for class patterns, "my/path/**" and "my/path/*" for path patterns.
*/
private final Set includes;
/**
* Patterns to exclude from relocation.
* Only Ant-based patterns (used with SelectorUtils.matchPath), must not start with "%ant[" prefix. Include both forms with dots and slashes, e.g. "my/package/**" and "my/package/*" for class patterns, "my/path/**" and "my/path/*" for path patterns.
*/
private final Set excludes;
// prefix (no wildcards), derived from excludes
private final Set sourcePackageExcludes = new LinkedHashSet<>();
// prefix (no wildcards), derived from excludes
private final Set sourcePathExcludes = new LinkedHashSet<>();
private final boolean rawString;
/**
* Same as {@link #SimpleRelocator(String, String, List, List, boolean)} with {@code rawString} set to {@code false}.
* @param patt
* @param shadedPattern
* @param includes
* @param excludes
*/
public SimpleRelocator(String patt, String shadedPattern, List includes, List excludes) {
this(patt, shadedPattern, includes, excludes, false);
}
/**
* Creates a relocator with the given patterns and includes/excludes. If {@code rawString} is {@code true}, then the given pattern is
* treated as regular expression pattern, otherwise it is treated as plain text with no wildcards.
* In the latter case, the pattern is expected to refer to classes, not paths, and the constructor will derive the path pattern by replacing dots with slashes.
* @param pattern
* @param shadedPattern
* @param includes
* @param excludes
* @param rawString
*/
public SimpleRelocator(
String pattern, String shadedPattern, List includes, List excludes, boolean rawString) {
this.rawString = rawString;
if (rawString) {
originalPathPattern = pattern;
this.shadedPathPattern = shadedPattern;
originalPattern = null; // not used for raw string relocator
this.shadedPattern = null; // not used for raw string relocator
} else {
if (pattern == null) {
// means default package
throw new IllegalArgumentException(
"Pattern must not be null, otherwise it is unclear what to relocate!");
} else {
originalPattern = pattern.replace('/', '.');
originalPathPattern = pattern.replace('.', '/');
}
if (shadedPattern != null) {
this.shadedPattern = shadedPattern.replace('/', '.');
this.shadedPathPattern = shadedPattern.replace('.', '/');
} else {
this.shadedPattern = "hidden." + originalPattern;
this.shadedPathPattern = "hidden/" + originalPathPattern;
}
}
if (rawString) {
if ((includes != null && !includes.isEmpty()) || (excludes != null && !excludes.isEmpty())) {
LOGGER.warn("Includes and excludes are ignored when rawString is true");
}
// In raw string mode, the pattern is treated as regular expression, so we compile it as is, without quoting
// it.
this.regExPattern = originalPattern != null ? Pattern.compile(originalPattern) : null;
this.regExPathPattern = Pattern.compile(originalPathPattern);
this.includes = null;
this.excludes = null;
} else {
this.includes = normalizePatterns(includes);
this.excludes = normalizePatterns(excludes);
// Don't replace all dots to slashes, otherwise /META-INF/maven/${groupId} can't be matched.
if (includes != null && !includes.isEmpty()) {
this.includes.addAll(includes);
}
if (excludes != null && !excludes.isEmpty()) {
this.excludes.addAll(excludes);
}
if (this.excludes != null) {
// Create exclude pattern sets for sources
for (String exclude : this.excludes) {
// Excludes should be subpackages of the global pattern
if (exclude.startsWith(originalPattern)) {
sourcePackageExcludes.add(
exclude.substring(originalPattern.length()).replaceFirst("[.][*]$", ""));
}
// Excludes should be subpackages of the global pattern
if (exclude.startsWith(originalPathPattern)) {
sourcePathExcludes.add(
exclude.substring(originalPathPattern.length()).replaceFirst("[/][*]$", ""));
}
}
}
this.regExPattern = originalPattern != null ? Pattern.compile(Pattern.quote(originalPattern)) : null;
this.regExPathPattern = Pattern.compile(Pattern.quote(originalPathPattern));
}
}
/**
* Normalizes the given patterns by replacing dots with slashes and slashes with dots so that both forms are returned.
*
* @param patterns
* @return the normalized patterns, or {@code null} if the given patterns were {@code null} or empty
*/
private static Set normalizePatterns(Collection patterns) {
Set normalized = null;
if (patterns != null && !patterns.isEmpty()) {
normalized = new LinkedHashSet<>();
for (String pattern : patterns) {
String classPattern = pattern.replace('.', '/');
normalized.add(classPattern);
// Actually, class patterns should just use 'foo.bar.*' ending with a single asterisk, but some users
// mistake them for path patterns like 'my/path/**', so let us be a bit more lenient here.
if (classPattern.endsWith("/*") || classPattern.endsWith("/**")) {
String packagePattern = classPattern.substring(0, classPattern.lastIndexOf('/'));
normalized.add(packagePattern);
}
}
}
return normalized;
}
protected boolean isIncluded(String path) {
if (includes != null && !includes.isEmpty()) {
for (String include : includes) {
if (SelectorUtils.matchPath(include, path, true)) {
return true;
}
}
return false;
}
return true;
}
protected boolean isExcluded(String path) {
if (excludes != null && !excludes.isEmpty()) {
for (String exclude : excludes) {
if (SelectorUtils.matchPath(exclude, path, true)) {
return true;
}
}
}
return false;
}
@Override
public boolean canRelocatePath(String path) {
if (rawString) {
return regExPathPattern.matcher(path).find();
}
if (path.endsWith(".class")) {
path = path.substring(0, path.length() - 6);
}
// Allow for annoying option of an extra / on the front of a path. See MSHADE-119; comes from
// getClass().getResource("/a/b/c.properties").
if (!path.isEmpty() && path.charAt(0) == '/') {
path = path.substring(1);
}
if (isIncluded(path) && !isExcluded(path)) {
Matcher matcher = regExPathPattern.matcher(path);
if (matcher.find()) {
return matcher.start() == 0;
}
}
return false;
}
@Override
public boolean canRelocateClass(String clazz) {
return !rawString && clazz.indexOf('/') < 0 && canRelocatePath(clazz.replace('.', '/'));
}
@Override
public String relocatePath(String path) {
if (rawString) {
return regExPathPattern.matcher(path).replaceAll(shadedPathPattern);
} else {
return regExPathPattern.matcher(path).replaceFirst(shadedPathPattern);
}
}
@Override
public String relocateClass(String input) {
return regExPattern == null ? input : regExPattern.matcher(input).replaceFirst(shadedPattern);
}
@Override
public String relocateAllClasses(String input) {
return regExPattern == null ? input : regExPattern.matcher(input).replaceAll(shadedPattern);
}
@Override
public String applyToSourceContent(String sourceContent) {
if (rawString) {
return sourceContent;
}
sourceContent = shadeSourceWithExcludes(sourceContent, originalPattern, shadedPattern, sourcePackageExcludes);
return shadeSourceWithExcludes(sourceContent, originalPathPattern, shadedPathPattern, sourcePathExcludes);
}
private String shadeSourceWithExcludes(
String sourceContent, String patternFrom, String patternTo, Set excludedPatterns) {
// Usually shading makes package names a bit longer, so make buffer 10% bigger than original source
StringBuilder shadedSourceContent = new StringBuilder(sourceContent.length() * 11 / 10);
boolean isFirstSnippet = true;
// Make sure that search pattern starts at word boundary and that we look for literal ".", not regex jokers
String[] snippets = sourceContent.split("\\b" + patternFrom.replace(".", "[.]") + "\\b");
for (int i = 0, snippetsLength = snippets.length; i < snippetsLength; i++) {
String snippet = snippets[i];
String previousSnippet = isFirstSnippet ? "" : snippets[i - 1];
boolean doExclude = false;
for (String excludedPattern : excludedPatterns) {
if (snippet.startsWith(excludedPattern)) {
doExclude = true;
break;
}
}
if (isFirstSnippet) {
shadedSourceContent.append(snippet);
isFirstSnippet = false;
} else {
String previousSnippetOneLine = previousSnippet.replaceAll("\\s+", " ");
boolean afterDotSlashSpace = RX_ENDS_WITH_DOT_SLASH_SPACE
.matcher(previousSnippetOneLine)
.find();
boolean afterJavaKeyWord = RX_ENDS_WITH_JAVA_KEYWORD
.matcher(previousSnippetOneLine)
.find();
boolean shouldExclude = doExclude || afterDotSlashSpace && !afterJavaKeyWord;
shadedSourceContent
.append(shouldExclude ? patternFrom : patternTo)
.append(snippet);
}
}
return shadedSourceContent.toString();
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/resource/AbstractCompatibilityTransformer.java
================================================
/*
* 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.plugins.shade.resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.maven.plugins.shade.relocation.Relocator;
/**
* An abstract class to implement once the old non-reproducible ResourceTransformer API.
*/
abstract class AbstractCompatibilityTransformer implements ReproducibleResourceTransformer {
@Override
public final void processResource(String resource, InputStream is, List relocators) throws IOException {
processResource(resource, is, relocators, 0);
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/resource/ApacheLicenseResourceTransformer.java
================================================
/*
* 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.plugins.shade.resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.jar.JarOutputStream;
import org.apache.maven.plugins.shade.relocation.Relocator;
/**
* Prevents duplicate copies of the license
*/
public class ApacheLicenseResourceTransformer extends AbstractCompatibilityTransformer {
private static final String LICENSE_PATH = "META-INF/LICENSE";
private static final String LICENSE_TXT_PATH = "META-INF/LICENSE.txt";
private static final String LICENSE_MD_PATH = "META-INF/LICENSE.md";
@Override
public boolean canTransformResource(String resource) {
return LICENSE_PATH.equalsIgnoreCase(resource)
|| LICENSE_TXT_PATH.regionMatches(true, 0, resource, 0, LICENSE_TXT_PATH.length())
|| LICENSE_MD_PATH.regionMatches(true, 0, resource, 0, LICENSE_MD_PATH.length());
}
@Override
public void processResource(String resource, InputStream is, List relocators, long time)
throws IOException {
// no op
}
@Override
public boolean hasTransformedResource() {
return false;
}
@Override
public void modifyOutputStream(JarOutputStream os) throws IOException {
// no op
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/resource/ApacheNoticeResourceTransformer.java
================================================
/*
* 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.plugins.shade.resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import org.apache.maven.plugins.shade.relocation.Relocator;
/**
* Merges META-INF/NOTICE.TXT files.
*/
public class ApacheNoticeResourceTransformer extends AbstractCompatibilityTransformer {
Set entries = new LinkedHashSet<>();
Map> organizationEntries = new LinkedHashMap<>();
String projectName = ""; // MSHADE-101 :: NullPointerException when projectName is missing
boolean addHeader = true;
String preamble1 = "// ------------------------------------------------------------------\n"
+ "// NOTICE file corresponding to the section 4d of The Apache License,\n"
+ "// Version 2.0, in this case for ";
String preamble2 = "\n// ------------------------------------------------------------------\n";
String preamble3 = "This product includes software developed at\n";
// defaults overridable via config in pom
String organizationName = "The Apache Software Foundation";
String organizationURL = "http://www.apache.org/";
String inceptionYear = "2006";
String copyright;
/**
* The file encoding of the NOTICE file.
*/
String encoding;
private long time = Long.MIN_VALUE;
private static final String NOTICE_PATH = "META-INF/NOTICE";
private static final String NOTICE_TXT_PATH = "META-INF/NOTICE.txt";
private static final String NOTICE_MD_PATH = "META-INF/NOTICE.md";
@Override
public boolean canTransformResource(String resource) {
return NOTICE_PATH.equalsIgnoreCase(resource)
|| NOTICE_TXT_PATH.equalsIgnoreCase(resource)
|| NOTICE_MD_PATH.equalsIgnoreCase(resource);
}
@Override
public void processResource(String resource, InputStream is, List relocators, long time)
throws IOException {
if (entries.isEmpty()) {
String year = new SimpleDateFormat("yyyy").format(new Date());
if (!inceptionYear.equals(year)) {
year = inceptionYear + "-" + year;
}
// add headers
if (addHeader) {
entries.add(preamble1 + projectName + preamble2);
} else {
entries.add("");
}
// fake second entry, we'll look for a real one later
entries.add(projectName + "\nCopyright " + year + " " + organizationName + "\n");
entries.add(preamble3 + organizationName + " (" + organizationURL + ").\n");
}
BufferedReader reader;
if (encoding != null && !encoding.isEmpty()) {
reader = new BufferedReader(new InputStreamReader(is, encoding));
} else {
reader = new BufferedReader(new InputStreamReader(is));
}
String line = reader.readLine();
StringBuilder sb = new StringBuilder();
Set currentOrg = null;
int lineCount = 0;
while (line != null) {
String trimedLine = line.trim();
if (!trimedLine.startsWith("//")) {
if (trimedLine.length() > 0) {
if (trimedLine.startsWith("- ")) {
// resource-bundle 1.3 mode
if (lineCount == 1
&& sb.toString().contains("This product includes/uses software(s) developed by")) {
currentOrg = organizationEntries.get(sb.toString().trim());
if (currentOrg == null) {
currentOrg = new TreeSet<>();
organizationEntries.put(sb.toString().trim(), currentOrg);
}
sb = new StringBuilder();
} else if (sb.length() > 0 && currentOrg != null) {
currentOrg.add(sb.toString());
sb = new StringBuilder();
}
}
sb.append(line).append("\n");
lineCount++;
} else {
String ent = sb.toString();
if (ent.startsWith(projectName) && ent.contains("Copyright ")) {
copyright = ent;
}
if (currentOrg == null) {
entries.add(ent);
} else {
currentOrg.add(ent);
}
sb = new StringBuilder();
lineCount = 0;
currentOrg = null;
}
}
line = reader.readLine();
}
if (sb.length() > 0) {
if (currentOrg == null) {
entries.add(sb.toString());
} else {
currentOrg.add(sb.toString());
}
}
if (time > this.time) {
this.time = time;
}
}
@Override
public boolean hasTransformedResource() {
return true;
}
@Override
public void modifyOutputStream(JarOutputStream jos) throws IOException {
JarEntry jarEntry = new JarEntry(NOTICE_PATH);
jarEntry.setTime(time);
jos.putNextEntry(jarEntry);
Writer writer;
if (encoding != null && !encoding.isEmpty()) {
writer = new OutputStreamWriter(jos, encoding);
} else {
writer = new OutputStreamWriter(jos);
}
int count = 0;
for (String line : entries) {
++count;
if (line.equals(copyright) && count != 2) {
continue;
}
if (count == 2 && copyright != null) {
writer.write(copyright);
writer.write('\n');
} else {
writer.write(line);
writer.write('\n');
}
if (count == 3) {
// do org stuff
for (Map.Entry> entry : organizationEntries.entrySet()) {
writer.write(entry.getKey());
writer.write('\n');
for (String l : entry.getValue()) {
writer.write(l);
}
writer.write('\n');
}
}
}
writer.flush();
entries.clear();
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/resource/AppendingTransformer.java
================================================
/*
* 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.plugins.shade.resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import org.apache.maven.plugins.shade.relocation.Relocator;
import org.codehaus.plexus.util.IOUtil;
/**
* A resource processor that appends content for a resource, separated by a newline.
*/
public class AppendingTransformer extends AbstractCompatibilityTransformer {
String resource;
ByteArrayOutputStream data = new ByteArrayOutputStream();
private long time = Long.MIN_VALUE;
@Override
public boolean canTransformResource(String r) {
return resource != null && resource.equalsIgnoreCase(r);
}
@Override
public void processResource(String resource, InputStream is, List relocators, long time)
throws IOException {
IOUtil.copy(is, data);
data.write('\n');
if (time > this.time) {
this.time = time;
}
}
@Override
public boolean hasTransformedResource() {
return data.size() > 0;
}
@Override
public void modifyOutputStream(JarOutputStream jos) throws IOException {
JarEntry jarEntry = new JarEntry(resource);
jarEntry.setTime(time);
jos.putNextEntry(jarEntry);
jos.write(data.toByteArray());
data.reset();
}
}
================================================
FILE: src/main/java/org/apache/maven/plugins/shade/resource/ComponentsXmlResourceTransformer.java
================================================
/*
* 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.plugins.shade.resource;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import org.apache.maven.plugins.shade.relocation.Relocator;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.Xpp3DomWriter;
/**
* A resource processor that aggregates plexus components.xml files.
*/
public class ComponentsXmlResourceTransformer extends AbstractCompatibilityTransformer {
private Map components = new LinkedHashMap<>();
private long time = Long.MIN_VALUE;
public static final String COMPONENTS_XML_PATH = "META-INF/plexus/components.xml";
@Override
public boolean canTransformResource(String resource) {
return COMPONENTS_XML_PATH.equals(resource);
}
@Override
public void processResource(String resource, InputStream is, List