Package org.dru.clay.respository.ivy

Source Code of org.dru.clay.respository.ivy.IvyXmlParser

package org.dru.clay.respository.ivy;

import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.dru.clay.logger.Logger;
import org.dru.clay.logger.LoggerFactory;
import org.dru.clay.respository.Configuration;
import org.dru.clay.respository.artifact.Artifact;
import org.dru.clay.respository.artifact.Group;
import org.dru.clay.respository.artifact.Module;
import org.dru.clay.respository.artifact.UnresolvedArtifact;
import org.dru.clay.respository.artifact.VersionPattern;
import org.dru.clay.respository.dependency.ConfigurationMapping;
import org.dru.clay.respository.dependency.Dependency;
import org.dru.clay.respository.exception.ResolveException;
import org.dru.clay.util.xml.Xml;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class IvyXmlParser {
  private final Logger logger = LoggerFactory.getLogger(IvyXmlParser.class);

  // private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

  private final Map<String, Configuration> configurations = new HashMap<String, Configuration>();
  private final Set<Dependency> dependencies = new HashSet<Dependency>();

  private final Map<String, String> configurationExtensionMap = new HashMap<String, String>();

  private final ConfigurationMappingParser configurationParser = new ConfigurationMappingParser();

  private IvyStatus status;
  private String dependencyDefaultConf;

  public IvyXmlParser() {
  }

  public IvyXml parse(Module module, byte[] content) {
    try {
      final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      factory.setValidating(false);

      int length = content.length;
      while (length > 0 && content[length - 1] != '>') {
        length--;
      }

      final DocumentBuilder builder = factory.newDocumentBuilder();
      final Document document = builder.parse(new ByteArrayInputStream(content, 0, length));
      final Element ivyModule = document.getDocumentElement();

      verifyModuleInformation(module, ivyModule);
      parseConfigurations(module, ivyModule);
      parseArtifacts(module, ivyModule);
      parseDependencies(module, ivyModule);
      resolveExtensions();

      return new IvyXml(module, status, configurations, dependencies);
    } catch (Exception e) {
      throw new ResolveException("Resolve error: " + e.getMessage(), e);
    }
  }

  private void verifyModuleInformation(Module module, Element ivyModule) {
    final Node info = Xml.getSingleChild(ivyModule, "info");

    final String organisation = Xml.getAttribute(info, "organisation");
    final String moduleName = Xml.getAttribute(info, "module");
    final String revision = Xml.getAttribute(info, "revision");

    this.status = Xml.getEnumAttribute(info, "status", IvyStatus.class, IvyStatus.Integration);
    // final String publication = Xml.getAttribute(info, "publication");

    if (!module.getGroup().get().equals(organisation)) {
      throw new IllegalArgumentException("Ivy description of artifact has different organisation than the resolve artifact: "
          + organisation);
    }

    final Artifact artifact = module.getArtifact();
    if (!artifact.getName().equals(moduleName)) {
      throw new IllegalArgumentException("Ivy description of artifact has different module than the resolve artifact: " + moduleName);
    }

    if (!artifact.getVersion().plain().equals(revision)) {
      throw new IllegalArgumentException("Ivy description of artifact has different revision than the resolve artifact: " + revision);
    }
  }

  private void parseConfigurations(Module module, Element ivyModule) {
    final Node configs = Xml.getSingleChild(ivyModule, "configurations");
    dependencyDefaultConf = Xml.getAttribute(configs, "defaultConf", "");

    for (Node node : Xml.getChildren(configs, "conf")) {
      final String name = Xml.getAttribute(node, "name");
      if (name == null) {
        throw new IllegalArgumentException("Configuration is missing the required attribute 'name'");
      }

      final String description = Xml.getAttribute(node, "description");
      final IvyVisibility visibility = Xml.getEnumAttribute(node, "visibility", IvyVisibility.class, IvyVisibility.Public);
      final String extending = Xml.getAttribute(node, "extends", null);

      // final boolean transitive = Xml.getBooleanAttribute(conf, "transitive", true);
      // final String deprecated = Xml.getAttribute(conf, "deprecated");

      final Configuration configuration = new Configuration(name, description, visibility);
      configurations.put(name, configuration);
      if (extending != null) {
        configurationExtensionMap.put(name, extending);
      }
    }
  }

  private void parseArtifacts(Module module, Element ivyModule) {
    final Node publications = Xml.getSingleChild(ivyModule, "publications");
    final String defaultConf = Xml.getAttribute(publications, "defaultConf", "*");

    for (Node node : Xml.getChildren(publications, "artifact")) {
      final String name = Xml.getAttribute(node, "name", module.getArtifact().getName());
      final String type = Xml.getAttribute(node, "type", "jar");
      final String ext = Xml.getAttribute(node, "ext", type);
      final String conf = Xml.getAttribute(node, "conf", defaultConf);
      // final String url = Xml.getAttribute(node, "url", type);

      final Artifact artifact = new Artifact(name, module.getArtifact().getVersion(), ext, null);

      final StringTokenizer tokenizer = new StringTokenizer(conf);
      while (tokenizer.hasMoreTokens()) {
        final String token = tokenizer.nextToken().trim();

        if ("*".equals(token)) {
          // insert the artifact in all configurations
          for (Configuration configuration : configurations.values()) {
            configuration.addArtifact(artifact);
          }
          break;
        } else {
          final Configuration configuration = configurations.get(token);
          if (configuration == null) {
            throw new IllegalArgumentException("The artifact " + artifact + " specified unknown configuration " + token);
          }
          configuration.addArtifact(artifact);
        }
      }
    }
  }

  private void parseDependencies(Module module, Element ivyModule) {
    final Node deps = Xml.getSingleChild(ivyModule, "dependencies");

    for (Node node : Xml.getChildren(deps, "dependency")) {
      final Dependency dependency = parseDependency(module, node);
      dependencies.add(dependency);
    }
  }

  private Dependency parseDependency(Module module, Node node) {
    final String group = Xml.getAttribute(node, "org", module.getGroup().get());
    final String name = Xml.getAttribute(node, "name");
    final String rev = Xml.getAttribute(node, "rev");
    // final String revConstraint = Xml.getAttribute(node, "revConstraint", rev);
    final Boolean transitive = Xml.getBooleanAttribute(node, "transitive", true);
    String conf = Xml.getAttribute(node, "conf", dependencyDefaultConf);

    if (name == null) {
      throw new IllegalArgumentException("Dependency is missing attribute name");
    }

    if (rev == null) {
      throw new IllegalArgumentException("Dependency " + name + " is missing attribute rev");
    }

    UnresolvedArtifact artifact = new UnresolvedArtifact(name, new VersionPattern(rev));

    if (!Xml.getChildren(node, "conf").isEmpty()) {
      logger.error("Dependency %s uses nested conf elements which isn't supported : using '*'", artifact);
      conf = "*";
    }
    final ConfigurationMapping mapping = configurationParser.parse(conf);
    return new Dependency(new Group(group), artifact, mapping, transitive);
  }

  private void resolveExtensions() {
    for (Map.Entry<String, String> entry : configurationExtensionMap.entrySet()) {
      final Configuration configuration = configurations.get(entry.getKey());
      if (configuration == null) {
        throw new IllegalArgumentException("Invalid configuration " + entry.getKey() + " used in configuration extension.");
      }

      final StringTokenizer tokenizer = new StringTokenizer(entry.getValue(), ",");
      while (tokenizer.hasMoreTokens()) {
        final String token = tokenizer.nextToken().trim();
        final Configuration source = configurations.get(token);
        if (source == null) {
          throw new IllegalArgumentException("Invalid configuration " + token + " used in configuration extension.");
        }

        for (Artifact artifact : source.getArtifacts()) {
          configuration.addArtifact(artifact);
        }
      }
    }
  }
}
TOP

Related Classes of org.dru.clay.respository.ivy.IvyXmlParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.