package net.sourceforge.javautil.classloader.resolver.impl.maven;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import net.sourceforge.javautil.classloader.resolver.ClassPackageException;
import net.sourceforge.javautil.classloader.resolver.IClassArtifactReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackageDependencyReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackageReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackageDescriptor;
import net.sourceforge.javautil.classloader.resolver.IClassPackageRelocation;
import net.sourceforge.javautil.classloader.resolver.IClassPackageRepositoryRemote;
import net.sourceforge.javautil.classloader.resolver.IClassDependency.Scope;
import net.sourceforge.javautil.classloader.resolver.IClassPackage.IVersion;
import net.sourceforge.javautil.classloader.resolver.IClassPackageResolver;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageImpl;
import net.sourceforge.javautil.classloader.resolver.impl.maven.ProjectObjectModel.Dependency.Exclusion;
import net.sourceforge.javautil.classloader.util.ClassPackageUtil;
import net.sourceforge.javautil.common.IOUtil;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IInputSource;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.impl.ISystemArtifact;
import net.sourceforge.javautil.common.io.impl.SystemFile;
import net.sourceforge.javautil.common.jaxb.JavaXML;
import net.sourceforge.javautil.common.jaxb.XmlElementName;
import net.sourceforge.javautil.common.jaxb.XmlElementOrder;
import net.sourceforge.javautil.common.jaxb.XmlMap;
import net.sourceforge.javautil.common.jaxb.XmlMap.Type;
import net.sourceforge.javautil.common.jaxb.XmlParent;
/**
* The trimmed down XML bindings for pom.xml files.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ProjectObjectModel.java 2745 2011-02-05 04:23:36Z ponderator $
*/
@XmlRootElement(name="project")
public class ProjectObjectModel implements IClassPackageDescriptor, IClassPackageReference {
public static final String DEFAULT_APACHE_REPOSITORY = "http://repo1.maven.org/maven2/";
public static final String DEFAULT_FILE_NAME = "pom.xml";
public static final String DEFAULT_BUILD_DIRECTORY = "target";
public static final String DEFAULT_BUILD_OUTPUTDIRECTORY = DEFAULT_BUILD_DIRECTORY + "/classes";
public static final String DEFAULT_BUILD_TESTOUTPUTDIRECTORY = DEFAULT_BUILD_DIRECTORY + "/test-classes";
public static Logger log = Logger.getLogger(ProjectObjectModel.class.getName());
public static final Pattern VAR_PATTERN = Pattern.compile(".*(\\$\\{([-A-Za-z0-9\\._]+)}).*");
public static final JavaXML POM_CONTEXT;
static {
try {
POM_CONTEXT = JavaXML.newInstance(ProjectObjectModel.class);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static ProjectObjectModel parse (IClassPackageResolver resolver, IInputSource input) {
try {
log.fine("Parsing Maven POM: " + input);
ProjectObjectModel pom = (ProjectObjectModel) POM_CONTEXT.unmarshal(input);
pom.setInput(input);
if (pom.getParent() != null) {
pom.setParentPom( (ProjectObjectModel) resolver.getDescriptor(pom.getParent()) );
}
return pom;
} catch (JAXBException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
protected IInputSource input;
protected String modelVersion;
protected String artifactId;
protected String groupId;
protected IVersion version;
protected String versionString;
protected String packaging;
protected Parent parent;
protected ProjectObjectModel parentPom;
protected Build build;
protected DistributionManagement distributionManagement;
protected DependencyManagement dependencyManagement;
protected List<Repository> repositories = new ArrayList<Repository>();
protected List<Dependency> dependencies = new ArrayList<Dependency>();
protected Properties properties = new Properties();
public ProjectObjectModel () {}
private ProjectObjectModel (ProjectObjectModel parent, Dependency dependency) {
this.parentPom = parent;
this.groupId = dependency.getGroupId();
this.artifactId = dependency.getArtifactId();
this.versionString = dependency.getVersionString();
this.version = dependency.getVersion();
}
@XmlElementOrder(before="groupId") public String getModelVersion() { return modelVersion; }
public void setModelVersion(String modelVersion) {
this.modelVersion = modelVersion;
}
@XmlElementOrder(before="classifier") public String getArtifactId() { return artifactId; }
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
this.properties.properties.put("project.artifactId", artifactId);
this.properties.properties.put("pom.artifactId", artifactId);
}
@XmlElementOrder(before="artifactId") public String getGroupId() {
if (this.groupId == null && this.parent != null) return this.parent.getGroupId();
return this.parse(groupId);
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
@XmlTransient public IVersion getVersion() {
if (version == null) {
if (versionString != null && !"".equals(versionString)) {
version = ClassPackageImpl.decode(versionString);
} else if (parent != null && parent.getVersion() != null) {
version = parent.getVersion();
}
}
return version;
}
@XmlElement(name="version") public String getVersionString() {
return versionString;
}
public void setVersionString(String versionString) {
this.versionString = versionString;
}
@XmlElementOrder(before="version")
public String getClassifier() { return null; }
@XmlTransient @Override public boolean isDescriptorOnly() {
return "pom".equals(packaging);
}
@XmlElementOrder(after="version")
public Parent getParent() { return parent; }
public void setParent(Parent parent) { this.parent = parent; }
@XmlTransient public ProjectObjectModel getParentPom() { return parentPom; }
public void setParentPom(ProjectObjectModel parentPom) { this.parentPom = parentPom; }
@XmlElementOrder(after="version")
public String getPackaging() { return packaging; }
public void setPackaging(String packaging) { this.packaging = packaging; }
@XmlElementOrder(after="packaging") public Build getBuild() { return build; }
public void setBuild(Build build) { this.build = build; }
@XmlElementWrapper(name="repositories") @XmlElementOrder(after="build")
public List<Repository> getRepositories() { return repositories; }
public void setRepositories(List<Repository> repositories) { this.repositories = repositories; }
@XmlElementWrapper(name="dependencies") @XmlElementOrder(after="repositories")
public List<Dependency> getDependencies() { return dependencies; }
public void setDependencies(List<Dependency> dependencies) { this.dependencies = dependencies; }
@XmlElementOrder(before="dependencyManagement")
public DistributionManagement getDistributionManagement() { return distributionManagement; }
public void setDistributionManagement(DistributionManagement distributionManagement) { this.distributionManagement = distributionManagement; }
@XmlElementOrder(after="dependencies") public DependencyManagement getDependencyManagement() { return dependencyManagement; }
public void setDependencyManagement(DependencyManagement dependencyManagement) { this.dependencyManagement = dependencyManagement; }
@XmlElementOrder(after="dependencyManagement")
public Properties getProperties() { return properties; }
public void setProperties(Properties properties) { this.properties = properties; }
//
// CONVENIENCE METHODS
//
protected IInputSource getInput() { return input; }
protected void setInput(IInputSource input) { this.input = input; }
/**
* @return The specified build directory or {@link #DEFAULT_BUILD_DIRECTORY}
*/
@XmlTransient public String getBuildDirectoryOrDefault () {
return build != null && build.directory != null ? build.directory : DEFAULT_BUILD_DIRECTORY;
}
/**
* @return The specified build output directory or {@link #DEFAULT_BUILD_OUTPUTDIRECTORY}
*/
@XmlTransient public String getCompileDirectoryOrDefault () {
return build != null && build.outputDirectory != null ? build.outputDirectory : DEFAULT_BUILD_OUTPUTDIRECTORY;
}
/**
* @return The specified build test output directory or {@link #DEFAULT_BUILD_TESTOUTPUTDIRECTORY}
*/
@XmlTransient public String getCompileTestsDirectoryOrDefault () {
return build != null && build.testOutputDirectory != null ? build.testOutputDirectory : DEFAULT_BUILD_TESTOUTPUTDIRECTORY;
}
@XmlTransient public List<String> getRemoteRepositories() {
List<String> repositories = new ArrayList<String>();
if (this.repositories.size() != 0) {
for (Repository repository : this.repositories) {
repositories.add( repository.getUrl() );
}
} else {
repositories.add( MavenRepositoryRemote.DEFAULT_APACHE_REPOSITORY );
}
return repositories;
}
public IClassPackageRepositoryRemote createRepository(String url) {
try {
return new MavenRepositoryRemote(url, new URL(url));
} catch (MalformedURLException e) {
throw ThrowableManagerRegistry.caught(e);
}
}
@XmlTransient public List<? extends IClassArtifactReference> getExclusions () {
List<Exclusion> exclusions = new ArrayList<Exclusion>();
for (Dependency dependency : this.dependencies) {
exclusions.addAll( dependency.getExclusions() );
}
return exclusions;
}
@XmlTransient @Override public IClassPackageRelocation getRelocation() {
DistributionManagement dm = this.getDistributionManagement();
return dm != null && dm.getRelocation() != null ? dm.getRelocation() : null;
}
public List<? extends IClassPackageDependencyReference> getDependencies(Scope scope) {
List<Dependency> dependencies = new ArrayList<Dependency>();
for (Dependency dependency : this.dependencies) {
if (dependency.shouldLoad(scope)) dependencies.add(dependency);
}
if (this.parentPom != null) {
if (this.parentPom.dependencies != null)
dependencies.addAll( (List<Dependency>) parentPom.getDependencies(scope) );
}
return dependencies;
}
@XmlTransient @Override public String getNamespace() { return this.groupId; }
@XmlTransient @Override public String getName() { return this.artifactId; }
@XmlTransient @Override public String getUniqueIdentifier() {
return this.toArtifactString();
}
public void write (OutputStream output) throws JAXBException {
if (this.input == null) {
throw new ClassPackageException(this, "Cannot write out simulated POM files");
}
try {
IOUtil.transfer(input.getInputStream(), output);
} catch (IOException e) {
throw new ClassPackageException(this, "Could not write out original source");
}
}
public String toString () { return ClassPackageUtil.toString(this); }
public String toArtifactString() {
return this.getGroupId() + ":" + this.getArtifactId(); }
public int compareTo(IClassArtifactReference o) { return ClassPackageUtil.compare(this, o); }
public boolean equals (Object object) {
return object instanceof IClassArtifactReference ? this.compareTo((IClassArtifactReference)object) == 0 : false;
}
protected Dependency getDependencyManagement (IClassArtifactReference reference) {
Dependency dependency = this.dependencyManagement == null ? null : dependencyManagement.getManagement(reference);
if (dependency == null && parentPom != null) {
dependency = parentPom.getDependencyManagement(reference);
}
return dependency;
}
@Override public boolean isExcluded(IClassArtifactReference reference) {
if (this.dependencyManagement != null && dependencyManagement.isExcluded(reference)) return true;
return parentPom != null && parentPom.isExcluded(reference);
}
protected IVersion resolveVersion (Dependency dependency) {
if (this.dependencyManagement != null) {
IVersion version = dependencyManagement.findVersion(dependency);
if (version != null) return version;
}
if (this.parent != null && this.parent.getGroupId().equals(dependency.getGroupId()) &&
this.parent.getArtifactId().equals(dependency.getArtifactId()) && this.parent.version != null) {
return this.parent.version;
}
if (this.parentPom != null) return this.parentPom.resolveVersion(dependency);
return getVersion();
}
protected String parse (String value) {
if (value == null || "".equals(value)) return null;
if (!value.contains("${")) return value;
for (Matcher matcher=VAR_PATTERN.matcher(value.trim()); matcher.matches(); matcher=VAR_PATTERN.matcher(value)) {
String key = matcher.group(2);
if (key.startsWith("pom.") || key.startsWith("project.")) {
String[] items = key.split("\\.");
if (items.length == 2) {
if ("version".equalsIgnoreCase(items[1]) && this.getVersion() != null) {
value = value.replace(matcher.group(), this.getVersion().toVersionString());
continue;
} else if ("artifactId".equalsIgnoreCase(items[1]) && this.getArtifactId() != null) {
value = value.replace(matcher.group(), this.getArtifactId());
continue;
} else if ("groupId".equalsIgnoreCase(items[1]) && this.getGroupId() != null) {
value = value.replace(matcher.group(), this.getGroupId());
continue;
}
}
}
String replacement = null;
if (this.properties.containsKey(key)) {
replacement = this.properties.getProperty(key);
} else if (parentPom != null) {
ProjectObjectModel pp = parentPom;
while (pp != null) {
if (pp.properties.containsKey(key)) {
replacement = pp.properties.getProperty(key);
break;
}
pp = pp.parentPom;
}
}
if (replacement == null) {
log.warning("Could not resolve: " + key);
value = value.replace(matcher.group(1), "");
} else
value = value.replace(matcher.group(1), replacement);
}
value = value.trim();
return "".equals(value) ? null : value;
}
/**
* The parent element of a pom.xml
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ProjectObjectModel.java 2745 2011-02-05 04:23:36Z ponderator $
*/
@XmlType(name="parent")
public static class Parent implements IClassPackageReference {
protected String groupId;
protected String artifactId;
protected String versionString;
protected IVersion version;
protected ProjectObjectModel pom;
public String getGroupId() { return groupId; }
public void setGroupId(String groupId) { this.groupId = groupId; }
public String getArtifactId() { return artifactId; }
public void setArtifactId(String artifactId) { this.artifactId = artifactId; }
@XmlElement(name="version") public String getVersionString() {
return this.versionString;
}
public void setVersionString(String version) {
this.versionString = version;
this.version = null;
}
@XmlTransient public IVersion getVersion() {
if (version == null && this.versionString != null && !"".equals(this.versionString)) {
this.version = ClassPackageImpl.decode(versionString);
}
return version == null && pom.version != null ? pom.getVersion() : version;
}
public void setVersion(IVersion version) { this.version = version; }
public ProjectObjectModel getModel() { return pom; }
@XmlParent public void setModel(ProjectObjectModel model) { this.pom = model; }
public String getClassifier() { return null; }
public int compareTo(IClassArtifactReference o) {
return ClassPackageUtil.compare(this, o);
}
@Override public String getNamespace() { return this.groupId; }
@Override public String getName() { return this.artifactId; }
@Override public String getUniqueIdentifier() { return this.toArtifactString(); }
public String toString () { return ClassPackageUtil.toString(this); }
public String toArtifactString() { return this.groupId + ":" + this.artifactId; }
}
/**
* Maven build info
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ProjectObjectModel.java 2745 2011-02-05 04:23:36Z ponderator $
*/
@XmlType(name="build")
public static class Build {
protected String directory;
protected String outputDirectory;
protected String testOutputDirectory;
public String getOutputDirectory() { return outputDirectory; }
public void setOutputDirectory(String outputDirectory) { this.outputDirectory = outputDirectory; }
public String getTestOutputDirectory() { return testOutputDirectory; }
public void setTestOutputDirectory(String testOutputDirectory) { this.testOutputDirectory = testOutputDirectory; }
public String getDirectory() { return directory; }
public void setDirectory(String directory) { this.directory = directory; }
}
/**
* Information about how this artifact is distributed.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ProjectObjectModel.java 2745 2011-02-05 04:23:36Z ponderator $
*/
@XmlType(name="distributionManagement")
public static class DistributionManagement {
protected Relocation relocation;
public Relocation getRelocation() { return relocation; }
public void setRelocation(Relocation relocation) { this.relocation = relocation; }
}
/**
* Relocation information about an artifact that has changed name.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ProjectObjectModel.java 2745 2011-02-05 04:23:36Z ponderator $
*/
@XmlType(name="relocation")
public static class Relocation implements IClassPackageRelocation {
protected String groupId;
protected String artifactId;
protected String version;
protected String message;
public String getGroupId() { return groupId; }
public void setGroupId(String groupId) { this.groupId = groupId; }
public String getArtifactId() { return artifactId; }
public void setArtifactId(String artifactId) { this.artifactId = artifactId; }
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}
/**
* A maven dependency
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ProjectObjectModel.java 2745 2011-02-05 04:23:36Z ponderator $
*/
@XmlType(name="dependency")
public static class Dependency implements IClassPackageDependencyReference {
protected String groupId;
protected String artifactId;
protected IVersion version;
protected String versionString;
protected String type;
protected String scope;
protected String classifier;
protected boolean optional;
protected String systemPath;
protected List<Exclusion> exclusions = new ArrayList<Exclusion>();
protected ProjectObjectModel model;
public String getGroupId() { return groupId == null ? null : model.parse(groupId); }
public void setGroupId(String groupId) { this.groupId = groupId; }
public String getArtifactId() { return artifactId == null ? null : model.parse(artifactId); }
public void setArtifactId(String artifactId) { this.artifactId = artifactId; }
@XmlTransient @Override public IVersion getVersion() {
return this.getVersion(false);
}
public IVersion getVersion(boolean fromManagement) {
if (version == null && versionString != null && !"".equals(versionString)) {
String newversion = model.parse(versionString);
if (newversion != null && !"".equals(newversion.trim()))
this.version = ClassPackageImpl.decode(newversion);
else
log.warning("Improper version parsing: " + newversion + "/" + version + " for: " + groupId + ":" + artifactId + " in " + model);
}
return version == null && !fromManagement ? version = model.resolveVersion(this) : version;
}
@XmlElement(name="version") public String getVersionString () {
return this.versionString;
}
public void setVersionString(String version) {
this.version = null;
this.versionString = version;
}
@XmlElement(name="scope") public String getDeclaredScope() { return scope; }
public void setDeclaredScope(String scope) { this.scope = scope; }
@XmlTransient public Scope getScope() {
if (isOptional()) return Scope.Optional;
if ("runtime".equals(scope)) return Scope.Runtime;
if ("provided".equals(scope)) return Scope.Provided;
if ("test".equals(scope)) return Scope.Test;
return Scope.Compile;
}
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public String getClassifier() { return classifier; }
public void setClassifier(String classifier) { this.classifier = classifier; }
public boolean isOptional() { return optional; }
public void setOptional(boolean optional) { this.optional = optional; }
public String getSystemPath() { return systemPath; }
public void setSystemPath(String systemPath) { this.systemPath = systemPath; }
public ISystemArtifact getSystemArtifact() { return this.isSystemReference() ? new SystemFile(systemPath) : null; }
public IClassPackageDescriptor getSystemDescriptor() { return this.isSystemReference() ? new ProjectObjectModel(model, this) : null; }
public boolean isSystemReference() {
return "system".equalsIgnoreCase( this.scope ) && this.systemPath != null && !"".equals(systemPath);
}
@XmlTransient public List<Exclusion> getExclusions() {
return getExclusions(true);
}
protected List<Exclusion> getExclusions(boolean resolve) {
if (resolve) {
Dependency managed = model.getDependencyManagement(this);
if (managed != null) {
List<Exclusion> all = new ArrayList<Exclusion>(exclusions);
all.addAll(managed.getExclusions(false));
return all;
}
}
return exclusions;
}
@XmlElementWrapper(name="exclusions") @XmlElement(name="exclusions")
public List<Exclusion> getDeclaredExclusions() {
return this.exclusions;
}
public void setDeclaredExclusions(List<Exclusion> exclusions) { this.exclusions = exclusions; }
public ProjectObjectModel getModel() { return model; }
@XmlParent public void setModel(ProjectObjectModel model) { this.model = model; }
public int compareTo(IClassArtifactReference o) { return ClassPackageUtil.compare(this, o); }
public boolean equals (Object object) {
return object instanceof IClassArtifactReference ? this.compareTo((IClassArtifactReference)object) == 0 : false;
}
@Override public String getNamespace() { return this.groupId; }
@Override public String getName() { return this.artifactId; }
@Override public String getUniqueIdentifier() { return this.toArtifactString(); }
public String toString () { return ClassPackageUtil.toString(this); }
public String toArtifactString() { return this.getGroupId() + ":" + this.getArtifactId(); }
public boolean shouldLoad (Scope scope) {
if (scope == Scope.All) return true;
if (this.isOptional() && scope != Scope.Optional) return false;
switch (scope) {
case Compile: return "compile".equals(this.scope) || "".equals(this.scope) || this.scope == null || "system".equals(this.scope);
case Runtime: return "compile".equals(this.scope) || "".equals(this.scope) || this.scope == null || "runtime".equals(this.scope) || "system".equals(this.scope);
case Optional: return isOptional();
case Test: return "test".equals(this.scope);
case Provided: return "provided".equals(this.scope);
}
return false;
}
@XmlType(name="exclusion")
public static class Exclusion implements IClassArtifactReference {
protected String groupId;
protected String artifactId;
public String getGroupId() { return groupId; }
public void setGroupId(String groupId) { this.groupId = groupId; }
public String getArtifactId() { return artifactId; }
public void setArtifactId(String artifactId) { this.artifactId = artifactId; }
@Override public String getNamespace() { return this.groupId; }
@Override public String getName() { return this.artifactId; }
@Override public String getUniqueIdentifier() { return this.toArtifactString(); }
public String toArtifactString() { return this.groupId + ":" + this.artifactId; }
public int compareTo(IClassArtifactReference o) {
return ClassPackageUtil.compare(this, o);
}
}
}
/**
* Management of dependencies so that versions can be resolved in children descriptors
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ProjectObjectModel.java 2745 2011-02-05 04:23:36Z ponderator $
*/
@XmlType(name="dependencyManagement")
public static class DependencyManagement {
protected List<Dependency> dependencies = new ArrayList<Dependency>();
protected ProjectObjectModel pom;
@XmlElementWrapper(name="dependencies")
public List<Dependency> getDependencies() { return dependencies; }
public void setDependencies(List<Dependency> dependencies) { this.dependencies = dependencies; }
@XmlParent public ProjectObjectModel getPom() { return pom; }
public void setPom(ProjectObjectModel pom) { this.pom = pom; }
public Dependency getManagement (IClassArtifactReference reference) {
for (Dependency dependency : dependencies) {
if (reference.compareTo(dependency) == 0) return dependency;
}
return null;
}
public boolean isExcluded (IClassArtifactReference reference) {
for (Dependency dependency : dependencies) {
for (Exclusion exclusion : dependency.getExclusions(false)) {
if (reference.compareTo(exclusion) != 0) {
return true;
}
}
}
return false;
}
public IVersion findVersion (Dependency reference) {
for (Dependency dependency : this.dependencies) {
if (reference.getGroupId() != null && reference.getGroupId().equals( dependency.getGroupId() ) &&
reference.getArtifactId() != null && reference.getArtifactId().equals( dependency.getArtifactId() )) {
return dependency.getVersion(true);
}
}
return null;
}
}
/**
* A maven repository
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ProjectObjectModel.java 2745 2011-02-05 04:23:36Z ponderator $
*/
@XmlType(name="repository")
public static class Repository {
protected String url;
protected String name;
protected String id;
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getId() { return id; }
public void setId(String id) { this.id = id; }
}
@XmlType(name="properties")
public static class Properties {
protected List<Property> elements = new ArrayList<Property>();
protected boolean translated = false;
protected Map<String, String> properties = new HashMap<String, String>();
@XmlAnyElement public List<Property> getElements() { return elements; }
public void setElements(List<Property> elements) {
this.elements = elements;
}
public String getProperty (String name) {
if (!translated) {
for (Property element : elements) {
properties.put(element.getName(), element.getValue());
}
translated = true;
}
return properties.get(name);
}
public boolean containsKey (String name) {
return getProperty(name) != null;
}
}
@XmlType(name="property")
public static class Property {
protected String name;
protected String value;
@XmlElementName public String getName() { return name; }
public void setName(String name) {
this.name = name;
}
@XmlValue public String getValue() { return value; }
public void setValue(String value) {
this.value = value;
}
}
}