Package aQute.library.capreq

Source Code of aQute.library.capreq.Engine

package aQute.library.capreq;

import static javax.xml.stream.XMLStreamConstants.*;

import java.io.*;
import java.util.*;

import javax.xml.stream.*;

import org.osgi.resource.*;

import aQute.library.capreq.FilterParser.Expression;

public class Engine {
  FilterParser        parser    = new FilterParser();
  private Set<ResourceImpl>  resources  = new HashSet<ResourceImpl>();
  ResourceImpl        local    = new ResourceImpl(this);

  /**
   * Parse an OBR xml file into Resources.
   *
   * @param obrFile
   * @return
   * @throws Exception
   */
  public void parse(File obrFile) throws Exception {
    Set<ResourceImpl> set = new HashSet<ResourceImpl>();

    XMLInputFactory inputFactory = XMLInputFactory.newInstance();

    inputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
    inputFactory.setProperty(XMLInputFactory.IS_VALIDATING, false);
    inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);

    FileReader reader = new FileReader(obrFile);
    try {

      XMLStreamReader xml = inputFactory.createXMLStreamReader(reader);
      while (xml.hasNext()) {
        int type = xml.next();
        String localName;

        switch (type) {
          case START_ELEMENT :
            localName = xml.getLocalName();
            if ("resource".equals(localName)) {
              set.add(doResource(xml));
            }
            break;
          case END_ELEMENT :
            localName = xml.getLocalName();
            if (!localName.equals("repository"))
              throw new UnsupportedOperationException("Did not expect an END_ELEMENT for "
                  + xml.getLocalName());
        }
      }
    }
    finally {
      reader.close();
    }
    this.resources = set;
  }

  private ResourceImpl doResource(XMLStreamReader xml) throws Exception {
    ResourceImpl resource = new ResourceImpl(this);
    while (xml.hasNext()) {
      int type = xml.next();

      switch (type) {
        case START_ELEMENT : {
          String localName = xml.getLocalName();
          if ("capability".equals(localName)) {
            doNamespace(xml, new CapabilityImpl(resource, xml.getAttributeValue(null, "namespace")));
          } else if ("requirement".equals(localName)) {
            doNamespace(xml, new RequirementImpl(resource, xml.getAttributeValue(null, "namespace")));
          } else
            throw new UnsupportedOperationException("Unknwon START_ELEMENT for " + xml.getLocalName());
          break;
        }
        case END_ELEMENT : {
          String localName = xml.getLocalName();
          if ("resource".equals(localName))
            return resource;

          throw new UnsupportedOperationException("Unknwon END_ELEMENT for " + xml.getLocalName());
        }
      }
    }
    throw new IllegalArgumentException("Invalid XML, expected END_ELEMENT for resource, got eof");
  }

  private <T extends NamespaceImpl> void doNamespace(XMLStreamReader xml, T ns) throws Exception {
    while (xml.hasNext()) {
      int type = xml.next();

      switch (type) {
        case START_ELEMENT : {
          String localName = xml.getLocalName();
          if ("attribute".equals(localName)) {
            if (ns.attributes == null)
              ns.attributes = new HashMap<String,Object>();
            doAttribute(xml, ns.attributes, null);
          } else if ("directive".equals(localName)) {
            if (ns.directives == null)
              ns.directives = new HashMap<String,String>();
            doAttribute(xml, null, ns.directives);
          } else
            throw new UnsupportedOperationException("Unknwon START_ELEMENT for " + xml.getLocalName());
          break;
        }
        case END_ELEMENT : {
          String localName = xml.getLocalName();
          if ("capability".equals(localName) || "requirement".equals(localName)) {
            return;
          } else
            throw new UnsupportedOperationException("Unknwon END_ELEMENT for " + xml.getLocalName());
        }
      }
    }
  }

  private void doAttribute(XMLStreamReader xml, Map<String,Object> attrs, Map<String,String> directives)
      throws XMLStreamException {
    String name = xml.getAttributeValue(null, "name");
    String value = xml.getAttributeValue(null, "value");
    if (directives != null) {
      directives.put(name, value);
      ensure(xml, "directive");
      return;
    }

    String type = xml.getAttributeValue(null, "type");
    attrs.put(name, convert(type, value));
    ensure(xml, "attribute");
  }

  private void ensure(XMLStreamReader xml, String string) throws XMLStreamException {
    int type = xml.next();
    if (type != END_ELEMENT && !xml.getLocalName().equals(string))
      throw new IllegalArgumentException("Expected end element for " + string);
  }

  private Object convert(String type, String value) {
    if (type == null || type.equals("String"))
      return value;

    if (type.startsWith("List<") && type.endsWith(">")) {
      type = type.substring(5, type.length() - 1);
      String members[] = value.split("\\s*,\\s*");
      List<Object> result = new ArrayList<Object>();
      for (String member : members) {
        result.add(convert(type, member));
      }
      return result;
    } else if ("Long".equals(type)) {
      return Long.parseLong(value);
    } else if ("Version".equals(type)) {
      return org.osgi.framework.Version.parseVersion(value);
    } else if ("Double".equals(type)) {
      return Double.parseDouble(value);
    } else
      throw new IllegalArgumentException("Invalid type: " + type);
  }

  public Collection<ResourceImpl> getResources() {
    return resources;
  }

  public Expression filter(String filter) {
    try {
      return parser.parse(filter);
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  public boolean match(org.osgi.resource.Requirement req, Map<String,Object> attributes) throws IOException {
    if (req instanceof RequirementImpl)
      return ((RequirementImpl) req).match(attributes);

    String f = req.getDirectives().get("filter");
    if (f == null)
      return false;

    Expression parse = parser.parse(f);

    return parse.eval(attributes);
  }

  public RequirementImpl createRequirement(String namespace, String filter) {
    RequirementImpl req = new RequirementImpl(local, namespace);
    req.setFilter(filter);
    return req;
  }

  public List<Capability> findProviders(Requirement rq) throws IOException {
    List<Capability> providers = new ArrayList<Capability>();
    Expression exp = null;
    if (!(rq instanceof RequirementImpl)) {
      exp = parser.parse(rq.getDirectives().get("filter"));
    } else
      exp = ((RequirementImpl) rq).getFilter();
    for (ResourceImpl rs : getResources()) {
      for (Capability cap : rs.getCapabilities(rq.getNamespace())) {
        if (exp.eval(cap.getAttributes()))
          providers.add(cap);
      }
    }
    return providers;
  }

  public static boolean isMandatory(org.osgi.resource.Requirement req) {
    String resolution = req.getDirectives().get("resolution");
    if (resolution == null || "mandatory".equalsIgnoreCase(resolution))
      return true;

    return false;
  }
}
TOP

Related Classes of aQute.library.capreq.Engine

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.