You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2009/06/27 17:53:26 UTC
svn commit: r788992 [19/25] - in /incubator/ace/trunk: gateway/ gateway/src/
gateway/src/net/ gateway/src/net/luminis/ gateway/src/net/luminis/liq/
gateway/src/net/luminis/liq/bootstrap/
gateway/src/net/luminis/liq/bootstrap/multigateway/ gateway/src/n...
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/RepositoryImpl.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/RepositoryImpl.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/RepositoryImpl.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,375 @@
+/*
+ * $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.*;
+
+/**
+ * Implements the basic repository. A repository holds a set of resources.
+ *
+ *
+ * @version $Revision: 44 $
+ */
+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();
+ }
+ } 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;
+ }
+
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/RequirementImpl.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/RequirementImpl.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/RequirementImpl.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/RequirementImpl.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,180 @@
+/*
+ * $Id: RequirementImpl.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 org.osgi.service.obr.*;
+import org.xmlpull.v1.XmlPullParser;
+
+
+
+/**
+ * Implements the Requirement interface.
+ *
+ *
+ * @version $Revision: 44 $
+ */
+public class RequirementImpl implements Requirement {
+ int id;
+ String name;
+ String filter="()";
+ FilterImpl _filter;
+ String comment;
+ boolean optional;
+ boolean multiple;
+ boolean extend;
+
+ /**
+ * Create a requirement with the given name.
+ *
+ * @param name
+ */
+ public RequirementImpl(String name) {
+ this.name = name;
+ }
+
+
+ /**
+ * Parse the requirement from the pull parser.
+ *
+ * @param parser
+ * @throws Exception
+ */
+ public RequirementImpl(XmlPullParser parser) throws Exception {
+ parser.require(XmlPullParser.START_TAG, null, null );
+ name = parser.getAttributeValue(null, "name");
+ filter = parser.getAttributeValue(null, "filter");
+
+ String opt = parser.getAttributeValue(null,"optional");
+ String mul = parser.getAttributeValue(null,"multiple");
+ String ext = parser.getAttributeValue(null,"extend");
+ optional = "true".equalsIgnoreCase(opt);
+ multiple = "true".equalsIgnoreCase(mul);
+ extend = "true".equalsIgnoreCase(ext);
+
+
+ StringBuffer sb = new StringBuffer();
+ while ( parser.next() == XmlPullParser.TEXT ) {
+ sb.append( parser.getText() );
+ }
+ if ( sb.length() > 0 )
+ setComment(sb.toString().trim());
+
+ parser.require(XmlPullParser.END_TAG, null, null );
+ }
+
+ public void setFilter(String filter) {
+ this.filter = filter;
+ _filter= null;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public Tag toXML(String name) {
+ Tag tag = toXML(this);
+ tag.rename(name);
+ return tag;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isSatisfied(Capability capability) {
+ if (_filter == null)
+ _filter = new FilterImpl(filter);
+
+ boolean result = _filter.match(capability.getProperties());
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return name + " " + filter;
+ }
+
+
+ public String getComment() {
+ return comment;
+ }
+
+
+ public void setComment(String comment) {
+ this.comment=comment;
+ }
+
+
+ public static Tag toXML(Requirement requirement) {
+ Tag req = new Tag("require");
+ req.addAttribute("name", requirement.getName());
+ req.addAttribute("filter", requirement.getFilter());
+
+ req.addAttribute("optional", requirement.isOptional()+"");
+ req.addAttribute("multiple", requirement.isMultiple()+"");
+ req.addAttribute("extend", requirement.isExtend()+"");
+
+ if ( requirement.getComment() != null )
+ req.addContent(requirement.getComment());
+
+ return req;
+ }
+
+
+ public boolean isMultiple() {
+ return multiple;
+ }
+
+
+ public boolean isOptional() {
+ return optional;
+ }
+
+
+ public void setOptional(boolean b) {
+ optional = b;
+ }
+
+ public void setMultiple(boolean b) {
+ multiple = b;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if ( ! (o instanceof Requirement) )
+ return false;
+
+ Requirement r2 = (Requirement)o;
+ return filter.equals(r2.getFilter()) && name.equals(r2.getName());
+ }
+
+ @Override
+ public int hashCode() {
+ return filter.hashCode() ^ name.hashCode();
+ }
+
+ public boolean isExtend() {
+ return extend;
+ }
+
+ public void setExtend(boolean extend) {
+ this.extend = extend;
+ }
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/ResourceImpl.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/ResourceImpl.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/ResourceImpl.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/ResourceImpl.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,384 @@
+/*
+ * $Id: ResourceImpl.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.File;
+import java.net.URL;
+import java.util.*;
+
+import org.osgi.framework.Version;
+import org.osgi.service.obr.*;
+import org.xmlpull.v1.XmlPullParser;
+
+public class ResourceImpl implements Resource {
+ List capabilities = new ArrayList();
+ List requirements = new ArrayList();
+ URL url;
+ String symbolicName;
+ VersionRange version;
+ List categories = new ArrayList();
+ long size = -1;
+ String id;
+ static int ID = 1;
+ Map map = new HashMap();
+ RepositoryImpl repository;
+ String presentationName;
+ File file;
+
+
+ public ResourceImpl(RepositoryImpl repository, String name,
+ VersionRange version) {
+ this.version = version;
+ if ( version == null)
+ this.version = new VersionRange("0");
+ this.symbolicName = name;
+ this.repository = repository;
+ }
+
+ public ResourceImpl(RepositoryImpl repository, XmlPullParser parser)
+ throws Exception {
+ this.repository = repository;
+ parser.require(XmlPullParser.START_TAG, null, "resource");
+ symbolicName = parser.getAttributeValue(null, "symbolicname");
+ if (symbolicName == null)
+ System.err.println("Hey, no symb name! "
+ + parser.getAttributeValue(null, "uri"));
+
+ map.put(SYMBOLIC_NAME, symbolicName);
+ presentationName = parser.getAttributeValue(null, PRESENTATION_NAME);
+ if (presentationName != null)
+ map.put(PRESENTATION_NAME, presentationName);
+ String v = parser.getAttributeValue(null, "version");
+ if (v == null)
+ setVersion(new VersionRange("0"));
+ else
+ setVersion(new VersionRange(v));
+
+ setURL(toURL(parser.getAttributeValue(null, "uri")));
+
+ while (parser.nextTag() == XmlPullParser.START_TAG) {
+ if (parser.getName().equals("category")) {
+ categories.add(parser.getAttributeValue(null, "id").trim());
+ }
+ else if (parser.getName().equals("require"))
+ addRequirement(new RequirementImpl(parser));
+ else if (parser.getName().equals("capability"))
+ addCapability(new CapabilityImpl(parser));
+ else {
+ String text = parser.nextText();
+ if (text != null)
+ map.put(parser.getName(), text.trim());
+ }
+ parser.next();
+ }
+ parser.require(XmlPullParser.END_TAG, null, "resource");
+ }
+
+ public ResourceImpl(RepositoryImpl impl) {
+ this.repository = impl;
+ }
+
+ public ResourceImpl(RepositoryImpl impl, URL url) {
+ this.repository = impl;
+ setURL(url);
+ }
+
+ private URL toURL(String attributeValue) throws Exception {
+ if (attributeValue == null)
+ return null;
+
+ return new URL(repository.getURL(), attributeValue);
+ }
+
+ public void addCategory(String category) {
+ categories.add(category);
+ }
+
+ public void addCapability(CapabilityImpl capability) {
+ if (capability != null)
+ capabilities.add(capability);
+ }
+
+ public void addRequirement(RequirementImpl requirement) {
+ if (requirement != null)
+ requirements.add(requirement);
+ }
+
+ public void setLicense(URL license) {
+ if (license != null)
+ map.put(LICENSE_URL, license);
+ }
+
+ public String getDescription() {
+ return (String) map.get(DESCRIPTION);
+ }
+
+ public void setDescription(String description) {
+ if (description != null)
+ map.put(DESCRIPTION, description);
+ }
+
+ public Capability[] getCapabilities() {
+ return (Capability[]) capabilities.toArray(new Capability[capabilities
+ .size()]);
+ }
+
+ public URL getLicense() {
+ return (URL) map.get(LICENSE_URL);
+ }
+
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+
+ public Requirement[] getRequirements() {
+ return (Requirement[]) requirements
+ .toArray(new Requirement[requirements.size()]);
+ }
+
+ public Tag toXML() {
+ return toXML(this );
+ }
+
+ public static Tag toXML(Resource resource) {
+ return toXML(resource,true);
+ }
+
+ public static Tag toXML(Resource resource, boolean relative ) {
+ Tag meta = new Tag("resource");
+ URL url = resource.getURL();
+ String urlString = url.toExternalForm();
+
+ if ( relative )
+ urlString = makeRelative(resource.getRepository().getURL(), url);
+
+ meta.addAttribute("uri", urlString );
+ if (urlString.endsWith(".jar")) {
+ meta.addAttribute(SYMBOLIC_NAME, resource.getSymbolicName());
+ if (resource.getPresentationName() != null)
+ meta
+ .addAttribute(PRESENTATION_NAME, resource
+ .getPresentationName());
+ meta.addAttribute(VERSION, resource.getVersion().toString());
+ meta.addAttribute("id", resource.getId());
+ Map map = new TreeMap(resource.getProperties());
+ for (int i = 0; i < Resource.KEYS.length; i++) {
+ String key = KEYS[i];
+ if (!(key.equals(URL) || key.equals(SYMBOLIC_NAME) || key
+ .equals(VERSION) || key.equals(PRESENTATION_NAME))) {
+ Object value = map.get(KEYS[i]);
+ if (value != null) {
+ if (value instanceof URL)
+ value = makeRelative(resource.getRepository().getURL(),(URL) value);
+ meta.addContent(new Tag(key, value.toString()));
+ }
+ }
+ }
+
+ String[] categories = resource.getCategories();
+ for (int i = 0; i < categories.length; i++) {
+ String category = categories[i];
+ meta.addContent(new Tag("category", new String[] {"id",
+ category.toLowerCase()}));
+ }
+
+ Capability[] capabilities = resource.getCapabilities();
+ for (int i = 0; i < capabilities.length; i++) {
+ meta.addContent(CapabilityImpl.toXML(capabilities[i]));
+ }
+
+ Requirement[] requirements = resource.getRequirements();
+ for (int i = 0; i < requirements.length; i++) {
+ meta.addContent(RequirementImpl.toXML(requirements[i]));
+ }
+ }
+ return meta;
+ }
+
+ public URL getURL() {
+ return url;
+ }
+
+ static String makeRelative(URL repository, URL url) {
+ try {
+ if (repository != null) {
+ String a = url.toExternalForm();
+ String b = repository.toExternalForm();
+ int index = b.lastIndexOf('/');
+ if ( index > 0 )
+ b = b.substring(0,index+1);
+ if (a.startsWith(b))
+ return a.substring(b.length());
+ }
+ }
+ catch (Exception e) {
+ // Ignore
+ }
+ return url.toExternalForm();
+ }
+
+ public void setURL(URL url) {
+ this.url = url;
+ if (url != null)
+ map.put(URL, url);
+ }
+
+ public String getCopyright() {
+ return (String) map.get(COPYRIGHT);
+ }
+
+ public Version getVersion() {
+ if (version == null)
+ version = new VersionRange("0");
+ return version.low;
+ }
+
+ void setVersion(VersionRange version) {
+ if (version == null)
+ this.version = new VersionRange("0");
+ else
+ this.version = version;
+ }
+
+ public void setCopyright(String copyright) {
+ if (copyright != null)
+ map.put(COPYRIGHT, copyright);
+ }
+
+ public URL getDocumentation() {
+ return (URL) map.get(DOCUMENTATION_URL);
+ }
+
+ public void setDocumentation(URL documentation) {
+ if (documentation != null)
+ map.put(DOCUMENTATION_URL, documentation);
+ }
+
+ public URL getSource() {
+ return (URL) map.get(SOURCE_URL);
+ }
+
+ public void setSource(URL source) {
+ if (source != null)
+ map.put(SOURCE_URL, source);
+ }
+
+ public boolean satisfies(RequirementImpl requirement) {
+ for (Iterator i = capabilities.iterator(); i.hasNext();) {
+ CapabilityImpl capability = (CapabilityImpl) i.next();
+ if (requirement.isSatisfied(capability))
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return symbolicName + "-" + version;
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ map.put(SIZE, new Long(size));
+ }
+
+ public Collection getRequirementList() {
+ return requirements;
+ }
+
+ public Collection getCapabilityList() {
+ return capabilities;
+ }
+
+ @Override
+ public int hashCode() {
+ if (url.toExternalForm().endsWith(".jar")) {
+ return symbolicName.hashCode() ^ version.hashCode();
+ }
+ else {
+ return url.hashCode();
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ try {
+ ResourceImpl other = (ResourceImpl) o;
+ return symbolicName.equals(other.symbolicName)
+ && version.equals(other.version);
+ }
+ catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ public String[] getCategories() {
+ return (String[]) categories.toArray(new String[categories.size()]);
+ }
+
+ public Map getProperties() {
+ return Collections.unmodifiableMap(map);
+ }
+
+ public synchronized String getId() {
+ if ( id == null )
+ id = symbolicName + "/" + version;
+ return id;
+ }
+
+ public Repository getRepository() {
+ return repository;
+ }
+
+ void setName(String value) {
+ this.symbolicName = value;
+ }
+
+ void put(String name, Object value) {
+ map.put(name, value);
+ }
+
+ public void setPresentationName(String name) {
+ presentationName = name;
+ if (name != null)
+ map.put(PRESENTATION_NAME, name);
+ }
+
+ public String getPresentationName() {
+ return presentationName;
+ }
+
+ public void setFile(File zipFile) {
+ file = zipFile;
+ }
+
+ public Set getExtendList() {
+ Set set = new HashSet();
+ for (Iterator i = requirements.iterator(); i.hasNext();) {
+ RequirementImpl impl = (RequirementImpl) i.next();
+ if ( impl.isExtend())
+ set.add(impl);
+ }
+ return set;
+ }
+
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/StringSet.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/StringSet.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/StringSet.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/StringSet.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,32 @@
+/*
+ * $Id: StringSet.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.util.*;
+
+public class StringSet extends HashSet {
+ static final long serialVersionUID = 1L;
+
+ public StringSet(String set) {
+ StringTokenizer st = new StringTokenizer(set, ",");
+ while (st.hasMoreTokens())
+ add(st.nextToken().trim());
+ }
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Tag.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Tag.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Tag.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Tag.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,489 @@
+/*
+ * $Id: Tag.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.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * The Tag class represents a minimal XML tree. It consist of a named element
+ * with a hashtable of named attributes. Methods are provided to walk the tree
+ * and get its constituents. The content of a Tag is a list that contains String
+ * objects or other Tag objects.
+ */
+public class Tag {
+ Tag parent;
+ String name;
+ Map attributes = new TreeMap();
+ Vector content = new Vector();
+
+ static SimpleDateFormat format = new SimpleDateFormat(
+ "yyyyMMddhhmmss.SSS");
+
+ /**
+ * Construct a new Tag with a name.
+ */
+ public Tag(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Construct a new Tag with a name.
+ */
+ public Tag(String name, Map attributes) {
+ this.name = name;
+ this.attributes = attributes;
+ }
+
+ /**
+ * Construct a new Tag with a name and a set of attributes. The attributes
+ * are given as ( name, value ) ...
+ */
+ public Tag(String name, String[] attributes) {
+ this.name = name;
+ for (int i = 0; i < attributes.length; i += 2)
+ addAttribute(attributes[i], attributes[i + 1]);
+ }
+
+ /**
+ * Construct a new Tag with a single string as content.
+ */
+ public Tag(String name, String content) {
+ this.name = name;
+ addContent(content);
+ }
+
+ /**
+ * Add a new attribute.
+ */
+ public void addAttribute(String key, String value) {
+ attributes.put(key, value);
+ }
+
+ /**
+ * Add a new attribute.
+ */
+ public void addAttribute(String key, Object value) {
+ if (value == null)
+ return;
+ attributes.put(key, value.toString());
+ }
+
+ /**
+ * Add a new attribute.
+ */
+ public void addAttribute(String key, int value) {
+ attributes.put(key, Integer.toString(value));
+ }
+
+ /**
+ * Add a new date attribute. The date is formatted as the SimpleDateFormat
+ * describes at the top of this class.
+ */
+ public void addAttribute(String key, Date value) {
+ attributes.put(key, format.format(value));
+ }
+
+ /**
+ * Add a new content string.
+ */
+ public void addContent(String string) {
+ content.addElement(string);
+ }
+
+ /**
+ * Add a new content tag.
+ */
+ public void addContent(Tag tag) {
+ content.addElement(tag);
+ tag.parent = this;
+ }
+
+ /**
+ * Return the name of the tag.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Return the attribute value.
+ */
+ public String getAttribute(String key) {
+ return (String) attributes.get(key);
+ }
+
+ /**
+ * Return the attribute value or a default if not defined.
+ */
+ public String getAttribute(String key, String deflt) {
+ String answer = getAttribute(key);
+ return answer == null ? deflt : answer;
+ }
+
+ /**
+ * Answer the attributes as a Dictionary object.
+ */
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * Return the contents.
+ */
+ public Vector getContents() {
+ return content;
+ }
+
+ /**
+ * Return a string representation of this Tag and all its children
+ * recursively.
+ */
+ @Override
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ print(0, new PrintWriter(sw));
+ return sw.toString();
+ }
+
+ /**
+ * Return only the tags of the first level of descendants that match the
+ * name.
+ */
+ public Vector getContents(String tag) {
+ Vector out = new Vector();
+ for (Enumeration e = content.elements(); e.hasMoreElements();) {
+ Object o = e.nextElement();
+ if (o instanceof Tag && ((Tag) o).getName().equals(tag))
+ out.addElement(o);
+ }
+ return out;
+ }
+
+ /**
+ * Return the whole contents as a String (no tag info and attributes).
+ */
+ public String getContentsAsString() {
+ StringBuffer sb = new StringBuffer();
+ getContentsAsString(sb);
+ return sb.toString();
+ }
+
+ /**
+ * convenient method to get the contents in a StringBuffer.
+ */
+ public void getContentsAsString(StringBuffer sb) {
+ for (Enumeration e = content.elements(); e.hasMoreElements();) {
+ Object o = e.nextElement();
+ if (o instanceof Tag)
+ ((Tag) o).getContentsAsString(sb);
+ else
+ sb.append(o.toString());
+ }
+ }
+
+ /**
+ * Print the tag formatted to a PrintWriter.
+ */
+ public void print(int indent, PrintWriter pw) {
+ pw.print("\n");
+ spaces(pw, indent);
+ pw.print('<');
+ pw.print(name);
+
+ for (Iterator e = attributes.keySet().iterator(); e.hasNext();) {
+ String key = (String) e.next();
+ String value = escape((String) attributes.get(key));
+ pw.print(' ');
+ pw.print(key);
+ pw.print("=");
+ String quote = "'";
+ if (value.indexOf(quote) >= 0)
+ quote = "\"";
+ pw.print(quote);
+ pw.print(value);
+ pw.print(quote);
+ }
+
+ if (content.size() == 0)
+ pw.print('/');
+ else {
+ pw.print('>');
+ for (Enumeration e = content.elements(); e.hasMoreElements();) {
+ Object content = e.nextElement();
+ if (content instanceof String) {
+ formatted(pw, indent + 2, 60, escape((String) content));
+ }
+ else if (content instanceof Tag) {
+ Tag tag = (Tag) content;
+ tag.print(indent + 2, pw);
+ }
+ }
+ pw.print("\n");
+ spaces(pw, indent);
+ pw.print("</");
+ pw.print(name);
+ }
+ pw.print('>');
+ }
+
+ /**
+ * Convenience method to print a string nicely and does character conversion
+ * to entities.
+ */
+ void formatted(PrintWriter pw, int left, int width, String s) {
+ int pos = width + 1;
+ s = s.trim();
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (i == 0 || (Character.isWhitespace(c) && pos > width - 3)) {
+ pw.print("\n");
+ spaces(pw, left);
+ pos = 0;
+ }
+ switch (c) {
+ case '<' :
+ pw.print("<");
+ pos += 4;
+ break;
+ case '>' :
+ pw.print(">");
+ pos += 4;
+ break;
+ case '&' :
+ pw.print("&");
+ pos += 5;
+ break;
+ default :
+ pw.print(c);
+ pos++;
+ break;
+ }
+
+ }
+ }
+
+ /**
+ * Escape a string, do entity conversion.
+ */
+ String escape(String s) {
+ if ( s == null )
+ return "?null?";
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '<' :
+ sb.append("<");
+ break;
+ case '>' :
+ sb.append(">");
+ break;
+ case '&' :
+ sb.append("&");
+ break;
+ default :
+ sb.append(c);
+ break;
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Make spaces.
+ */
+ void spaces(PrintWriter pw, int n) {
+ while (n-- > 0)
+ pw.print(' ');
+ }
+
+ /**
+ * root/preferences/native/os
+ */
+ public Tag[] select(String path) {
+ return select(path, (Tag) null);
+ }
+
+ public Tag[] select(String path, Tag mapping) {
+ Vector v = new Vector();
+ select(path, v, mapping);
+ Tag[] result = new Tag[v.size()];
+ v.copyInto(result);
+ return result;
+ }
+
+ void select(String path, Vector results, Tag mapping) {
+ if (path.startsWith("//")) {
+ int i = path.indexOf('/', 2);
+ String name = path.substring(2, i < 0 ? path.length() : i);
+
+ for (Enumeration e = content.elements(); e.hasMoreElements();) {
+ Object o = e.nextElement();
+ if (o instanceof Tag) {
+ Tag child = (Tag) o;
+ if (match(name, child, mapping))
+ results.add(child);
+ child.select(path, results, mapping);
+ }
+
+ }
+ return;
+ }
+
+ if (path.length() == 0) {
+ results.addElement(this);
+ return;
+ }
+
+ int i = path.indexOf("/");
+ String elementName = path;
+ String remainder = "";
+ if (i > 0) {
+ elementName = path.substring(0, i);
+ remainder = path.substring(i + 1);
+ }
+
+ for (Enumeration e = content.elements(); e.hasMoreElements();) {
+ Object o = e.nextElement();
+ if (o instanceof Tag) {
+ Tag child = (Tag) o;
+ if (child.getName().equals(elementName)
+ || elementName.equals("*"))
+ child.select(remainder, results, mapping);
+ }
+ }
+ }
+
+ public boolean match(String search, Tag child, Tag mapping) {
+ String target = child.getName();
+ String sn = null;
+ String tn = null;
+
+ if (search.equals("*"))
+ return true;
+
+ int s = search.indexOf(':');
+ if (s > 0) {
+ sn = search.substring(0, s);
+ search = search.substring(s + 1);
+ }
+ int t = target.indexOf(':');
+ if (t > 0) {
+ tn = target.substring(0, t);
+ target = target.substring(t + 1);
+ }
+
+ if (!search.equals(target)) // different tag names
+ return false;
+
+ if (mapping == null) {
+ return tn == sn || (sn != null && sn.equals(tn));
+ }
+ else {
+ String suri = sn == null ? mapping.getAttribute("xmlns") : mapping
+ .getAttribute("xmlns:" + sn);
+ String turi = tn == null ? child.findRecursiveAttribute("xmlns")
+ : child.findRecursiveAttribute("xmlns:" + tn);
+ return turi == suri
+ || (turi != null && suri != null && turi.equals(suri));
+ }
+ }
+
+ public String getString(String path) {
+ String attribute = null;
+ int index = path.indexOf("@");
+ if (index >= 0) {
+ // attribute
+ attribute = path.substring(index + 1);
+
+ if (index > 0) {
+ // prefix path
+ path = path.substring(index - 1); // skip -1
+ }
+ else
+ path = "";
+ }
+ Tag tags[] = select(path);
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < tags.length; i++) {
+ if (attribute == null)
+ tags[i].getContentsAsString(sb);
+ else
+ sb.append(tags[i].getAttribute(attribute));
+ }
+ return sb.toString();
+ }
+
+ public String getStringContent() {
+ StringBuffer sb = new StringBuffer();
+ for (Enumeration e = content.elements(); e.hasMoreElements();) {
+ Object c = e.nextElement();
+ if (!(c instanceof Tag))
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ public String getNameSpace() {
+ return getNameSpace(name);
+ }
+
+ public String getNameSpace(String name) {
+ int index = name.indexOf(':');
+ if (index > 0) {
+ String ns = name.substring(0, index);
+ return findRecursiveAttribute("xmlns:" + ns);
+ }
+ else
+ return findRecursiveAttribute("xmlns");
+ }
+
+ public String findRecursiveAttribute(String name) {
+ String value = getAttribute(name);
+ if (value != null)
+ return value;
+ if (parent != null)
+ return parent.findRecursiveAttribute(name);
+ return null;
+ }
+
+ public String getLocalName() {
+ int index = name.indexOf(':');
+ if (index <= 0)
+ return name;
+
+ return name.substring(index + 1);
+ }
+
+ public void rename(String string) {
+ name = string;
+ }
+
+
+ public static void convert( Collection c, String type, Tag parent ) {
+ for ( Iterator i=c.iterator(); i.hasNext(); ) {
+ Map map = (Map) i.next();
+ parent.addContent( new Tag(type, map) );
+ }
+ }
+
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/VersionRange.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/VersionRange.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/VersionRange.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/VersionRange.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,122 @@
+/*
+ * $Id: VersionRange.java 46 2008-01-17 19:05:21Z peter.kriens@aqute.biz $
+ *
+ * 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.util.regex.*;
+
+import org.osgi.framework.*;
+
+public class VersionRange implements Comparable {
+ Version high;
+ Version low;
+ char start = '[';
+ char end = ']';
+
+ static String V = "[0-9]+(\\.[0-9]+(\\.[0-9]+(\\.[a-zA-Z0-9_-]+)?)?)?";
+ static Pattern RANGE = Pattern.compile("(\\(|\\[)\\s*(" + V + ")\\s*,\\s*(" + V
+ + ")\\s*(\\)|\\])");
+
+ public VersionRange(String string) {
+ string = string.trim();
+ Matcher m = RANGE.matcher(string);
+ if (m.matches()) {
+ start = m.group(1).charAt(0);
+ low = new Version(m.group(2));
+ high = new Version(m.group(6));
+ end = m.group(10).charAt(0);
+ if (low.compareTo(high) >= 0)
+ throw new IllegalArgumentException(
+ "Low Range is higher than High Range: " + low + "-"
+ + high);
+
+ } else
+ high = low = new Version(string);
+ }
+
+ public boolean isRange() {
+ return high != low;
+ }
+
+ public boolean includeLow() {
+ return start == '[';
+ }
+
+ public boolean includeHigh() {
+ return end == ']';
+ }
+
+ @Override
+ public String toString() {
+ if (high == low)
+ return high.toString();
+
+ StringBuffer sb = new StringBuffer();
+ sb.append(start);
+ sb.append(low);
+ sb.append(',');
+ sb.append(high);
+ sb.append(end);
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof VersionRange) {
+ return compareTo(other)==0;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return low.hashCode() * high.hashCode();
+ }
+
+ public int compareTo(Object other) {
+ VersionRange range = (VersionRange) other;
+ VersionRange a = this, b = range;
+ if (range.isRange()) {
+ a = range;
+ b = this;
+ } else {
+ if ( !isRange() )
+ return low.compareTo(range.high);
+ }
+ int l = a.low.compareTo(b.low);
+ boolean ll = false;
+ if (a.includeLow())
+ ll = l <= 0;
+ else
+ ll = l < 0;
+
+ if (!ll)
+ return -1;
+
+ int h = a.high.compareTo(b.high);
+ if (a.includeHigh())
+ ll = h >= 0;
+ else
+ ll = h > 0;
+
+ if (ll)
+ return 0;
+ else
+ return 1;
+ }
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/service/obr/Capability.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/service/obr/Capability.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/service/obr/Capability.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/service/obr/Capability.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,48 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.obr/src/org/osgi/service/obr/Capability.java,v 1.3 2006/03/16 14:56:17 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2006). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+package org.osgi.service.obr;
+
+import java.util.Map;
+
+/**
+ * A named set of properties representing some capability that is provided by
+ * its owner.
+ *
+ * @version $Revision: 1.3 $
+ */
+public interface Capability
+{
+ /**
+ * Return the name of the capability.
+ *
+ */
+ String getName();
+
+ /**
+ * Return the set of properties.
+ *
+ * Notice that the value of the properties is a list of values.
+ *
+ * @return a Map<String,List>
+ */
+ Map getProperties();
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/service/obr/CapabilityProvider.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/service/obr/CapabilityProvider.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/service/obr/CapabilityProvider.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/service/obr/CapabilityProvider.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,49 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.obr/src/org/osgi/service/obr/CapabilityProvider.java,v 1.3 2006/03/16 14:56:17 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2006). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+package org.osgi.service.obr;
+
+/**
+ * This service interface allows third parties to provide capabilities that are
+ * present on the system but not encoded in the bundle's manifests. For example,
+ * a capability provider could provide:
+ * <ol>
+ * <li>A Set of certificates</li>
+ * <li>Dimensions of the screen</li>
+ * <li>Amount of memory</li>
+ * <li>...</li>
+ * </ol>
+ *
+ * @version $Revision: 1.3 $
+ */
+public interface CapabilityProvider
+{
+ /**
+ * Return a set of capabilities.
+ *
+ * These capabilities are considered part of the platform. Bundles can
+ * require these capabilities during selection. All capabilities from
+ * different providers are considered part of the platform.
+ *
+ * @return Set of capabilities
+ */
+ Capability[] getCapabilities();
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/service/obr/Repository.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/service/obr/Repository.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/service/obr/Repository.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/service/obr/Repository.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,53 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.obr/src/org/osgi/service/obr/Repository.java,v 1.3 2006/03/16 14:56:17 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2006). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+package org.osgi.service.obr;
+
+import java.net.URL;
+
+/**
+ * Represents a repository.
+ *
+ * @version $Revision: 1.3 $
+ */
+public interface Repository
+{
+ /**
+ * Return the associated URL for the repository.
+ *
+ */
+ URL getURL();
+
+ /**
+ * Return the resources for this repository.
+ */
+ Resource[] getResources();
+
+ /**
+ * Return the name of this reposotory.
+ *
+ * @return a non-null name
+ */
+ String getName();
+
+ long getLastModified();
+
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/service/obr/RepositoryAdmin.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/service/obr/RepositoryAdmin.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/service/obr/RepositoryAdmin.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/service/obr/RepositoryAdmin.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,104 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.obr/src/org/osgi/service/obr/RepositoryAdmin.java,v 1.3 2006/03/16 14:56:17 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2006). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+package org.osgi.service.obr;
+
+import java.net.URL;
+
+/**
+ * Provides centralized access to the distributed repository.
+ *
+ * A repository contains a set of <i>resources</i>. A resource contains a
+ * number of fixed attributes (name, version, etc) and sets of:
+ * <ol>
+ * <li>Capabilities - Capabilities provide a named aspect: a bundle, a display,
+ * memory, etc.</li>
+ * <li>Requirements - A named filter expression. The filter must be satisfied
+ * by one or more Capabilties with the given name. These capabilities can come
+ * from other resources or from the platform. If multiple resources provide the
+ * requested capability, one is selected. (### what algorithm? ###)</li>
+ * <li>Requests - Requests are like requirements, except that a request can be
+ * fullfilled by 0..n resources. This feature can be used to link to resources
+ * that are compatible with the given resource and provide extra functionality.
+ * For example, a bundle could request all its known fragments. The UI
+ * associated with the repository could list these as optional downloads.</li>
+ *
+ * @version $Revision: 1.3 $
+ */
+public interface RepositoryAdmin
+{
+ /**
+ * Discover any resources that match the given filter.
+ *
+ * This is not a detailed search, but a first scan of applicable resources.
+ *
+ * ### Checking the capabilities of the filters is not possible because that
+ * requires a new construct in the filter.
+ *
+ * The filter expression can assert any of the main headers of the resource.
+ * The attributes that can be checked are:
+ *
+ * <ol>
+ * <li>name</li>
+ * <li>version (uses filter matching rules)</li>
+ * <li>description</li>
+ * <li>category</li>
+ * <li>copyright</li>
+ * <li>license</li>
+ * <li>source</li>
+ * </ol>
+ *
+ * @param filterExpr
+ * A standard OSGi filter
+ * @return List of resources matching the filters.
+ */
+ Resource[] discoverResources(String filterExpr);
+
+ /**
+ * Create a resolver.
+ *
+ * @param resource
+ * @return
+ */
+ Resolver resolver();
+
+ /**
+ * Add a new repository to the federation.
+ *
+ * The url must point to a repository XML file.
+ *
+ * @param repository
+ * @return
+ * @throws Exception
+ */
+ Repository addRepository(URL repository) throws Exception;
+
+ boolean removeRepository(URL repository);
+
+ /**
+ * List all the repositories.
+ *
+ * @return
+ */
+ Repository[] listRepositories();
+
+ Resource getResource(String respositoryId);
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/service/obr/RepositoryPermission.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/service/obr/RepositoryPermission.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/service/obr/RepositoryPermission.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/service/obr/RepositoryPermission.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,40 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.obr/src/org/osgi/service/obr/RepositoryPermission.java,v 1.3 2006/03/16 14:56:17 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2006). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+package org.osgi.service.obr;
+
+import java.security.BasicPermission;
+
+/**
+ * TODO OBR - Implement repository permission.
+ *
+ * @version $Revision: 1.3 $
+ */
+public class RepositoryPermission extends BasicPermission
+{
+
+ public RepositoryPermission(String name)
+ {
+ super(name);
+
+ }
+
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/service/obr/Requirement.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/service/obr/Requirement.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/service/obr/Requirement.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/service/obr/Requirement.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,53 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.obr/src/org/osgi/service/obr/Requirement.java,v 1.4 2006/03/16 14:56:17 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2006). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+package org.osgi.service.obr;
+
+/**
+ * A named requirement specifies the need for certain capabilities with the same
+ * name.
+ *
+ * @version $Revision: 1.4 $
+ */
+public interface Requirement
+{
+
+ /**
+ * Return the name of the requirement.
+ */
+ String getName();
+
+ /**
+ * Return the filter.
+ *
+ */
+ String getFilter();
+
+ boolean isMultiple();
+
+ boolean isOptional();
+
+ boolean isExtend();
+
+ String getComment();
+
+ boolean isSatisfied(Capability capability);
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/service/obr/Resolver.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/service/obr/Resolver.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/service/obr/Resolver.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/service/obr/Resolver.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,44 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.obr/src/org/osgi/service/obr/Resolver.java,v 1.3 2006/03/16 14:56:17 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2006). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+package org.osgi.service.obr;
+
+public interface Resolver
+{
+
+ void add(Resource resource);
+
+ Requirement[] getUnsatisfiedRequirements();
+
+ Resource[] getOptionalResources();
+
+ Requirement[] getReason(Resource resource);
+
+ Resource[] getResources(Requirement requirement);
+
+ Resource[] getRequiredResources();
+
+ Resource[] getAddedResources();
+
+ boolean resolve();
+
+ void deploy(boolean start);
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/service/obr/Resource.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/service/obr/Resource.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/service/obr/Resource.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/service/obr/Resource.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,86 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.obr/src/org/osgi/service/obr/Resource.java,v 1.5 2006/03/16 14:56:17 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2006). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+package org.osgi.service.obr;
+
+import java.net.URL;
+import java.util.Map;
+
+import org.osgi.framework.Version;
+
+/**
+ * A resource is an abstraction of a downloadable thing, like a bundle.
+ *
+ * Resources have capabilities and requirements. All a resource's requirements
+ * must be satisfied before it can be installed.
+ *
+ * @version $Revision: 1.5 $
+ */
+public interface Resource
+{
+ final String LICENSE_URL = "license";
+
+ final String DESCRIPTION = "description";
+
+ final String DOCUMENTATION_URL = "documentation";
+
+ final String COPYRIGHT = "copyright";
+
+ final String SOURCE_URL = "source";
+
+ final String SYMBOLIC_NAME = "symbolicname";
+
+ final String PRESENTATION_NAME = "presentationname";
+
+ final String ID = "id";
+
+ final String VERSION = "version";
+
+ final String URL = "url";
+
+ final String SIZE = "size";
+
+ final static String[] KEYS = { DESCRIPTION, SIZE, ID, LICENSE_URL,
+ DOCUMENTATION_URL, COPYRIGHT, SOURCE_URL, PRESENTATION_NAME,
+ SYMBOLIC_NAME, VERSION, URL };
+
+ // get readable name
+
+ Map getProperties();
+
+ String getSymbolicName();
+
+ String getPresentationName();
+
+ Version getVersion();
+
+ String getId();
+
+ URL getURL();
+
+ Requirement[] getRequirements();
+
+ Capability[] getCapabilities();
+
+ String[] getCategories();
+
+ Repository getRepository();
+}
\ No newline at end of file
Added: incubator/ace/trunk/test/ext/cobertura/asm-2.2.1.jar
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/ext/cobertura/asm-2.2.1.jar?rev=788992&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/ace/trunk/test/ext/cobertura/asm-2.2.1.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/ace/trunk/test/ext/cobertura/asm-tree-2.2.1.jar
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/ext/cobertura/asm-tree-2.2.1.jar?rev=788992&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/ace/trunk/test/ext/cobertura/asm-tree-2.2.1.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/ace/trunk/test/ext/cobertura/cobertura.jar
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/ext/cobertura/cobertura.jar?rev=788992&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/ace/trunk/test/ext/cobertura/cobertura.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/ace/trunk/test/ext/cobertura/jakarta-oro-2.0.8.jar
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/ext/cobertura/jakarta-oro-2.0.8.jar?rev=788992&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/ace/trunk/test/ext/cobertura/jakarta-oro-2.0.8.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/ace/trunk/test/ext/cobertura/log4j-1.2.9.jar
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/ext/cobertura/log4j-1.2.9.jar?rev=788992&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/ace/trunk/test/ext/cobertura/log4j-1.2.9.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/ace/trunk/test/ext/commons/commons-cli-1.1.jar
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/ext/commons/commons-cli-1.1.jar?rev=788992&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/ace/trunk/test/ext/commons/commons-cli-1.1.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/ace/trunk/test/ext/easymock.jar
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/ext/easymock.jar?rev=788992&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/ace/trunk/test/ext/easymock.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/ace/trunk/test/ext/testng-5.5-jdk15.jar
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/ext/testng-5.5-jdk15.jar?rev=788992&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/ace/trunk/test/ext/testng-5.5-jdk15.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/AdminTestUtil.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/AdminTestUtil.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/AdminTestUtil.java (added)
+++ incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/AdminTestUtil.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,35 @@
+package net.luminis.liq.client.repository.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class AdminTestUtil {
+
+ public static byte[] copy(InputStream in) throws IOException {
+ byte[] result = new byte[in.available()];
+ in.read(result);
+ return result;
+ }
+
+ public static boolean byteArraysEqual(byte[] left, byte[] right) {
+ if (left.length != right.length) {
+ return false;
+ }
+ for (int i = 0; i < right.length; i++) {
+ if (left[i] != right[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static byte[] copy(byte[] input) {
+ byte[] result = new byte[input.length];
+ for (int i = 0; i < input.length; i++) {
+ result[i] = input[i];
+ }
+ return result;
+ }
+
+
+}
Added: incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/ArtifactTest.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/ArtifactTest.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/ArtifactTest.java (added)
+++ incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/ArtifactTest.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,165 @@
+package net.luminis.liq.client.repository.impl;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.luminis.liq.client.repository.helper.ArtifactHelper;
+import net.luminis.liq.client.repository.helper.ArtifactPreprocessor;
+import net.luminis.liq.client.repository.helper.bundle.BundleHelper;
+import net.luminis.liq.client.repository.helper.bundle.impl.BundleHelperImpl;
+import net.luminis.liq.client.repository.object.ArtifactObject;
+import net.luminis.liq.test.utils.TestUtils;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.log.LogService;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Tests the behavior of the ArtifactObject class, most prominently, checking whether
+ * delegation to the Helpers is done at the right moments.
+ */
+public class ArtifactTest {
+
+ private ArtifactRepositoryImpl m_artifactRepository;
+
+ @BeforeMethod(alwaysRun = true)
+ public void init() {
+ BundleContext bc = TestUtils.createMockObjectAdapter(BundleContext.class, new Object() {
+ @SuppressWarnings("unused")
+ public Filter createFilter(String filter) throws InvalidSyntaxException {
+ return new org.apache.felix.framework.FilterImpl(filter);
+ }
+ });
+
+ m_artifactRepository = new ArtifactRepositoryImpl(TestUtils.createNullObject(ChangeNotifier.class));
+ TestUtils.configureObject(m_artifactRepository, LogService.class);
+ TestUtils.configureObject(m_artifactRepository, BundleContext.class, bc);
+ }
+
+ @Test( groups = { TestUtils.UNIT } )
+ public void testAttributeChecking() {
+ ArtifactHelper helper = new MockHelper("yourURL");
+
+ try {
+ createArtifact("myMime", "myUrl", null, null);
+ assert false : "There is no helper for this type of artifact.";
+ }
+ catch (IllegalArgumentException iae) {
+ // expected
+ }
+
+ m_artifactRepository.addHelper("myMime", helper);
+
+ ArtifactObject obj = createArtifact("myMime", "myUrl", null, null);
+
+ assert obj.getURL().equals("yourURL");
+
+ try {
+ m_artifactRepository.getHelper("yourMime");
+ assert false : "We have not registered this helper.";
+ }
+ catch (IllegalArgumentException iae) {
+ // expected
+ }
+ }
+
+ @Test( groups = { TestUtils.UNIT } )
+ public void testResourceProcessorFiltering() throws InvalidSyntaxException {
+ m_artifactRepository.addHelper("myMime", new MockHelper());
+ m_artifactRepository.addHelper(BundleHelper.MIMETYPE, new BundleHelperImpl());
+
+ ArtifactObject normalBundle = createArtifact(BundleHelper.MIMETYPE, "normalBundle", "normalBundle", null);
+
+ ArtifactObject resourceProcessor1 = createArtifact(BundleHelper.MIMETYPE, "resourceProcessor1", "resourceProcessor1", "somePID");
+ ArtifactObject resourceProcessor2 = createArtifact(BundleHelper.MIMETYPE, "resourceProcessor2", "resourceProcessor2", "someOtherPID");
+
+ ArtifactObject myArtifact = createArtifact("myMime", "myArtifact", null, null);
+
+ assert m_artifactRepository.get().size() == 2 : "We expect to find two artifacts, but we find " + m_artifactRepository.get().size();
+
+ List<ArtifactObject> list = m_artifactRepository.get(m_artifactRepository.createFilter("(!(" + BundleHelper.KEY_SYMBOLICNAME + "=normalBundle))"));
+ assert (list.size() == 1) && list.contains(myArtifact) : "We expect to find one artifact when filtering, but we find " + list.size();
+
+ list = m_artifactRepository.getResourceProcessors();
+ assert (list.size() == 2) && list.contains(resourceProcessor1) && list.contains(resourceProcessor2) : "We expect to find both our resource processors when asking for them; we find " + list.size() + " artifacts.";
+
+ m_artifactRepository.get(m_artifactRepository.createFilter("(" + BundleHelper.MIMETYPE + "=my\\(Mi\\*me)"));
+ }
+
+ private ArtifactObject createArtifact(String mimetype, String URL, String symbolicName, String processorPID) {
+ Map<String, String> attributes = new HashMap<String, String>();
+ attributes.put(ArtifactObject.KEY_MIMETYPE, mimetype);
+ attributes.put(ArtifactObject.KEY_URL, URL);
+ Map<String, String> tags = new HashMap<String, String>();
+
+ if (symbolicName != null) {
+ attributes.put(BundleHelper.KEY_SYMBOLICNAME, symbolicName);
+ }
+ if (processorPID != null) {
+ attributes.put(BundleHelper.KEY_RESOURCE_PROCESSOR_PID, processorPID);
+ }
+
+ return m_artifactRepository.create(attributes, tags);
+ }
+}
+
+/**
+ * Helper for testing the ArtifactObject. In the constructor, a <code>replaceURL</code> can
+ * be passed in to test the attribute normalization.
+ */
+class MockHelper implements ArtifactHelper {
+ private final String m_replaceURL;
+
+ MockHelper() {
+ this(null);
+ }
+
+ MockHelper(String replaceURL) {
+ m_replaceURL = replaceURL;
+ }
+
+ public Map<String, String> checkAttributes(Map<String, String> attributes) {
+ if ((m_replaceURL != null) && attributes.containsKey(ArtifactObject.KEY_URL)) {
+ attributes.put(ArtifactObject.KEY_URL, m_replaceURL);
+ }
+ return attributes;
+ }
+
+ public Comparator<ArtifactObject> getComparator() {
+ return null;
+ }
+
+ public String[] getDefiningKeys() {
+ return new String[0];
+ }
+
+ public String[] getMandatoryAttributes() {
+ return new String[0];
+ }
+
+ public boolean canUse(ArtifactObject object) {
+ return false;
+ }
+
+ public <TYPE extends ArtifactObject> String getAssociationFilter(TYPE obj, Map<String, String> properties) {
+ return null;
+ }
+
+ public <TYPE extends ArtifactObject> int getCardinality(TYPE obj, Map<String, String> properties) {
+ return 0;
+ }
+
+ public ArtifactPreprocessor getPreprocessor() {
+ return null;
+ }
+}
+
+
+
+
+
Added: incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/CachedRepositoryImplTest.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/CachedRepositoryImplTest.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/CachedRepositoryImplTest.java (added)
+++ incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/CachedRepositoryImplTest.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,108 @@
+package net.luminis.liq.client.repository.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.luminis.liq.repository.Repository;
+import net.luminis.liq.repository.ext.BackupRepository;
+import net.luminis.liq.repository.ext.CachedRepository;
+import net.luminis.liq.repository.impl.CachedRepositoryImpl;
+import net.luminis.liq.test.utils.TestUtils;
+
+import org.testng.annotations.Test;
+
+public class CachedRepositoryImplTest {
+
+ /**
+ * Initial checkout: the remote repository contains some data for a given version,
+ * we make the cached repository do a checkout, and check whether all data arrives at the
+ * right places: in getLocal, and in the backup repository.
+ */
+ @Test( groups = { TestUtils.UNIT } )
+ public void testInitialCheckout() throws IllegalArgumentException, IOException {
+ Repository m_repository = new MockRepository();
+ byte[] testContent = new byte[] {'i', 'n', 'i', 't', 'i', 'a', 'l'};
+ m_repository.commit(new ByteArrayInputStream(testContent), 0);
+ BackupRepository m_backupRepository = new MockBackupRepository();
+
+ CachedRepository m_cachedRepository = new CachedRepositoryImpl(null, m_repository, m_backupRepository, 0);
+
+ InputStream input = m_cachedRepository.checkout(1);
+ byte[] inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, testContent) : "We got something different than 'initial' from checkout: " + new String(inputBytes);
+ input = m_cachedRepository.getLocal(false);
+ inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, testContent) : "We got something different than 'initial' from getLocal: " + new String(inputBytes);
+ input = m_backupRepository.read();
+ inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, testContent) : "We got something different than 'initial' from the backup repository: " + new String(inputBytes);
+ }
+
+ /**
+ * There are two types of commit, one that takes an input stream, and one that
+ * simply flushes whatever is in the current to the remote repository.
+ * After each commit, we should be able to renew the cached repository,
+ * and checkout the data we put in before.
+ */
+ @Test( groups = { TestUtils.UNIT } )
+ public void testCommit() throws IllegalArgumentException, IOException {
+ Repository m_repository = new MockRepository();
+ BackupRepository m_backupRepository = new MockBackupRepository();
+
+ CachedRepository m_cachedRepository = new CachedRepositoryImpl(null, m_repository, m_backupRepository, 0);
+ byte[] testContent = new byte[] {'i', 'n', 'i', 't', 'i', 'a', 'l'};
+
+ InputStream input = new ByteArrayInputStream(testContent);
+ m_cachedRepository.commit(input, 0);
+
+ m_cachedRepository = new CachedRepositoryImpl(null, m_repository, m_backupRepository, 0);
+ input = m_cachedRepository.checkout(1);
+ byte[] inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, testContent) : "We got something different than 'initial' from checkout: " + new String(inputBytes);
+
+ byte[] newTestContent = new byte[] {'n', 'e', 'w'};
+
+ m_cachedRepository.writeLocal(new ByteArrayInputStream(newTestContent));
+
+ m_cachedRepository.commit();
+
+ m_cachedRepository = new CachedRepositoryImpl(null, m_repository, m_backupRepository, 0);
+ input = m_cachedRepository.checkout(2);
+ inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, newTestContent) : "We got something different than 'new' from checkout: " + new String(inputBytes);
+ }
+
+ /**
+ * After checking out and changing stuff, we want to revert to the old version.
+ * @throws IOException
+ * @throws IllegalArgumentException
+ */
+ @Test( groups = { TestUtils.UNIT } )
+ public void testRevert() throws IllegalArgumentException, IOException {
+ Repository m_repository = new MockRepository();
+ BackupRepository m_backupRepository = new MockBackupRepository();
+
+ CachedRepository m_cachedRepository = new CachedRepositoryImpl(null, m_repository, m_backupRepository, 0);
+ byte[] testContent = new byte[] {'i', 'n', 'i', 't', 'i', 'a', 'l'};
+
+ InputStream input = new ByteArrayInputStream(testContent);
+ m_cachedRepository.commit(input, 0);
+
+ m_cachedRepository = new CachedRepositoryImpl(null, m_repository, m_backupRepository, 0);
+ input = m_cachedRepository.checkout(1);
+
+ byte[] newTestContent = new byte[] {'n', 'e', 'w'};
+
+ m_cachedRepository.writeLocal(new ByteArrayInputStream(newTestContent));
+ input = m_cachedRepository.getLocal(false);
+ byte[] inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, newTestContent) : "We got something different than 'new' from getLocal: " + new String(inputBytes);
+
+ m_cachedRepository.revert();
+ input = m_cachedRepository.getLocal(false);
+ inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, testContent) : "We got something different than 'initial' from getLocal: " + new String(inputBytes);
+ }
+
+}
Added: incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/FilebasedBackupRepositoryTest.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/FilebasedBackupRepositoryTest.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/FilebasedBackupRepositoryTest.java (added)
+++ incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/FilebasedBackupRepositoryTest.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,58 @@
+package net.luminis.liq.client.repository.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.luminis.liq.repository.impl.FilebasedBackupRepository;
+import net.luminis.liq.test.utils.TestUtils;
+
+import org.testng.annotations.Test;
+
+public class FilebasedBackupRepositoryTest {
+
+ /**
+ * A basic scenario: we write, backup, write again, and revert.
+ */
+ @Test( groups = { TestUtils.UNIT } )
+ public void testFilebasedBackupRepository() throws IOException {
+ File current = File.createTempFile("testFilebasedBackupRepository", null);
+ File backup = File.createTempFile("testFilebasedBackupRepository", null);
+ current.deleteOnExit();
+ backup.deleteOnExit();
+
+ FilebasedBackupRepository rep = new FilebasedBackupRepository(current, backup);
+
+ byte[] testContent = new byte[] {'i', 'n', 'i', 't', 'i', 'a', 'l'};
+
+ // write initial content
+ rep.write(new ByteArrayInputStream(testContent));
+
+ // read initial content
+ InputStream input = rep.read();
+ byte[] inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, testContent) : "We got something different than 'initial' from read: " + new String(inputBytes);
+
+ // backup what's in the repository
+ rep.backup();
+
+ // write new content
+ byte[] newTestContent = new byte[] {'n', 'e', 'w'};
+ rep.write(new ByteArrayInputStream(newTestContent));
+
+ // read current content
+ input = rep.read();
+ inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, newTestContent) : "We got something different than 'new' from read: " + new String(inputBytes);
+
+ // revert to previous (initial) content
+ rep.restore();
+
+ // read current content
+ input = rep.read();
+ inputBytes = AdminTestUtil.copy(input);
+ assert AdminTestUtil.byteArraysEqual(inputBytes, testContent) : "We got something different than 'initial' from read: " + new String(inputBytes);
+ }
+
+}
Added: incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/MockBackupRepository.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/MockBackupRepository.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/MockBackupRepository.java (added)
+++ incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/MockBackupRepository.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,40 @@
+package net.luminis.liq.client.repository.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.luminis.liq.repository.ext.BackupRepository;
+
+public class MockBackupRepository implements BackupRepository {
+ private byte[] m_current;
+ private byte[] m_backup;
+
+ @Override
+ public boolean backup() throws IOException {
+ if (m_current == null) {
+ return false;
+ }
+ m_backup = AdminTestUtil.copy(m_current);
+ return true;
+ }
+
+ @Override
+ public InputStream read() throws IOException {
+ return new ByteArrayInputStream(m_current);
+ }
+
+ @Override
+ public boolean restore() throws IOException {
+ if (m_backup == null) {
+ return false;
+ }
+ m_current = AdminTestUtil.copy(m_backup);
+ return true;
+ }
+
+ @Override
+ public void write(InputStream data) throws IOException {
+ m_current = AdminTestUtil.copy(data);
+ }
+}
Added: incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/MockCachedRepository.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/MockCachedRepository.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/MockCachedRepository.java (added)
+++ incubator/ace/trunk/test/src/net/luminis/liq/client/repository/impl/MockCachedRepository.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,72 @@
+package net.luminis.liq.client.repository.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.luminis.liq.repository.SortedRangeSet;
+import net.luminis.liq.repository.ext.CachedRepository;
+
+public class MockCachedRepository implements CachedRepository {
+
+ @Override
+ public InputStream checkout(boolean fail) throws IOException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean commit() throws IOException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public InputStream getLocal(boolean fail) throws IOException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean revert() throws IOException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void writeLocal(InputStream data) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public InputStream checkout(long version) throws IOException, IllegalArgumentException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean commit(InputStream data, long fromVersion) throws IOException, IllegalArgumentException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public SortedRangeSet getRange() throws IOException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean isCurrent() throws IOException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public long getHighestRemoteVersion() throws IOException {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public long getMostRecentVersion() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+}