Skip to content

Commit

Permalink
Better indentation when adding GCP libraries to pom.xml GoogleCloudPl…
Browse files Browse the repository at this point in the history
  • Loading branch information
lak-proddev committed Jun 26, 2019
1 parent a44850f commit e59d265
Showing 1 changed file with 134 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ void updateDependencies(Collection<Library> selectedLibraries,
// to delimit compilation/runtime dependencies from test dependencies.
Comment testComment = findTestComment(dependencies);

createBOMIfNeeded(xpath);
if (removedLibraries != null) {
removeUnusedDependencies(dependencies, selectedLibraries, removedLibraries);
}
Expand All @@ -218,8 +219,9 @@ void updateDependencies(Collection<Library> selectedLibraries,
String groupId = coordinates.getGroupId();
String artifactId = coordinates.getArtifactId();

if (!dependencyExists(dependencies, groupId, artifactId)) {
Element dependency = document.createElementNS(
Element dependency = findDependency(dependencies, groupId, artifactId);
if (dependency == null) {
dependency = document.createElementNS(
"http://maven.apache.org/POM/4.0.0", "dependency");
Element groupIdElement = document.createElementNS(
"http://maven.apache.org/POM/4.0.0", "groupId");
Expand All @@ -230,32 +232,14 @@ void updateDependencies(Collection<Library> selectedLibraries,
"http://maven.apache.org/POM/4.0.0", "artifactId");
artifactIdElement.setTextContent(artifactId);
dependency.appendChild(artifactIdElement);

if (!dependencyManaged(groupId, artifactId)) {
String version = coordinates.getVersion();
if (!artifact.isPinned()) {
ArtifactVersion latestVersion =
ArtifactRetriever.DEFAULT.getBestVersion(groupId, artifactId);
if (latestVersion != null) {
version = latestVersion.toString();
}
}

// todo latest version may not be needed anymore.
if (!MavenCoordinates.LATEST_VERSION.equals(version)) {
Element versionElement = document.createElementNS(
"http://maven.apache.org/POM/4.0.0", "version");
versionElement.setTextContent(version);
dependency.appendChild(versionElement);
}
}


if (testComment == null) {
dependencies.appendChild(dependency);
addChild(dependencies, dependency);
} else {
dependencies.insertBefore(dependency, testComment);
}
}
handleDependencyManaged(artifact, dependency);
}
}

Expand All @@ -270,6 +254,92 @@ void updateDependencies(Collection<Library> selectedLibraries,
}
}

private void handleDependencyManaged(LibraryFile artifact, Element dependency) {
MavenCoordinates coordinates = artifact.getMavenCoordinates();
String groupId = coordinates.getGroupId();
String artifactId = coordinates.getArtifactId();
Node versionNode = findChildByName(dependency, "version");
if (!dependencyManaged(groupId, artifactId)) {
if (versionNode == null) {
String version = coordinates.getVersion();
if (!artifact.isPinned()) {
ArtifactVersion latestVersion =
ArtifactRetriever.DEFAULT.getBestVersion(groupId, artifactId);
if (latestVersion != null) {
version = latestVersion.toString();
}
}
// todo latest version may not be needed anymore.
if (!MavenCoordinates.LATEST_VERSION.equals(version)) {
Element versionElement =
document.createElementNS("http://maven.apache.org/POM/4.0.0", "version");
versionElement.setTextContent(version);
dependency.appendChild(versionElement);
}
}
} else {
if (versionNode != null) {
removeChild(dependency, versionNode);
}
}
}

private void createBOMIfNeeded(XPath xpath) throws CoreException {
try {
Element bomElement = (Element) xpath.evaluate(
"//m:dependencyManagement/m:dependencies/m:dependency[m:groupId='com.google.cloud'][m:artifactId='google-cloud-bom']",
document.getDocumentElement(), XPathConstants.NODE);
if (bomElement == null) {
Element dependencies = null;
NodeList dependenciesNodes =
(NodeList) xpath.evaluate("//m:dependencyManagement/m:dependencies",
document.getDocumentElement(), XPathConstants.NODESET);
if (dependenciesNodes.getLength() > 0) {
dependencies = (Element) dependenciesNodes.item(0);
} else {
dependencies =
document.createElementNS("http://maven.apache.org/POM/4.0.0", "dependencies");
Node dependencyManagement = (Node) xpath.evaluate("//m:dependencyManagement",
document.getDocumentElement(), XPathConstants.NODE);
if (dependencyManagement == null) {
dependencyManagement = document.createElementNS("http://maven.apache.org/POM/4.0.0",
"dependencyManagement");
}
addChild(dependencyManagement, dependencies);
addChild(document.getDocumentElement(), dependencyManagement);
}

Element dependency =
document.createElementNS("http://maven.apache.org/POM/4.0.0", "dependency");
dependency.appendChild(createChild("groupId", "com.google.cloud"));
dependency.appendChild(createChild("artifactId", "google-cloud-bom"));
dependency.appendChild(createChild("type", "pom"));
dependency.appendChild(createChild("scope", "import"));
String version = getBestVersion("com.google.cloud", "google-cloud-bom");
dependency.appendChild(createChild("version", version));
Bom bom = Bom.loadBom("com.google.cloud", "google-cloud-bom", version, null);
if (bom != null) {
boms.add(bom);
}
addChild(dependencies, dependency);
}
} catch (XPathExpressionException ex) {
IStatus status = StatusUtil.error(Pom.class, ex.getMessage(), ex);
throw new CoreException(status);
}
}

private String getBestVersion(String groupId, String artifactId) {
ArtifactVersion latestVersion = ArtifactRetriever.DEFAULT.getBestVersion(groupId, artifactId);
return latestVersion != null ? latestVersion.toString() : MavenCoordinates.LATEST_VERSION;
}

private Element createChild(String name, String value) {
Element child = document.createElementNS("http://maven.apache.org/POM/4.0.0", name);
child.setTextContent(value);
return child;
}

private static Comment findTestComment(Element dependencies) {
NodeList children = dependencies.getChildNodes();

Expand All @@ -284,6 +354,20 @@ private static Comment findTestComment(Element dependencies) {
return null;
}

@VisibleForTesting
static Node findChildByName(Element dependency, String name) {
if (name == null || name.isEmpty())
return null;
NodeList childNodes = dependency.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (name.equals(node.getNodeName())) {
return node;
}
}
return null;
}

/**
* @return true if and only if this artifact is controlled by a BOM
*/
Expand Down Expand Up @@ -360,13 +444,17 @@ static void removeUnusedDependencies(Element dependencies,
}

for (Node node : nodesToRemove) {
dependencies.removeChild(node);
removeChild(dependencies, node);
}
}

private boolean dependencyExists(Element dependencies, String targetGroupId,
String targetArtifactId) {

return findDependency(dependencies, targetGroupId, targetArtifactId) != null;
}

@VisibleForTesting
Element findDependency(Element dependencies, String targetGroupId, String targetArtifactId) {
NodeList children = dependencies.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
Expand All @@ -375,11 +463,11 @@ private boolean dependencyExists(Element dependencies, String targetGroupId,
String groupId = getValue(dependency, "groupId");
String artifactId = getValue(dependency, "artifactId");
if (targetGroupId.equals(groupId) && targetArtifactId.equals(artifactId)) {
return true;
return dependency;
}
}
}
return false;
return null;
}

private static String getValue(Element dependency, String childName) {
Expand All @@ -394,10 +482,29 @@ private static String getValue(Element dependency, String childName) {
private void writeDocument() throws CoreException, TransformerException {
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4"); //$NON-NLS-1$ //$NON-NLS-2$
ByteArrayOutputStream out = new ByteArrayOutputStream();
transformer.transform(new DOMSource(document), new StreamResult(out));
InputStream in = new ByteArrayInputStream(out.toByteArray());

pomFile.setContents(in, true, true, null);
}

private void addChild(Node parent, Node newChild) {
parent.appendChild(newChild);
removeWhiteSpaceBefore(newChild);// for child indentation
}

private static void removeChild(Node parent, Node oldChild) {
removeWhiteSpaceBefore(oldChild);
parent.removeChild(oldChild);
}

private static void removeWhiteSpaceBefore(Node node) {
Node prevElement = node.getPreviousSibling();
if (prevElement != null && prevElement.getNodeType() == Node.TEXT_NODE
&& prevElement.getNodeValue().trim().length() == 0) {
node.getParentNode().removeChild(prevElement);
}
}
}

0 comments on commit e59d265

Please sign in to comment.