Package org.osgi.impl.bundle.obr.resource

Source Code of org.osgi.impl.bundle.obr.resource.RepositoryImpl

/*
* $Id: RepositoryImpl.java 44 2007-07-13 20:49:41Z hargrave@us.ibm.com $
*
* Copyright (c) OSGi Alliance (2002, 2006, 2007). All Rights Reserved.
*
* 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.osgi.impl.bundle.obr.resource;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.zip.*;

import org.kxml2.io.KXmlParser;
import org.osgi.service.obr.*;
import org.xmlpull.v1.*;

import aQute.bnd.annotation.ProviderType;

/**
* Implements the basic repository. A repository holds a set of resources.
*
*
* @version $Revision: 44 $
*/
@SuppressWarnings({"unchecked"})
@ProviderType
public class RepositoryImpl implements Repository {
  transient Set      resources    = new HashSet();
  URL            url;
  String          date;
  Set            visited      = new HashSet();
  final static Resource[]  EMPTY_RESOURCE  = new Resource[0];
  String          name      = "Untitled";
  long          lastModified;
  Exception        exception;
  int            ranking=0;

  /**
   * Each repository is identified by a single URL.
   *
   * A repository can hold referrals to other repositories. These referred
   * repositories are included at the point of referall.
   *
   * @param url
   */
  public RepositoryImpl(URL url) {
    this.url = url;
  }

  /**
   * Refresh the repository from the URL.
   *
   * @throws Exception
   */
  public boolean refresh() {
    exception = null;
    try {
      resources.clear();
      parseDocument(url);
      visited = null;
      return true;
    }
    catch (Exception e) {
      e.printStackTrace();
      exception = e;
    }
    return false;
  }

  /**
   * Parse the repository.
   *
   * @param parser
   * @throws Exception
   */
  private void parseRepository(XmlPullParser parser) throws Exception {
    try {
      parser.require(XmlPullParser.START_DOCUMENT, null, null);
      parser.nextTag();
      if (parser.getName().equals("bundles"))
        parseOscar(parser);
      else {
        parser.require(XmlPullParser.START_TAG, null, "repository");
        date = parser.getAttributeValue(null, "lastmodified");
        name = parser.getAttributeValue(null, "name");
        if (name == null)
          name = "Untitled";

        while (parser.nextTag() == XmlPullParser.START_TAG) {
          if (parser.getName().equals("resource")) {
            ResourceImpl resource = new ResourceImpl(this, parser);
            resources.add(resource);
          }
          else if (parser.getName().equals("referral"))
            referral(parser);
          else
            throw new IllegalArgumentException(
                "Invalid tag in repository: " + url + " "
                    + parser.getName());
        }
        parser.require(XmlPullParser.END_TAG, null, "repository");
      }
    }
    catch (XmlPullParserException e) {
      e.printStackTrace();
      throw new IllegalArgumentException("XML unregognized around: "
          + e.getLineNumber() + " " + e.getMessage());
    }
  }

  /**
   * Parse an old style OBR repository.
   *
   * <dtd-version>1.0</dtd-version> <repository> <name>Oscar Bundle
   * Repository</name> <url>http://oscar-osgi.sourceforge.net/</url>
   * <date>Fri May 07 16:45:07 CEST 2004</date> <extern-repositories> <!--
   * Stefano Lenzi (kismet@interfree.it) -->
   * <url>http://domoware.isti.cnr.it/osgi-obr/niche-osgi-obr.xml</url>
   * <!--Manuel Palencia (santillan@dit.upm.es) --> <!--
   * <url>http://jmood.forge.os4os.org/repository.xml</url> --> <!-- Enrique
   * Rodriguez (erodriguez@apache.org) -->
   * <url>http://update.cainenable.org/repository.xml</url>
   * </extern-repositories> </repository> <bundle> <bundle-name>Bundle
   * Repository</bundle-name> <bundle-description> A bundle repository
   * service for Oscar. </bundle-description> <bundle-updatelocation>
   * http://oscar-osgi.sf.net/repo/bundlerepository/bundlerepository.jar
   * </bundle-updatelocation> <bundle-sourceurl>
   * http://oscar-osgi.sf.net/repo/bundlerepository/bundlerepository-src.jar
   * </bundle-sourceurl> <bundle-version>1.1.3</bundle-version>
   * <bundle-docurl> http://oscar-osgi.sf.net/repo/bundlerepository/
   * </bundle-docurl> <bundle-category>General</bundle-category>
   * <import-package package="org.osgi.framework"/> <export-package
   * package="org.ungoverned.osgi.service.bundlerepository"
   * specification-version="1.1.0"/> </bundle> *
   */
  private void parseOscar(XmlPullParser parser) throws Exception {
    parser.require(XmlPullParser.START_TAG, null, "bundles");
    while (true) {
      int event = parser.next();

      // Error ..
      if (event == XmlPullParser.TEXT)
        event = parser.next();

      if (event != XmlPullParser.START_TAG)
        break;

      ResourceImpl resource = new ResourceImpl(this);

      if (parser.getName().equals("bundle")) {
        while (parser.nextTag() == XmlPullParser.START_TAG) {
          String key = parser.getName();
          if (key.equals("import-package")) {
            RequirementImpl requirement = new RequirementImpl(
                "package");
           
            requirement.setOptional(false);
            requirement.setMultiple(false);
           
            String p = parser.getAttributeValue(null, "package");
            StringBuffer sb = new StringBuffer();
            sb.append("(&(package=");
            sb.append(p);
            sb.append(")");
            String version = parser.getAttributeValue(null,
                "specification-version");
            VersionRange v = new VersionRange("0");
            if (version != null) {
              sb.append("(version=");
              sb.append(v= new VersionRange(version));
              sb.append(")");
            }
            sb.append(")");
            requirement.setFilter(sb.toString());
            requirement.setComment("Import-Package: " + p + ";" + v );
            resource.addRequirement(requirement);
           
            parser.nextTag();
          }
          else if (key.equals("export-package")) {
            CapabilityImpl capability = new CapabilityImpl(
                "package");
            capability.addProperty("package", parser
                .getAttributeValue(null, "package"));
            String version = parser.getAttributeValue(null,
                "specification-version");
            if (version != null) {
              capability.addProperty("version", new VersionRange(
                  version));
            }
            resource.addCapability(capability);
            parser.nextTag();
          }
          else {
            String value = parser.nextText().trim();
            if (key.equals("bundle-sourceurl"))
              resource.setSource(new URL(value));
            else if (key.equals("bundle-docurl"))
              resource.setDocumentation(new URL(value));
            else if (key.equals("bundle-updatelocation"))
              resource.setURL(new URL(value));
            else if (key.equals("bundle-description"))
              resource.setDescription(value);
            else if (key.equals("bundle-category"))
              resource.addCategory(value);
            else if (key.equals("bundle-name")) {
              resource.setName(value);
              resource.setPresentationName(value);
            }
            else if (key.equals("bundle-version"))
              resource.setVersion(new VersionRange(value));
            else {
              resource.put(key, value);
            }
          }
        }
        resources.add(resource);
        parser.require(XmlPullParser.END_TAG, null, "bundle");
      }
      else if (parser.getName().equals("repository")) {
        parser.require(XmlPullParser.START_TAG, null, "repository");
        while (parser.nextTag() == XmlPullParser.START_TAG) {
          String tag = parser.getName();
          if (tag.equals("name")) {
            String name = parser.nextText();
            if (this.name == null)
              this.name = name.trim();
          }
          else if (tag.equals("url"))
            parser.nextText().trim();
          else if (tag.equals("date"))
            parser.nextText().trim();
          else if (tag.equals("extern-repositories")) {
            parser.require(XmlPullParser.START_TAG, null,
                "extern-repositories");
            while (parser.nextTag() == XmlPullParser.START_TAG) {
              if (parser.getName().equals("url"))
                parseDocument(new URL(parser.nextText().trim()));
              else
                throw new IllegalArgumentException(
                    "Invalid tag in repository while parsing extern repositories: "
                        + url + " " + parser.getName());
            }
            parser.require(XmlPullParser.END_TAG, null,
                "extern-repositories");
          }
          else
            throw new IllegalArgumentException(
                "Invalid tag in repository: " + url + " "
                    + parser.getName());
        }
        parser.require(XmlPullParser.END_TAG, null, "repository");
      }
      else if (parser.getName().equals("dtd-version")) {
        parser.nextText();
      }
      else
        throw new IllegalArgumentException(
            "Invalid tag in repository: " + url + " "
                + parser.getName());
    }
    parser.require(XmlPullParser.END_TAG, null, "bundles");
  }

  /**
   * We have a referral to another repository. Just create another parser and
   * read it inline.
   *
   * @param parser
   */
  void referral(XmlPullParser parser) {
    // TODO handle depth!
    try {
      parser.require(XmlPullParser.START_TAG, null, "referral");
      // String depth = parser.getAttributeValue(null, "depth");
      String path = parser.getAttributeValue(null, "url");
      URL url = new URL(this.url, path);
      parseDocument(url);
      parser.next();
      parser.require(XmlPullParser.END_TAG, null, "referral");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Parse a repository document.
   *
   * @param url
   * @throws IOException
   * @throws XmlPullParserException
   * @throws Exception
   */
  void parseDocument(URL url) throws IOException, XmlPullParserException,
      Exception {
    if (!visited.contains(url)) {
      visited.add(url);
      try {
        System.out.println("Visiting: " + url);
        InputStream in = null;
       
        if ( url.getPath().endsWith(".zip")) {
          ZipInputStream zin = new ZipInputStream( url.openStream() );
          ZipEntry entry = zin.getNextEntry();
          while ( entry != null ) {
            if ( entry.getName().equals("repository.xml")) {
              in = zin;
              break;
            }
            entry = zin.getNextEntry();
          }
          zin.close();
        } else {
          in = url.openStream();
        }
        Reader reader = new InputStreamReader(in);
        XmlPullParser parser = new KXmlParser();
        parser.setInput(reader);
        parseRepository(parser);
      } catch( MalformedURLException e ) {
        System.out.println("Cannot create connection to url");
      }
    }
  }

  public URL getURL() {
    return url;
  }

  /**
   * @return
   */
  public Collection getResourceList() {
    return resources;
  }

  public Resource[] getResources() {
    return (Resource[]) getResourceList().toArray(EMPTY_RESOURCE);
  }

  public String getName() {
    return name;
  }

  public Resource getResource(String id) {
    for (Iterator i = getResourceList().iterator(); i.hasNext();) {
      ResourceImpl resource = (ResourceImpl) i.next();
      if (resource.getId().equals(id))
        return resource;
    }
    return null;
  }

  public long getLastModified() {
    return lastModified;
  }

  public int getRanking() {
    return ranking;
  }

  public void setRanking(int ranking) {
    this.ranking = ranking;
  }

}
TOP

Related Classes of org.osgi.impl.bundle.obr.resource.RepositoryImpl

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.