Pom.java

package org.flasby.util;

import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;

public class Pom {

	private final Class<?> classToDrivePomExtraction;

	private String version = "UNDEFINED";
	private String artifactId = "UNDEFINED";

	/**
	 * builds a Pom extractor for this project, flasby.org.
	 */
	public Pom() {
		this(Pom.class);
	}

	/**
	 * builds a Pom extractor for the project containing the passed class.
	 * 
	 * @param classToDrivePomExtraction
	 */
	public Pom(Class<?> classToDrivePomExtraction) {
		this.classToDrivePomExtraction = classToDrivePomExtraction;
		parse();
	}

	private void parse() {
		// Try to get version number from pom.xml (available in Eclipse)
		try {
			String className = classToDrivePomExtraction.getName();
			String classfileName = "/" + className.replace('.', '/') + ".class";
			URL classfileResource = getClass().getResource(classfileName);
			if (classfileResource != null) {
				Path absolutePackagePath = Paths.get(classfileResource.toURI()).getParent();
				if (absolutePackagePath == null) {
					throw new InvalidPathException(classfileResource.toURI().toString(),
							"Can't find Class to drive pom extraction parent, please check your settings");
				}
				System.out.println(absolutePackagePath);
				int packagePathSegments = className.length() - className.replace(".", "").length();
				// Remove package segments from path, plus two more levels
				// for "target/classes", which is the standard location for
				// classes in Eclipse.
				Path path = absolutePackagePath;
				for (int i = 0, segmentsToRemove = packagePathSegments + 2; i < segmentsToRemove; i++) {
					Path tp = path.getParent();
					if (tp != null) {
						path = tp;
					}
				}
				Path pom = path.resolve("pom.xml");
				if (pom == null) {
					throw new InvalidPathException(path.toString(), "Can't find pom.xml, please check your settings");
				}
				try (InputStream is = Files.newInputStream(pom)) {
					DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
					dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
					Document doc = dbf.newDocumentBuilder().parse(is);
					doc.getDocumentElement().normalize();
					version = getElement(doc, "/project/version");
					artifactId = getElement(doc, "/project/artifactId");
				}
			}
		} catch (RuntimeException e) {
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private String getElement(Document doc, String element) throws XPathExpressionException {
		String version = (String) XPathFactory.newInstance().newXPath().compile(element)
				.evaluate(doc, XPathConstants.STRING);
		if (version != null) {
			version = version.trim();
			if (!version.isEmpty()) {
				return version;
			}
		}
		return "Undefined";
	}

	public String getVersion() {
		return version;
	}

	public String getArtifactId() {
		return artifactId;
	}

}