All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wildfly.channelplugin.manipulation.PomManipulator Maven / Gradle / Ivy

Go to download

This maven plugin overrides dependencies versions in a Maven project according to Wildfly channel definition.

There is a newer version: 1.0.19
Show newest version
package org.wildfly.channelplugin.manipulation;

import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
import java.util.Stack;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;

import org.apache.http.util.Asserts;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.stax2.XMLInputFactory2;
import org.commonjava.maven.atlas.ident.ref.ArtifactRef;
import org.commonjava.maven.atlas.ident.ref.ProjectRef;
import org.commonjava.maven.ext.common.model.Project;

/**
 * Provides functionality to manipulate properties and dependencies in a POM file.
 */
public class PomManipulator {

    private static final String DEPENDENCY_MANAGEMENT_PATH = "/project/dependencyManagement/dependencies";
    private static final String REPOSITORIES_PATH = "/project/repositories";
    private static final String PLUGIN_REPOSITORIES_PATH = "/project/pluginRepositories";
    private static final String DEPENDENCIES = "dependencies";
    private static final String REPOSITORIES = "repositories";
    private static final String PLUGIN_REPOSITORIES = "pluginRepositories";

    private final Project project;
    private final ModifiedPomXMLEventReader eventReader;
    private final StringBuilder content;
    private boolean closed = false;

    /**
     * @param project Project instance
     */
    public PomManipulator(Project project) {
        try {
            this.project = project;
            XMLInputFactory inputFactory = XMLInputFactory2.newInstance();
            inputFactory.setProperty(XMLInputFactory2.P_PRESERVE_LOCATION, Boolean.TRUE);
            this.content = PomHelper.readXmlFile(project.getPom());
            this.eventReader = new ModifiedPomXMLEventReader(content, inputFactory, project.getPom().getPath());
        } catch (IOException | XMLStreamException e) {
            throw new RuntimeException("Couldn't initialize PomWriter instance", e);
        }
    }

    public void overrideDependencyVersion(ArtifactRef d, String newVersion) throws XMLStreamException {
        PomHelper.setDependencyVersion(eventReader, d.getGroupId(), d.getArtifactId(), d.getVersionString(),
                newVersion, project.getModel());
    }

    public void overrideDependencyVersion(String groupId, String artifactId, String oldVersionString, String newVersion) throws XMLStreamException {
        PomHelper.setDependencyVersion(eventReader, groupId, artifactId, oldVersionString, newVersion,
                project.getModel());
    }

    public boolean overrideProperty(String propertyName, String propertyValue) throws XMLStreamException {
        return PomHelper.setPropertyVersion(eventReader, null, propertyName, propertyValue);
    }

    public void injectManagedDependency(ArtifactRef dependency, Collection exclusions) throws XMLStreamException {
        injectManagedDependency(eventReader, dependency, exclusions);
    }

    public void injectRepository(String id, String url) throws XMLStreamException {
        eventReader.rewind();

        Stack stack = new Stack();
        String path = "";

        while (eventReader.hasNext()) {
            XMLEvent event = eventReader.nextEvent();
            if (event.isStartElement()) {
                stack.push(path);
                path = path + "/" + event.asStartElement().getName().getLocalPart();
            } else if (event.isEndElement()) {
                // replaces "" end element with new repository + the end element
                String elementName = event.asEndElement().getName().getLocalPart();
                if (elementName.equals(REPOSITORIES) && path.equals(REPOSITORIES_PATH)) {
                    eventReader.mark(0);
                    eventReader.replaceMark(0, composeRepositoryElementString(id, url)
                            + "    "
                    );
                    eventReader.clearMark(0);
                    break;
                }

                path = stack.pop();
            }
        }
    }

    public void injectPluginRepository(String id, String url) throws XMLStreamException {
        eventReader.rewind();

        Stack stack = new Stack();
        String path = "";

        while (eventReader.hasNext()) {
            XMLEvent event = eventReader.nextEvent();
            if (event.isStartElement()) {
                stack.push(path);
                path = path + "/" + event.asStartElement().getName().getLocalPart();
            } else if (event.isEndElement()) {
                // replaces "" end element with new repository + the end element
                String elementName = event.asEndElement().getName().getLocalPart();
                if (elementName.equals(PLUGIN_REPOSITORIES) && path.equals(PLUGIN_REPOSITORIES_PATH)) {
                    eventReader.mark(0);
                    eventReader.replaceMark(0, composePluginRepositoryElementString(id, url)
                            + "    "
                    );
                    eventReader.clearMark(0);
                    break;
                }

                path = stack.pop();
            }
        }
    }

    public void injectProperty(String key, String version) throws XMLStreamException {
        injectProperty(eventReader, key, version);
    }

    /**
     * Writes the updated POM file.
     */
    public void writePom() {
        assertOpen();
        try (Writer writer = WriterFactory.newXmlWriter(project.getPom())) {
            closed = true;
            IOUtil.copy(content.toString(), writer);
            eventReader.close();
        } catch (IOException e) {
            throw new RuntimeException("Failed to write to the pom file", e);
        } catch (XMLStreamException e) {
            throw new RuntimeException("Couldn't close event reader", e);
        }
    }

    private void assertOpen() {
        Asserts.check(!closed, "This instance cannot be used repeatedly.");
    }

    /**
     * This method attempts to inject new dependency into at the end of the dependencyManagement section.
     * 

* The dependencyManagement section must be already present in the POM. */ static void injectManagedDependency(ModifiedPomXMLEventReader eventReader, ArtifactRef dependency, Collection exclusions) throws XMLStreamException { eventReader.rewind(); Stack stack = new Stack<>(); String path = ""; while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); if (event.isStartElement()) { stack.push(path); path = path + "/" + event.asStartElement().getName().getLocalPart(); } else if (event.isEndElement()) { if (event.asEndElement().getName().getLocalPart().equals(DEPENDENCIES) && path.equals(DEPENDENCY_MANAGEMENT_PATH)) { eventReader.mark(0); eventReader.replaceMark(0, composeDependencyElementString(dependency, exclusions) + " " ); eventReader.clearMark(0); break; } path = stack.pop(); } } } /** * This method attempts to inject new property at the end of the properties section. *

* The properties section must be already present in the POM. */ static void injectProperty(ModifiedPomXMLEventReader eventReader, String key, String version) throws XMLStreamException { eventReader.rewind(); Stack stack = new Stack<>(); String path = ""; while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); if (event.isStartElement()) { stack.push(path); path = path + "/" + event.asStartElement().getName().getLocalPart(); } else if (event.isEndElement()) { if (event.asEndElement().getName().getLocalPart().equals("properties") && path.equals("/project/properties")) { eventReader.mark(0); eventReader.replaceMark(0, String.format(" <%s>%s\n", key, version, key) + " " ); eventReader.clearMark(0); break; } path = stack.pop(); } } } private static String composeDependencyElementString(ArtifactRef artifact, Collection exclusions) { StringBuilder sb = new StringBuilder(); sb.append(" \n"); sb.append(String.format(" %s\n", artifact.getGroupId())); sb.append(String.format(" %s\n", artifact.getArtifactId())); sb.append(String.format(" %s\n", artifact.getVersionString())); if (artifact.getClassifier() != null) { sb.append(String.format(" %s\n", artifact.getClassifier())); } if (!"jar".equals(artifact.getType())) { sb.append(String.format(" %s\n", artifact.getType())); } if (exclusions != null && !exclusions.isEmpty()) { sb.append(" \n"); for (ProjectRef e: exclusions) { sb.append(" \n"); sb.append(" " + e.getGroupId() + "\n"); sb.append(" " + e.getArtifactId() + "\n"); sb.append(" \n"); } sb.append(" \n"); } sb.append(" \n"); return sb.toString(); } private static String composeRepositoryElementString(String id, String url) { StringBuilder sb = new StringBuilder(); sb.append(" \n"); sb.append(String.format(" %s\n", id)); sb.append(String.format(" %s\n", url)); sb.append(" \n"); sb.append(" true\n"); sb.append(" always\n"); sb.append(" \n"); sb.append(" \n"); sb.append(" true\n"); sb.append(" always\n"); sb.append(" \n"); sb.append(" \n"); return sb.toString(); } private static String composePluginRepositoryElementString(String id, String url) { StringBuilder sb = new StringBuilder(); sb.append(" \n"); sb.append(String.format(" %s\n", id)); sb.append(String.format(" %s\n", url)); sb.append(" \n"); sb.append(" true\n"); sb.append(" always\n"); sb.append(" \n"); sb.append(" \n"); sb.append(" true\n"); sb.append(" always\n"); sb.append(" \n"); sb.append(" \n"); return sb.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy