/* * Copyright 2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.api.publish.ivy.internal.publisher; import org.gradle.api.Action; import org.gradle.api.UncheckedIOException; import org.gradle.api.XmlProvider; import org.gradle.api.artifacts.DependencyArtifact; import org.gradle.api.artifacts.ExcludeRule; import org.gradle.api.publish.ivy.IvyArtifact; import org.gradle.api.publish.ivy.IvyConfiguration; import org.gradle.api.publish.ivy.internal.dependency.IvyDependencyInternal; import org.gradle.internal.xml.SimpleXmlWriter; import org.gradle.internal.xml.XmlTransformer; import org.gradle.util.CollectionUtils; import javax.xml.namespace.QName; import java.io.File; import java.io.IOException; import java.io.Writer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; public class IvyDescriptorFileGenerator { private static final String IVY_FILE_ENCODING = "UTF-8"; private static final String IVY_DATE_PATTERN = "yyyyMMddHHmmss"; private final SimpleDateFormat ivyDateFormat = new SimpleDateFormat(IVY_DATE_PATTERN); private final IvyPublicationIdentity projectIdentity; private String branch; private String status; private Map<QName, String> extraInfo; private XmlTransformer xmlTransformer = new XmlTransformer(); private List<IvyConfiguration> configurations = new ArrayList<IvyConfiguration>(); private List<IvyArtifact> artifacts = new ArrayList<IvyArtifact>(); private List<IvyDependencyInternal> dependencies = new ArrayList<IvyDependencyInternal>(); public IvyDescriptorFileGenerator(IvyPublicationIdentity projectIdentity) { this.projectIdentity = projectIdentity; } public void setStatus(String status) { this.status = status; } public void setBranch(String branch) { this.branch = branch; } public Map<QName, String> getExtraInfo() { return extraInfo; } public void setExtraInfo(Map<QName, String> extraInfo) { this.extraInfo = extraInfo; } public IvyDescriptorFileGenerator addConfiguration(IvyConfiguration ivyConfiguration) { configurations.add(ivyConfiguration); return this; } public IvyDescriptorFileGenerator addArtifact(IvyArtifact ivyArtifact) { artifacts.add(ivyArtifact); return this; } public IvyDescriptorFileGenerator addDependency(IvyDependencyInternal ivyDependency) { dependencies.add(ivyDependency); return this; } public IvyDescriptorFileGenerator withXml(final Action<XmlProvider> action) { xmlTransformer.addAction(action); return this; } public IvyDescriptorFileGenerator writeTo(File file) { xmlTransformer.transform(file, IVY_FILE_ENCODING, new Action<Writer>() { public void execute(Writer writer) { try { writeDescriptor(writer); } catch (IOException e) { throw new UncheckedIOException(e); } } }); return this; } private void writeDescriptor(final Writer writer) throws IOException { OptionalAttributeXmlWriter xmlWriter = new OptionalAttributeXmlWriter(writer, " ", IVY_FILE_ENCODING); xmlWriter.startElement("ivy-module").attribute("version", "2.0"); if (usesClassifier()) { xmlWriter.attribute("xmlns:m", "http://ant.apache.org/ivy/maven"); } xmlWriter.startElement("info") .attribute("organisation", projectIdentity.getOrganisation()) .attribute("module", projectIdentity.getModule()) .attribute("branch", branch) .attribute("revision", projectIdentity.getRevision()) .attribute("status", status) .attribute("publication", ivyDateFormat.format(new Date())); if (extraInfo != null) { for (Map.Entry<QName, String> entry : extraInfo.entrySet()) { if (entry.getKey() != null) { xmlWriter.startElement("ns:" + entry.getKey().getLocalPart()) .attribute("xmlns:ns", entry.getKey().getNamespaceURI()) .characters(entry.getValue()) .endElement(); } } } xmlWriter.endElement(); writeConfigurations(xmlWriter); writePublications(xmlWriter); writeDependencies(xmlWriter); xmlWriter.endElement(); } private boolean usesClassifier() { for (IvyArtifact artifact : artifacts) { if (artifact.getClassifier() != null) { return true; } } for (IvyDependencyInternal dependency : this.dependencies) { for (DependencyArtifact dependencyArtifact : dependency.getArtifacts()) { if (dependencyArtifact.getClassifier() != null) { return true; } } } return false; } private void writeConfigurations(OptionalAttributeXmlWriter xmlWriter) throws IOException { xmlWriter.startElement("configurations"); for (IvyConfiguration configuration : configurations) { xmlWriter.startElement("conf") .attribute("name", configuration.getName()) .attribute("visibility", "public"); if (configuration.getExtends().size() > 0) { xmlWriter.attribute("extends", CollectionUtils.join(",", configuration.getExtends())); } xmlWriter.endElement(); } xmlWriter.endElement(); } private void writePublications(OptionalAttributeXmlWriter xmlWriter) throws IOException { xmlWriter.startElement("publications"); for (IvyArtifact artifact : artifacts) { xmlWriter.startElement("artifact") .attribute("name", artifact.getName()) .attribute("type", artifact.getType()) .attribute("ext", artifact.getExtension()) .attribute("conf", artifact.getConf()) .attribute("m:classifier", artifact.getClassifier()) .endElement(); } xmlWriter.endElement(); } private void writeDependencies(OptionalAttributeXmlWriter xmlWriter) throws IOException { xmlWriter.startElement("dependencies"); for (IvyDependencyInternal dependency : dependencies) { xmlWriter.startElement("dependency") .attribute("org", dependency.getOrganisation()) .attribute("name", dependency.getModule()) .attribute("rev", dependency.getRevision()) .attribute("conf", dependency.getConfMapping()); if (!dependency.isTransitive()) { xmlWriter.attribute("transitive", "false"); } for (DependencyArtifact dependencyArtifact : dependency.getArtifacts()) { printDependencyArtifact(dependencyArtifact, xmlWriter); } for(ExcludeRule excludeRule : dependency.getExcludeRules()) { writeDependencyExclude(excludeRule, xmlWriter); } xmlWriter.endElement(); } xmlWriter.endElement(); } private void writeDependencyExclude(ExcludeRule excludeRule, OptionalAttributeXmlWriter xmlWriter) throws IOException { xmlWriter.startElement("exclude") .attribute("org", excludeRule.getGroup()) .attribute("module", excludeRule.getModule()) .endElement(); } private void printDependencyArtifact(DependencyArtifact dependencyArtifact, OptionalAttributeXmlWriter xmlWriter) throws IOException { // TODO Use IvyArtifact here xmlWriter.startElement("artifact") .attribute("name", dependencyArtifact.getName()) .attribute("type", dependencyArtifact.getType()) .attribute("ext", dependencyArtifact.getExtension()) .attribute("m:classifier", dependencyArtifact.getClassifier()) .endElement(); } private static class OptionalAttributeXmlWriter extends SimpleXmlWriter { public OptionalAttributeXmlWriter(Writer writer, String indent, String encoding) throws IOException { super(writer, indent, encoding); } @Override public OptionalAttributeXmlWriter startElement(String name) throws IOException { super.startElement(name); return this; } @Override public OptionalAttributeXmlWriter attribute(String name, String value) throws IOException { if (value != null) { super.attribute(name, value); } return this; } } }