forked from eclipse-jkube/jkube
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix eclipse-jkube#195: Added MigrateMojo for migrating projects from FMP
- Loading branch information
1 parent
d290c13
commit ad7b9c8
Showing
11 changed files
with
844 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/service/MigrateService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/** | ||
* Copyright (c) 2019 Red Hat, Inc. | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at: | ||
* | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat, Inc. - initial API and implementation | ||
*/ | ||
package org.eclipse.jkube.kit.common.service; | ||
|
||
import org.eclipse.jkube.kit.common.KitLogger; | ||
import org.eclipse.jkube.kit.common.util.XMLUtil; | ||
import org.w3c.dom.Document; | ||
import org.w3c.dom.Element; | ||
import org.w3c.dom.Node; | ||
import org.w3c.dom.NodeList; | ||
import org.xml.sax.SAXException; | ||
|
||
import javax.xml.parsers.ParserConfigurationException; | ||
import javax.xml.transform.TransformerException; | ||
import javax.xml.xpath.XPathExpressionException; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
|
||
public class MigrateService { | ||
private File projectBasedir; | ||
private static final String POM_XML = "pom.xml"; | ||
private static final String FABRIC8 = "fabric8"; | ||
private static final String JKUBE = "jkube"; | ||
private static final String DEFAULT_FABRIC8_RESOURCE_FRAGMENT_DIRECTORY = "src/main/" + FABRIC8; | ||
private static final String DEFAULT_RESOURCE_FRAGMENT_DIRECTORY = "src/main/" + JKUBE; | ||
private static final String ARTIFACT_ID = "artifactId"; | ||
private static final String GROUP_ID = "groupId"; | ||
private static final String VERSION = "version"; | ||
private static final String FABRIC8_MAVEN_PLUGIN_ARTIFACT_ID = FABRIC8 + "-maven-plugin"; | ||
private static final String POM_PROJECT_PATH = "/project"; | ||
private static final String POM_PROFILES_PATH = POM_PROJECT_PATH + "/profiles"; | ||
private static final String POM_PLUGINS_PATH = "/build/plugins"; | ||
private static final String POM_PROPERTIES_PATH = "/properties"; | ||
private static final String POM_PLUGIN_PATH = "/plugin"; | ||
private KitLogger logger; | ||
|
||
public MigrateService(File projectBaseDirectory, KitLogger logger) { | ||
this.projectBasedir = projectBaseDirectory; | ||
this.logger = logger; | ||
} | ||
|
||
public void migrate(String pluginGroupId, String pluginArtifactId, String pluginVersion) throws IOException, ParserConfigurationException, SAXException, TransformerException, XPathExpressionException { | ||
File pomFile = getPomFile(); | ||
String pomContent = new String(Files.readAllBytes(pomFile.toPath()), StandardCharsets.UTF_8); | ||
String modifiedPomContent = searchAndReplaceEnricherRefsInPomToJKube(pomContent); | ||
Files.write(pomFile.toPath(), modifiedPomContent.getBytes(StandardCharsets.UTF_8)); | ||
if (pomContainsFMP(pomContent)) { | ||
Document dom = XMLUtil.readXML(pomFile); | ||
|
||
// Check Whether plugin is present in project.build.plugins | ||
modifyFMPPluginSectionInsideBuild(dom, pluginGroupId, pluginArtifactId, pluginVersion); | ||
// Check Whether plugin is present in project.profiles.build.plugins | ||
modifyFMPSectionInsideProfile(dom, pluginGroupId, pluginArtifactId, pluginVersion); | ||
// Rename all Fabric8 related properties to JKube | ||
modifyFMPPropertiesInsidePom(dom); | ||
|
||
XMLUtil.writeXML(dom, pomFile); | ||
renameResourceFragmentDirectoryToJKube(); | ||
} else { | ||
logger.warn("Unable to find Fabric8 Maven Plugin inside pom"); | ||
} | ||
} | ||
|
||
private String searchAndReplaceEnricherRefsInPomToJKube(String pomContent) { | ||
pomContent = pomContent.replace("fmp-", JKUBE + "-"); | ||
pomContent = pomContent.replace("f8-", JKUBE + "-"); | ||
|
||
return pomContent; | ||
} | ||
|
||
private boolean pomContainsFMP(String pomContent) { | ||
return pomContent.contains(FABRIC8_MAVEN_PLUGIN_ARTIFACT_ID); | ||
} | ||
|
||
private File getPomFile() { | ||
return new File(projectBasedir, POM_XML); | ||
} | ||
|
||
private File getResourceFragmentDirectory(File projectBasedir) { | ||
return new File(projectBasedir, DEFAULT_FABRIC8_RESOURCE_FRAGMENT_DIRECTORY); | ||
} | ||
|
||
private void modifyFMPPluginSectionInsideBuild(Document dom, String pluginGroupId, String pluginArtifactId, String pluginVersion) throws XPathExpressionException { | ||
convertFMPNodeToJKube(dom, pluginGroupId, pluginArtifactId, pluginVersion, POM_PROJECT_PATH + POM_PLUGINS_PATH); | ||
} | ||
|
||
private void modifyFMPSectionInsideProfile(Document dom, String pluginGroupId, String pluginArtifactId, String pluginVersion) throws XPathExpressionException { | ||
Node profilesNode = XMLUtil.getNodeFromDocument(dom, POM_PROFILES_PATH); | ||
if (profilesNode != null) { | ||
NodeList nodeList = profilesNode.getChildNodes(); | ||
for (int i = 0; i < nodeList.getLength(); i++) { | ||
convertFMPNodeToJKube(dom, pluginGroupId, pluginArtifactId, pluginVersion, POM_PROFILES_PATH + "/profile[" + i + "]" + POM_PLUGINS_PATH); | ||
} | ||
} | ||
} | ||
|
||
private void convertFMPNodeToJKube(Document dom, String pluginGroupId, String pluginArtifactId, String pluginVersion, String parentXPathExpression) throws XPathExpressionException { | ||
Node fmpNode = XMLUtil.getNodeFromDocument(dom, parentXPathExpression + POM_PLUGIN_PATH + "[artifactId='" + FABRIC8_MAVEN_PLUGIN_ARTIFACT_ID + "']"); | ||
if (fmpNode != null) { | ||
Element fmpNodeElem = (Element) fmpNode; | ||
Node artifactNode = fmpNodeElem.getElementsByTagName(ARTIFACT_ID).item(0); | ||
Node groupNode = fmpNodeElem.getElementsByTagName(GROUP_ID).item(0); | ||
Node versionNode = fmpNodeElem.getElementsByTagName(VERSION).item(0); | ||
logger.info("Found Fabric8 Maven Plugin in pom with version " + versionNode.getTextContent()); | ||
groupNode.setTextContent(pluginGroupId); | ||
artifactNode.setTextContent(pluginArtifactId); | ||
versionNode.setTextContent(pluginVersion); | ||
} | ||
} | ||
|
||
private void renameResourceFragmentDirectoryToJKube() { | ||
File resourceFragmentDir = getResourceFragmentDirectory(projectBasedir); | ||
if (resourceFragmentDir.exists()) { | ||
File jkubeResourceDir = new File(projectBasedir, DEFAULT_RESOURCE_FRAGMENT_DIRECTORY); | ||
boolean isRenamed = resourceFragmentDir.renameTo(jkubeResourceDir); | ||
if (!isRenamed) { | ||
logger.warn("Unable to rename resource fragment directory in project"); | ||
} else { | ||
logger.info("Renamed " + DEFAULT_FABRIC8_RESOURCE_FRAGMENT_DIRECTORY + " to " + DEFAULT_RESOURCE_FRAGMENT_DIRECTORY); | ||
} | ||
} | ||
} | ||
|
||
private void modifyFMPPropertiesInsidePom(Document dom) throws XPathExpressionException { | ||
Node propertiesNode = XMLUtil.getNodeFromDocument(dom, POM_PROJECT_PATH + POM_PROPERTIES_PATH); | ||
if (propertiesNode != null) { | ||
NodeList nodeList = propertiesNode.getChildNodes(); | ||
for (int i = 0; i < nodeList.getLength(); i++) { | ||
Node property = nodeList.item(i); | ||
if (property.getNodeName().contains(FABRIC8)) { | ||
String nodeName = property.getNodeName(); | ||
nodeName = nodeName.replace(FABRIC8, JKUBE); | ||
dom.renameNode(property, null, nodeName); | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
94 changes: 94 additions & 0 deletions
94
jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/XMLUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/** | ||
* Copyright (c) 2019 Red Hat, Inc. | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at: | ||
* | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat, Inc. - initial API and implementation | ||
*/ | ||
package org.eclipse.jkube.kit.common.util; | ||
|
||
import org.w3c.dom.Document; | ||
import org.w3c.dom.Node; | ||
import org.xml.sax.SAXException; | ||
|
||
import javax.xml.XMLConstants; | ||
import javax.xml.parsers.DocumentBuilder; | ||
import javax.xml.parsers.DocumentBuilderFactory; | ||
import javax.xml.parsers.ParserConfigurationException; | ||
import javax.xml.transform.Transformer; | ||
import javax.xml.transform.TransformerException; | ||
import javax.xml.transform.TransformerFactory; | ||
import javax.xml.transform.dom.DOMSource; | ||
import javax.xml.transform.stream.StreamResult; | ||
import javax.xml.xpath.XPath; | ||
import javax.xml.xpath.XPathConstants; | ||
import javax.xml.xpath.XPathExpressionException; | ||
import javax.xml.xpath.XPathFactory; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
public class XMLUtil { | ||
private static List<String> featuresToDisable = Arrays.asList("http://apache.org/xml/features/nonvalidating/load-external-dtd", | ||
"http://apache.org/xml/features/disallow-doctype-decl", | ||
"http://xml.org/sax/features/external-general-entities", | ||
"http://xml.org/sax/features/external-parameter-entities"); | ||
|
||
private XMLUtil() { } | ||
|
||
public static Document createNewDocument() throws ParserConfigurationException { | ||
DocumentBuilderFactory documentBuilderFactory = getDocumentBuilderFactory(); | ||
return documentBuilderFactory.newDocumentBuilder().newDocument(); | ||
} | ||
|
||
public static Document readXML(File xmlFile) throws ParserConfigurationException, IOException, SAXException { | ||
DocumentBuilderFactory documentBuilderFactory = getDocumentBuilderFactory(); | ||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); | ||
|
||
return documentBuilder.parse(xmlFile); | ||
} | ||
|
||
public static void writeXML(Document document, File xmlFile) throws TransformerException { | ||
TransformerFactory transformerFactory = TransformerFactory.newInstance(); | ||
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); | ||
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); | ||
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); | ||
Transformer transformer = transformerFactory.newTransformer(); | ||
document.setXmlStandalone(true); | ||
DOMSource source = new DOMSource(document); | ||
StreamResult result = new StreamResult(xmlFile); | ||
transformer.transform(source, result); | ||
} | ||
|
||
public static Node getNodeFromDocument(Document doc, String xPathExpression) throws XPathExpressionException { | ||
XPathFactory xPathfactory = XPathFactory.newInstance(); | ||
XPath xpath = xPathfactory.newXPath(); | ||
return (Node) xpath.compile(xPathExpression).evaluate(doc, XPathConstants.NODE); | ||
} | ||
|
||
public static String getNodeValueFromDocument(Document doc, String xPathExpression) throws XPathExpressionException { | ||
XPathFactory xPathfactory = XPathFactory.newInstance(); | ||
XPath xpath = xPathfactory.newXPath(); | ||
return (String) xpath.compile(xPathExpression).evaluate(doc, XPathConstants.STRING); | ||
} | ||
|
||
private static DocumentBuilderFactory getDocumentBuilderFactory() throws ParserConfigurationException { | ||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); | ||
documentBuilderFactory.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true); | ||
documentBuilderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); | ||
documentBuilderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); | ||
for (String feature : featuresToDisable) { | ||
documentBuilderFactory.setFeature(feature, false); | ||
} | ||
documentBuilderFactory.setXIncludeAware(false); | ||
documentBuilderFactory.setExpandEntityReferences(false); | ||
return documentBuilderFactory; | ||
} | ||
} |
96 changes: 96 additions & 0 deletions
96
jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/service/MigrateServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/** | ||
* Copyright (c) 2019 Red Hat, Inc. | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at: | ||
* | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat, Inc. - initial API and implementation | ||
*/ | ||
package org.eclipse.jkube.kit.common.service; | ||
|
||
import mockit.Mocked; | ||
import org.apache.commons.io.FileUtils; | ||
import org.eclipse.jkube.kit.common.KitLogger; | ||
import org.eclipse.jkube.kit.common.util.XMLUtil; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.rules.TemporaryFolder; | ||
import org.w3c.dom.Document; | ||
|
||
import java.io.File; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
public class MigrateServiceTest { | ||
@Mocked | ||
KitLogger logger; | ||
|
||
@Rule | ||
public TemporaryFolder folder = new TemporaryFolder(); | ||
|
||
@Test | ||
public void testPomPluginMigrationInBuild() throws Exception { | ||
// Given | ||
File projectPom = new File(getClass().getResource("/test-project/pom.xml").toURI()); | ||
File pomFile = folder.newFile("pom.xml"); | ||
FileUtils.copyFile(projectPom, pomFile); | ||
MigrateService migrateService = new MigrateService(folder.getRoot(), logger); | ||
|
||
// When | ||
migrateService.migrate("org.eclipse.jkube", "kubernetes-maven-plugin", "1.0.0-SNAPSHOT"); | ||
|
||
// Then | ||
Document document = XMLUtil.readXML(pomFile); | ||
assertTrue(pomFile.exists()); | ||
assertEquals("org.eclipse.jkube", XMLUtil.getNodeValueFromDocument(document, "/project/build/plugins/plugin[2]/groupId")); | ||
assertEquals("kubernetes-maven-plugin", XMLUtil.getNodeValueFromDocument(document, "/project/build/plugins/plugin[2]/artifactId")); | ||
assertEquals("1.0.0-SNAPSHOT", XMLUtil.getNodeValueFromDocument(document, "/project/build/plugins/plugin[2]/version")); | ||
} | ||
|
||
|
||
@Test | ||
public void testPomPluginMigrationInProfile() throws Exception { | ||
// Given | ||
File projectPom = new File(getClass().getResource("/test-project-profile/pom.xml").toURI()); | ||
File pomFile = folder.newFile("pom.xml"); | ||
FileUtils.copyFile(projectPom, pomFile); | ||
MigrateService migrateService = new MigrateService(folder.getRoot(), logger); | ||
|
||
// When | ||
migrateService.migrate("org.eclipse.jkube", "kubernetes-maven-plugin", "1.0.0-SNAPSHOT"); | ||
|
||
// Then | ||
Document document = XMLUtil.readXML(pomFile); | ||
assertTrue(pomFile.exists()); | ||
assertEquals("org.eclipse.jkube", XMLUtil.getNodeValueFromDocument(document, "/project/profiles/profile[1]/build/plugins/plugin[1]/groupId")); | ||
assertEquals("kubernetes-maven-plugin", XMLUtil.getNodeValueFromDocument(document, "/project/profiles/profile[1]/build/plugins/plugin[1]/artifactId")); | ||
assertEquals("1.0.0-SNAPSHOT", XMLUtil.getNodeValueFromDocument(document, "/project/profiles/profile[1]/build/plugins/plugin[1]/version")); | ||
} | ||
|
||
@Test | ||
public void testProjectResourceFragmentDirectoryRename() throws Exception { | ||
// Given | ||
File projectPom = new File(getClass().getResource("/test-project-profile/pom.xml").toURI()); | ||
File pomFile = folder.newFile("pom.xml"); | ||
folder.newFolder("src", "main", "fabric8"); | ||
FileUtils.copyFile(projectPom, pomFile); | ||
MigrateService migrateService = new MigrateService(folder.getRoot(), logger); | ||
|
||
// When | ||
migrateService.migrate("org.eclipse.jkube", "kubernetes-maven-plugin", "1.0.0-SNAPSHOT"); | ||
|
||
// Then | ||
Document document = XMLUtil.readXML(pomFile); | ||
assertTrue(pomFile.exists()); | ||
assertTrue(new File(folder.getRoot(), "src/main/jkube").exists()); | ||
assertEquals("org.eclipse.jkube", XMLUtil.getNodeValueFromDocument(document, "/project/profiles/profile[1]/build/plugins/plugin[1]/groupId")); | ||
assertEquals("kubernetes-maven-plugin", XMLUtil.getNodeValueFromDocument(document, "/project/profiles/profile[1]/build/plugins/plugin[1]/artifactId")); | ||
assertEquals("1.0.0-SNAPSHOT", XMLUtil.getNodeValueFromDocument(document, "/project/profiles/profile[1]/build/plugins/plugin[1]/version")); | ||
} | ||
} |
Oops, something went wrong.