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 [18/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/apache/felix/metatype/internal/MetaTypeServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/MetaTypeServiceImpl.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/MetaTypeServiceImpl.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/MetaTypeServiceImpl.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.felix.metatype.internal;
+
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.apache.felix.metatype.MetaData;
+import org.apache.felix.metatype.MetaDataReader;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.MetaTypeInformation;
+import org.osgi.service.metatype.MetaTypeService;
+import org.xmlpull.v1.XmlPullParserException;
+
+
+/**
+ * The <code>MetaTypeServiceImpl</code> class is the implementation of the
+ * <code>MetaTypeService</code> interface of the OSGi Metatype Service
+ * Specification 1.1.
+ *
+ * @author fmeschbe
+ */
+class MetaTypeServiceImpl implements MetaTypeService
+{
+
+ /** The <code>BundleContext</code> of the providing this service. */
+ private final BundleContext bundleContext;
+
+
+ /**
+ * Creates an instance of this class.
+ *
+ * @param bundleContext The <code>BundleContext</code> ultimately used to
+ * access services if there are no meta type documents.
+ */
+ MetaTypeServiceImpl( BundleContext bundleContext )
+ {
+ this.bundleContext = bundleContext;
+ }
+
+
+ /**
+ * Looks for meta type documents in the given <code>bundle</code>. If no
+ * such documents exist, a <code>MetaTypeInformation</code> object is
+ * returned handling the services of the bundle.
+ * <p>
+ * According to the specification, the services of the bundle are ignored
+ * if at least one meta type document exists.
+ *
+ * @param bundle The <code>Bundle</code> for which a
+ * <code>MetaTypeInformation</code> is to be returned.
+ */
+ public MetaTypeInformation getMetaTypeInformation( Bundle bundle )
+ {
+ MetaTypeInformation mti = fromDocuments( bundle );
+ if ( mti != null )
+ {
+ return mti;
+ }
+
+ return new ServiceMetaTypeInformation( bundleContext, bundle );
+ }
+
+
+ private MetaTypeInformation fromDocuments( Bundle bundle )
+ {
+ MetaDataReader reader = new MetaDataReader();
+
+ // get the descriptors, return nothing if none
+ Enumeration docs = bundle.findEntries( METATYPE_DOCUMENTS_LOCATION, "*.xml", false );
+ if ( docs == null || !docs.hasMoreElements() )
+ {
+ return null;
+ }
+
+ MetaTypeInformationImpl cmti = new MetaTypeInformationImpl( bundle );
+ while ( docs.hasMoreElements() )
+ {
+ URL doc = ( URL ) docs.nextElement();
+ try
+ {
+ MetaData metaData = reader.parse( doc );
+ if (metaData != null) {
+ cmti.addMetaData( metaData );
+ }
+ }
+ catch ( XmlPullParserException xppe )
+ {
+ Activator.log( LogService.LOG_ERROR, "fromDocuments: Error parsing document " + doc, xppe );
+ }
+ catch ( IOException ioe )
+ {
+ Activator.log( LogService.LOG_ERROR, "fromDocuments: Error accessing document " + doc, ioe );
+ }
+ }
+ return cmti;
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/ServiceMetaTypeInformation.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/ServiceMetaTypeInformation.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/ServiceMetaTypeInformation.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/ServiceMetaTypeInformation.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.felix.metatype.internal;
+
+
+import org.osgi.framework.*;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.MetaTypeProvider;
+
+
+/**
+ * The <code>ServiceMetaTypeInformation</code> extends the
+ * {@link MetaTypeInformationImpl} adding support to register and unregister
+ * <code>ManagedService</code>s and <code>ManagedServiceFactory</code>s
+ * also implementing the <code>MetaTypeProvider</code> interface.
+ *
+ * @author fmeschbe
+ */
+public class ServiceMetaTypeInformation extends MetaTypeInformationImpl implements ServiceListener
+{
+
+ /**
+ * The filter specification to find <code>ManagedService</code>s and
+ * <code>ManagedServiceFactory</code>s as well as to register a service
+ * listener for those services (value is
+ * "(|(objectClass=org.osgi.service.cm.ManagedService)(objectClass=org.osgi.service.cm.ManagedServiceFactory))").
+ * We use the hard coded class name here to not create a dependency on the
+ * ConfigurationAdmin service, which may not be available.
+ */
+ private static final String FILTER = "(|(objectClass=org.osgi.service.cm.ManagedService)(objectClass=org.osgi.service.cm.ManagedServiceFactory))";
+
+ /**
+ * The <code>BundleContext</code> used to get and unget services which
+ * have to be registered and unregistered with the base class.
+ */
+ private final BundleContext bundleContext;
+
+
+ /**
+ * Creates an instance of this class handling services of the given
+ * <code>bundle</code>.
+ *
+ * @param bundleContext The <code>BundleContext</code> used to get and
+ * unget services.
+ * @param bundle The <code>Bundle</code> whose services are handled by
+ * this class.
+ */
+ public ServiceMetaTypeInformation( BundleContext bundleContext, Bundle bundle )
+ {
+ super( bundle );
+
+ this.bundleContext = bundleContext;
+
+ // register for service events for the bundle
+ try
+ {
+ bundleContext.addServiceListener( this, FILTER );
+ }
+ catch ( InvalidSyntaxException ise )
+ {
+ Activator.log( LogService.LOG_ERROR, "ServiceMetaTypeInformation: Cannot register for service events", ise );
+ }
+
+ // prepare the filter to select existing services
+ Filter filter;
+ try
+ {
+ filter = bundleContext.createFilter( FILTER );
+ }
+ catch ( InvalidSyntaxException ise )
+ {
+ Activator.log( LogService.LOG_ERROR, "ServiceMetaTypeInformation: Cannot create filter '" + FILTER + "'",
+ ise );
+ return;
+ }
+
+ // add current services of the bundle
+ ServiceReference[] sr = bundle.getRegisteredServices();
+ if ( sr != null )
+ {
+ for ( int i = 0; i < sr.length; i++ )
+ {
+ if ( filter.match( sr[i] ) )
+ {
+ addService( sr[i] );
+ }
+ }
+ }
+ }
+
+
+ // ---------- ServiceListener ----------------------------------------------
+
+ /**
+ * Handles service registration and unregistration events ignoring all
+ * services not belonging to the <code>Bundle</code> which is handled by
+ * this instance.
+ *
+ * @param event The <code>ServiceEvent</code>
+ */
+ public void serviceChanged( ServiceEvent event )
+ {
+ // only care for services of our bundle
+ if ( !getBundle().equals( event.getServiceReference().getBundle() ) )
+ {
+ return;
+ }
+
+ if ( event.getType() == ServiceEvent.REGISTERED )
+ {
+ addService( event.getServiceReference() );
+ }
+ else if ( event.getType() == ServiceEvent.UNREGISTERING )
+ {
+ removeService( event.getServiceReference() );
+ }
+ }
+
+
+ /**
+ * Registers the service described by the <code>serviceRef</code> with
+ * this instance if the service is a <code>MetaTypeProvider</code>
+ * instance and either a <code>service.factoryPid</code> or
+ * <code>service.pid</code> property is set in the service registration
+ * properties.
+ * <p>
+ * If the service is registered, this bundle keeps a reference, which is
+ * ungot when the service is unregistered or this bundle is stopped.
+ *
+ * @param serviceRef The <code>ServiceReference</code> describing the
+ * service to be checked and handled.
+ */
+ protected void addService( ServiceReference serviceRef )
+ {
+ Object srv = bundleContext.getService( serviceRef );
+
+ boolean ungetService = true;
+
+ if ( srv instanceof MetaTypeProvider )
+ {
+ MetaTypeProvider mtp = ( MetaTypeProvider ) srv;
+
+ // 1. check for a service factory PID
+ String factoryPid = ( String ) serviceRef.getProperty( SERVICE_FACTORYPID );
+ if ( factoryPid != null )
+ {
+ addFactoryPids( new String[]
+ { factoryPid } );
+ addMetaTypeProvider( factoryPid, mtp );
+ ungetService = false;
+ }
+ else
+ {
+ // 2. check for a service PID
+ String pid = ( String ) serviceRef.getProperty( Constants.SERVICE_PID );
+ if ( pid != null )
+ {
+ addPids( new String[]
+ { pid } );
+ addMetaTypeProvider( pid, mtp );
+ ungetService = false;
+ }
+ }
+ }
+
+ if ( ungetService )
+ {
+ bundleContext.ungetService( serviceRef );
+ }
+ }
+
+
+ /**
+ * Unregisters the service described by the <code>serviceRef</code> from
+ * this instance. Unregistration just checks for the
+ * <code>service.factoryPid</code> and <code>service.pid</code> service
+ * properties but does not care whether the service implements the
+ * <code>MetaTypeProvider</code> interface. If the service is registered
+ * it is simply unregistered.
+ * <p>
+ * If the service is actually unregistered the reference retrieved by the
+ * registration method is ungotten.
+ *
+ * @param serviceRef The <code>ServiceReference</code> describing the
+ * service to be unregistered.
+ */
+ protected void removeService( ServiceReference serviceRef )
+ {
+ boolean ungetService = false;
+
+ // 1. check for a service factory PID
+ String factoryPid = ( String ) serviceRef.getProperty( SERVICE_FACTORYPID );
+ if ( factoryPid != null )
+ {
+ ungetService = removeMetaTypeProvider( factoryPid ) != null;
+ removeFactoryPid( factoryPid );
+ }
+ else
+ {
+ // 2. check for a service PID
+ String pid = ( String ) serviceRef.getProperty( Constants.SERVICE_PID );
+ if ( pid != null )
+ {
+ ungetService = removeMetaTypeProvider( pid ) != null;
+ removePid( pid );
+ }
+ }
+
+ // 3. drop the service reference
+ if ( ungetService )
+ {
+ bundleContext.ungetService( serviceRef );
+ }
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/l10n/BundleResources.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/l10n/BundleResources.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/l10n/BundleResources.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/l10n/BundleResources.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.felix.metatype.internal.l10n;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.osgi.framework.Bundle;
+
+
+/**
+ * The <code>BundleResources</code> TODO
+ *
+ * @author fmeschbe
+ * @version $Rev:$, $Date: 2007-04-11 20:27:12 +0200 (Wed, 11 Apr 2007) $
+ */
+public class BundleResources
+{
+
+ private Bundle bundle;
+ private long bundleLastModified;
+
+ private Map resourcesByLocale;
+
+ private static Map resourcesByBundle = null;
+
+
+ public static Resources getResources( Bundle bundle, String basename, String locale )
+ {
+ BundleResources bundleResources = null;
+
+ if ( resourcesByBundle != null )
+ {
+ // the bundle has been uninstalled, ensure removed from the cache
+ // and return null (e.g. no resources now)
+ if ( bundle.getState() == Bundle.UNINSTALLED )
+ {
+ resourcesByBundle.remove( new Long( bundle.getBundleId() ) );
+ return null;
+ }
+
+ // else check whether we know the bundle already
+ bundleResources = ( BundleResources ) resourcesByBundle.get( new Long( bundle.getBundleId() ) );
+ }
+ else
+ {
+ // create the cache to be used for a newly created BundleResources
+ resourcesByBundle = new HashMap();
+ }
+
+ if ( bundleResources == null )
+ {
+ bundleResources = new BundleResources( bundle );
+ resourcesByBundle.put( new Long( bundle.getBundleId() ), bundleResources );
+ }
+
+ return bundleResources.getResources( basename, locale );
+ }
+
+
+ public static void clearResourcesCache()
+ {
+ resourcesByBundle = null;
+ }
+
+
+ private BundleResources( Bundle bundle )
+ {
+ this.bundle = bundle;
+ this.bundleLastModified = bundle.getLastModified();
+ this.resourcesByLocale = new HashMap();
+ }
+
+
+ private boolean isUpToDate()
+ {
+ return bundle.getState() != Bundle.UNINSTALLED && bundleLastModified >= bundle.getLastModified();
+ }
+
+
+ private Resources getResources( String basename, String locale )
+ {
+ // ensure locale - use VM default locale if null
+ if ( locale == null )
+ {
+ locale = Locale.getDefault().toString();
+ }
+
+ // check the cache, if the bundle has not changed
+ if ( isUpToDate() )
+ {
+ Resources res = ( Resources ) resourcesByLocale.get( locale );
+ if ( res != null )
+ {
+ return res;
+ }
+ }
+ else
+ {
+ // otherwise clear the cache
+ resourcesByLocale.clear();
+ }
+
+ // get the list of potential resource names files
+ Properties parentProperties = null;
+ List resList = createResourceList( locale );
+ for ( Iterator ri = resList.iterator(); ri.hasNext(); )
+ {
+ String tmpLocale = ( String ) ri.next();
+ Resources res = ( Resources ) resourcesByLocale.get( tmpLocale );
+ if ( res != null )
+ {
+ parentProperties = res.getResources();
+ }
+ else
+ {
+ Properties props = loadProperties( basename, tmpLocale, parentProperties );
+ res = new Resources( tmpLocale, props );
+ resourcesByLocale.put( tmpLocale, res );
+ parentProperties = props;
+ }
+ }
+
+ // just return from the cache again
+ return ( Resources ) resourcesByLocale.get( locale );
+ }
+
+
+ private Properties loadProperties( String basename, String locale, Properties parentProperties )
+ {
+ String resourceName = basename;
+ if ( locale != null && locale.length() > 0 )
+ {
+ resourceName += "_" + locale;
+ }
+ resourceName += ".properties";
+
+ Properties props = new Properties( parentProperties );
+ URL resURL = bundle.getEntry( resourceName );
+ if ( resURL != null )
+ {
+ InputStream ins = null;
+ try
+ {
+ ins = resURL.openStream();
+ props.load( ins );
+ }
+ catch ( IOException ex )
+ {
+ // File doesn't exist, just continue loop
+ }
+ finally
+ {
+ if ( ins != null )
+ {
+ try
+ {
+ ins.close();
+ }
+ catch ( IOException ignore )
+ {
+ }
+ }
+ }
+ }
+
+ return props;
+ }
+
+
+ private List createResourceList( String locale )
+ {
+ List result = new ArrayList( 4 );
+
+ StringTokenizer tokens;
+ StringBuffer tempLocale = new StringBuffer();
+
+ result.add( tempLocale.toString() );
+
+ if ( locale != null && locale.length() > 0 )
+ {
+ tokens = new StringTokenizer( locale, "_" );
+ while ( tokens.hasMoreTokens() )
+ {
+ if ( tempLocale.length() > 0 )
+ {
+ tempLocale.append( "_" );
+ }
+ tempLocale.append( tokens.nextToken() );
+ result.add( tempLocale.toString() );
+ }
+ }
+ return result;
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/l10n/Resources.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/l10n/Resources.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/l10n/Resources.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/l10n/Resources.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.felix.metatype.internal.l10n;
+
+import java.util.Properties;
+
+/**
+ * The <code>Resources</code> TODO
+ *
+ * @author fmeschbe
+ */
+public class Resources
+{
+
+ private String locale;
+ private Properties resources;
+
+ Resources(String locale, Properties resources) {
+ this.locale = locale;
+ this.resources = resources;
+ }
+
+ public String getLocale() {
+ return locale;
+ }
+
+ Properties getResources() {
+ return resources;
+ }
+
+ public String getResource(String resourceName) {
+ return resources.getProperty( resourceName, resourceName );
+ }
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/bindex/Index.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/bindex/Index.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/bindex/Index.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/bindex/Index.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,308 @@
+/*
+ * $Id: Index.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.bindex;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.zip.CRC32;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.osgi.impl.bundle.obr.resource.BundleInfo;
+import org.osgi.impl.bundle.obr.resource.RepositoryImpl;
+import org.osgi.impl.bundle.obr.resource.ResourceImpl;
+import org.osgi.impl.bundle.obr.resource.Tag;
+
+/**
+ * Iterate over a set of given bundles and convert them to resources. When -a is
+ * specified, other resources than bundles will be included too. After
+ * this, convert an local urls (file systems, JAR file) to relative URLs and
+ * create a ZIP file with the complete content. This ZIP file can be used in an
+ * OSGi Framework to map to an http service or it can be expanded on the web
+ * server's file system.
+ *
+ * @version $Revision: 44 $
+ */
+public class Index {
+ static String repositoryFileName = "repository.xml";
+ static URL licenseURL = null;
+ static boolean quiet = false;
+ static String name = "Untitled";
+ static boolean all = false;
+ static String urlTemplate = null;
+ static File rootFile = new File("")
+ .getAbsoluteFile();
+ static RepositoryImpl repository;
+ static String root;
+
+ /**
+ * Main entry. See -help for options.
+ *
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String args[]) throws Exception {
+ System.err.println("Bundle Indexer | v2.2");
+ System.err.println("(c) 2007 OSGi, All Rights Reserved");
+
+ Set resources = new HashSet();
+ root = rootFile.toURL().toString();
+ repository = new RepositoryImpl(rootFile.toURL());
+
+ for (int i = 0; i < args.length; i++) {
+ try {
+ if (args[i].startsWith("-n")) {
+ name = args[++i];
+ }
+ else
+ if (args[i].startsWith("-r")) {
+ repositoryFileName = args[++i];
+ repository = new RepositoryImpl(new File(
+ repositoryFileName).getAbsoluteFile().toURL());
+ }
+ else
+ if (args[i].startsWith("-q")) {
+ quiet = true;
+ }
+ else
+ if (args[i].startsWith("-t")) {
+ urlTemplate = args[++i];
+ }
+ else
+ if (args[i].startsWith("-l")) {
+ licenseURL = new URL(new File("").toURL(),
+ args[++i]);
+ }
+ else
+ if (args[i].startsWith("-help")) {
+ System.err
+ .println("bindex [-t \"%s\" symbolic name \"%v\" version \"%f\" filename \"%p\" dirpath ] [ -r repository.(xml|zip) ] [-help] [-l file:license.html ] [-quiet] [-all] <jar file>*");
+ }
+ else
+ if (args[i].startsWith("-a")) {
+ all = true;
+ }
+ else {
+ recurse(resources, new File(args[i]));
+ }
+ }
+ catch (Exception e) {
+ System.err.println("Error in " + args[i] + " : " +
+ e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ List sorted = new ArrayList(resources);
+ Collections.sort(sorted, new Comparator() {
+ public int compare(Object r1, Object r2) {
+ String s1 = getName((ResourceImpl) r1);
+ String s2 = getName((ResourceImpl) r2);
+ return s1.compareTo(s2);
+ }
+ });
+
+ Tag tag = doIndex(sorted);
+ if (repositoryFileName != null) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,
+ "UTF-8"));
+
+ pw.println("<?xml version='1.0' encoding='utf-8'?>");
+ pw
+ .println("<?xml-stylesheet type='text/xsl' href='http://www2.osgi.org/www/obr2html.xsl'?>");
+
+ tag.print(0, pw);
+ pw.close();
+ byte buffer[] = out.toByteArray();
+ String name = "repository.xml";
+ FileOutputStream fout = new FileOutputStream(repositoryFileName);
+
+ if (repositoryFileName.endsWith(".zip")) {
+ ZipOutputStream zip = new ZipOutputStream(fout);
+ CRC32 checksum = new CRC32();
+ checksum.update(buffer);
+ ZipEntry ze = new ZipEntry(name);
+ ze.setSize(buffer.length);
+ ze.setCrc(checksum.getValue());
+ zip.putNextEntry(ze);
+ zip.write(buffer, 0, buffer.length);
+ zip.closeEntry();
+ zip.close();
+ }
+ else {
+ fout.write(buffer);
+ }
+ fout.close();
+ }
+
+ if (!quiet) {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
+ pw.println("<?xml version='1.0' encoding='utf-8'?>");
+ pw
+ .println("<?xml-stylesheet type='text/xsl' href='http://www2.osgi.org/www/obr2html.xsl'?>");
+ tag.print(0, pw);
+ pw.close();
+ }
+ }
+
+ static String getName(ResourceImpl impl) {
+ String s = impl.getSymbolicName();
+ if (s != null) {
+ return s;
+ }
+ else {
+ return "no-symbolic-name";
+ }
+ }
+
+ static void recurse(Set resources, File path) throws Exception {
+ if (path.isDirectory()) {
+ String list[] = path.list();
+ for (int i = 0; i < list.length; i++) {
+ recurse(resources, new File(path, list[i]));
+ }
+ }
+ else {
+ if (path.getName().equals("repository.xml") || path.getName().equals(new File(repositoryFileName).getName())) {
+ // do not index our repository.xml, nor the file we are working on now.
+ return;
+ }
+ if (path.getName().endsWith(".jar")) {
+ BundleInfo info = new BundleInfo(repository, path);
+ ResourceImpl resource = info.build();
+ if (urlTemplate != null) {
+ doTemplate(path, resource);
+ }
+ else {
+ resource.setURL(path.toURL());
+ }
+
+ resources.add(resource);
+ }
+ else {
+ // this is some other resource, we might want to include it.
+ if (all) {
+ resources.add(new ResourceImpl(repository, path.toURL()));
+ }
+ }
+ }
+ }
+
+ static void doTemplate(File path, ResourceImpl resource)
+ throws MalformedURLException {
+ String dir = path.getAbsoluteFile().getParentFile().getAbsoluteFile()
+ .toURL().toString();
+ if (dir.endsWith("/")) {
+ dir = dir.substring(0, dir.length() - 1);
+ }
+
+ if (dir.startsWith(root)) {
+ dir = dir.substring(root.length());
+ }
+
+ String url = urlTemplate.replaceAll("%v", "" + resource.getVersion());
+ url = url.replaceAll("%s", resource.getSymbolicName());
+ url = url.replaceAll("%f", path.getName());
+ url = url.replaceAll("%p", dir);
+ resource.setURL(new URL(url));
+ }
+
+ /**
+ * Create the repository index
+ *
+ * @param resources Set of resources
+ * @param collected The output zip file
+ * @throws IOException
+ */
+ static Tag doIndex(Collection resources) throws IOException {
+ Tag repository = new Tag("repository");
+ repository.addAttribute("lastmodified", new Date());
+ repository.addAttribute("name", name);
+
+ for (Iterator i = resources.iterator(); i.hasNext();) {
+ ResourceImpl resource = (ResourceImpl) i.next();
+ repository.addContent(resource.toXML());
+ }
+ return repository;
+ }
+
+ /**
+ * Add the resource to the ZIP file, calculating the CRC etc.
+ *
+ * @param zip The output ZIP file
+ * @param name The name of the resource
+ * @param actual The contents stream
+ * @throws IOException
+ */
+ static void addToZip(ZipOutputStream zip, String name, InputStream actual)
+ throws IOException {
+ byte buffer[];
+ buffer = readAll(actual, 0);
+ actual.close();
+ CRC32 checksum = new CRC32();
+ checksum.update(buffer);
+ ZipEntry ze = new ZipEntry(name);
+ ze.setSize(buffer.length);
+ ze.setCrc(checksum.getValue());
+ zip.putNextEntry(ze);
+ zip.write(buffer, 0, buffer.length);
+ zip.closeEntry();
+ }
+
+ /**
+ * Read a complete stream till EOF. This method will parse the input stream
+ * until a -1 is discovered.
+ *
+ * The method is recursive. It keeps on calling a higher level routine until
+ * EOF. Only then is the result buffer calculated.
+ */
+ static byte[] readAll(InputStream in, int offset) throws IOException {
+ byte temp[] = new byte[4096];
+ byte result[];
+ int size = in.read(temp, 0, temp.length);
+ if (size <= 0) {
+ return new byte[offset];
+ }
+ //
+ // We have a positive result, copy it
+ // to the right offset.
+ //
+ result = readAll(in, offset + size);
+ System.arraycopy(temp, 0, result, offset, size);
+ return result;
+ }
+
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/BundleInfo.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/BundleInfo.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/BundleInfo.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/BundleInfo.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,506 @@
+/*
+ * $Id: BundleInfo.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.URL;
+import java.util.*;
+import java.util.zip.*;
+
+import org.osgi.service.obr.Resource;
+
+/**
+ * Convert a bundle to a generic resource description and store its local
+ * dependencies (like for example a license file in the JAR) in a zip file.
+ *
+ * @version $Revision: 44 $
+ */
+public class BundleInfo {
+ Manifest manifest;
+ File bundleJar;
+ ZipFile jar;
+ String license;
+ Properties localization;
+ RepositoryImpl repository;
+
+ /**
+ * Parse a zipFile from the file system. We only need the manifest and the
+ * localization. So a zip file is used to minimze memory consumption.
+ *
+ * @param bundleJar Path name
+ * @throws Exception Any errors that occur
+ */
+ public BundleInfo(RepositoryImpl repository, File bundleJar) throws Exception {
+ this.bundleJar = bundleJar;
+ this.repository = repository;
+
+ if (!this.bundleJar.exists())
+ throw new FileNotFoundException(bundleJar.toString());
+
+ jar = new ZipFile(bundleJar);
+ ZipEntry entry = jar.getEntry("META-INF/MANIFEST.MF");
+ if (entry == null)
+ throw new FileNotFoundException("No Manifest in "
+ + bundleJar.toString());
+ manifest = new Manifest(jar.getInputStream(entry));
+ }
+
+ public BundleInfo(Manifest manifest) throws Exception {
+ this.manifest = manifest;
+ }
+
+ /**
+ * Convert the bundle to a Resource. All URIs are going to be abslute, but
+ * could be local.
+ *
+ * @return the resource
+ * @throws Exception
+ */
+ public ResourceImpl build() throws Exception {
+ ResourceImpl resource;
+ // Setup the manifest
+ // and create a resource
+ resource = new ResourceImpl(repository, manifest.getSymbolicName(), manifest
+ .getVersion());
+
+ try {
+
+ // Calculate the location URL of the JAR
+ URL location = new URL("jar:" + bundleJar.toURL().toString() + "!/");
+ resource.setURL(bundleJar.toURL());
+ resource.setFile(bundleJar);
+
+ doReferences(resource, location);
+ doSize(resource);
+ doCategories(resource);
+ doImportExportServices(resource);
+ doDeclarativeServices(resource);
+ doFragment(resource);
+ doRequires(resource);
+ doBundle(resource);
+ doExports(resource);
+ doImports(resource);
+ doExecutionEnvironment(resource);
+
+ return resource;
+ }
+ finally {
+ try {
+ jar.close();
+ }
+ catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Check the size and add it.
+ *
+ * @param resource
+ */
+ void doSize(ResourceImpl resource) {
+ long size = bundleJar.length();
+ if (size > 0)
+ resource.setSize(size);
+ }
+
+ /**
+ * Find the categories, break them up and add them.
+ *
+ * @param resource
+ */
+ void doCategories(ResourceImpl resource) {
+ for (int i = 0; i < manifest.getCategories().length; i++) {
+ String category = manifest.getCategories()[i];
+ resource.addCategory(category);
+ }
+ }
+
+ void doReferences(ResourceImpl resource, URL location) {
+ // Presentation name
+ String name = translated("Bundle-Name");
+ if (name != null)
+ resource.setPresentationName(name);
+
+ // Handle license. -l allows a global license
+ // set when no license is included.
+
+ String license = translated("Bundle-License");
+ if (license != null)
+ resource.setLicense(toURL(location, license));
+ else if (this.license != null)
+ resource.setLicense(toURL(location, this.license));
+
+ String description = translated("Bundle-Description");
+ if (description != null)
+ resource.setDescription(description);
+
+ String copyright = translated("Bundle-Copyright");
+ if (copyright != null)
+ resource.setCopyright(copyright);
+
+ String documentation = translated("Bundle-DocURL");
+ if (documentation != null)
+ resource.setDocumentation(toURL(location, documentation));
+
+ String source = manifest.getValue("Bundle-Source");
+ if (source != null)
+ resource.setSource(toURL(location, source));
+ }
+
+ URL toURL(URL location, String source) {
+ try {
+ return new URL(location, source);
+ }
+ catch (Exception e) {
+ System.err.println("Error in converting url: " + location + " : "
+ + source);
+ return null;
+ }
+ }
+
+ void doDeclarativeServices(ResourceImpl resource) throws Exception {
+ String serviceComponent = manifest.getValue("service-component");
+ if (serviceComponent == null)
+ return;
+
+ StringTokenizer st = new StringTokenizer(serviceComponent, " ,\t");
+ String parts[] = new String[st.countTokens()];
+ for (int i = 0; i < parts.length; i++)
+ parts[i] = st.nextToken();
+
+ for (int i = 0; i < parts.length; i++) {
+ ZipEntry entry = jar.getEntry(parts[i]);
+ if (entry == null) {
+ System.err.println("Bad Service-Component header: "
+ + serviceComponent + ", no such file " + parts[i]);
+ }
+ InputStream in = jar.getInputStream(entry);
+ // TODO parse declarative services files.
+ in.close();
+ }
+ }
+
+ void doImportExportServices(ResourceImpl resource) throws IOException {
+ String importServices = manifest.getValue("import-service");
+ if (importServices != null) {
+ List entries = manifest.getEntries(importServices);
+ for (Iterator i = entries.iterator(); i.hasNext();) {
+ ManifestEntry entry = (ManifestEntry) i.next();
+ RequirementImpl ri = new RequirementImpl("service");
+ ri.setFilter(createServiceFilter(entry));
+ ri.setComment("Import Service " + entry.getName());
+
+ // TODO the following is arbitrary
+ ri.setOptional(false);
+ ri.setMultiple(true);
+ resource.addRequirement(ri);
+ }
+ }
+
+ String exportServices = manifest.getValue("export-service");
+ if (exportServices != null) {
+ List entries = manifest.getEntries(exportServices);
+ for (Iterator i = entries.iterator(); i.hasNext();) {
+ ManifestEntry entry = (ManifestEntry) i.next();
+ CapabilityImpl cap = createServiceCapability(entry);
+ resource.addCapability(cap);
+ }
+ }
+ }
+
+ String translated(String key) {
+ return translate(manifest.getValue(key));
+ }
+
+ void doFragment(ResourceImpl resource) {
+ // Check if we are a fragment
+ ManifestEntry entry = manifest.getHost();
+ if (entry == null) {
+ return;
+ }
+ else {
+ // We are a fragment, create a requirement
+ // to our host.
+ RequirementImpl r = new RequirementImpl("bundle");
+ StringBuffer sb = new StringBuffer();
+ sb.append("(&(symbolicname=");
+ sb.append(entry.getName());
+ sb.append(")(version>=");
+ sb.append(entry.getVersion());
+ sb.append("))");
+ r.setFilter(sb.toString());
+ r.setComment("Required Host " + entry.getName() );
+ r.setExtend(true);
+ r.setOptional(false);
+ r.setMultiple(false);
+ resource.addRequirement(r);
+
+ // And insert a capability that we are available
+ // as a fragment. ### Do we need that with extend?
+ CapabilityImpl capability = new CapabilityImpl("fragment");
+ capability.addProperty("host", entry.getName());
+ capability.addProperty("version", entry.getVersion());
+ resource.addCapability(capability);
+ }
+ }
+
+ void doRequires(ResourceImpl resource) {
+ List entries = manifest.getRequire();
+ if (entries == null)
+ return;
+
+ for (Iterator i = entries.iterator(); i.hasNext();) {
+ ManifestEntry entry = (ManifestEntry) i.next();
+ RequirementImpl r = new RequirementImpl("bundle");
+
+ StringBuffer sb = new StringBuffer();
+ sb.append("(&(symbolicname=");
+ sb.append(entry.getName());
+ sb.append(")(version>=");
+ sb.append(entry.getVersion());
+ sb.append("))");
+ r.setFilter(sb.toString());
+ r.setComment("Require Bundle " + entry.getName() + "; "
+ + entry.getVersion());
+ if (entry.directives == null
+ || "true".equalsIgnoreCase((String) entry.directives
+ .get("resolution")))
+ r.setOptional(false);
+ else
+ r.setOptional(true);
+ resource.addRequirement(r);
+ }
+ }
+
+ void doExecutionEnvironment(ResourceImpl resource) {
+ String[] parts = manifest.getRequiredExecutionEnvironments();
+ if (parts == null)
+ return;
+
+ StringBuffer sb = new StringBuffer();
+ sb.append("(|");
+ for (int i = 0; i < parts.length; i++) {
+ String part = parts[i];
+ sb.append("(ee=");
+ sb.append(part);
+ sb.append(")");
+ }
+ sb.append(")");
+
+ RequirementImpl req = new RequirementImpl("ee");
+ req.setFilter(sb.toString());
+ req.setComment("Execution Environment " + sb.toString());
+ resource.addRequirement(req);
+ }
+
+ void doImports(ResourceImpl resource) {
+ List requirements = new ArrayList();
+ List packages = manifest.getImports();
+ if (packages == null)
+ return;
+
+ for (Iterator i = packages.iterator(); i.hasNext();) {
+ ManifestEntry pack = (ManifestEntry) i.next();
+ RequirementImpl requirement = new RequirementImpl("package");
+
+ createImportFilter(requirement, "package", pack);
+ requirement.setComment("Import package " + pack);
+ requirements.add(requirement);
+ }
+ for (Iterator i = requirements.iterator(); i.hasNext();)
+ resource.addRequirement((RequirementImpl) i.next());
+ }
+
+ String createServiceFilter(ManifestEntry pack) {
+ StringBuffer filter = new StringBuffer();
+ filter.append("(service=");
+ filter.append(pack.getName());
+ filter.append(")");
+ return filter.toString();
+ }
+
+ void createImportFilter(RequirementImpl req, String name, ManifestEntry pack) {
+ StringBuffer filter = new StringBuffer();
+ filter.append("(&(");
+ filter.append(name);
+ filter.append("=");
+ filter.append(pack.getName());
+ filter.append(")");
+ VersionRange version = pack.getVersion();
+ if (version != null) {
+ if ( version.isRange() ) {
+ filter.append("(version");
+ filter.append(">");
+ if (version.includeLow())
+ filter.append("=");
+ filter.append(version.low);
+ filter.append(")");
+
+ filter.append("(version");
+ filter.append("<");
+ if (version.includeHigh())
+ filter.append("=");
+ filter.append(version.high);
+ filter.append(")");
+ }
+ else {
+ filter.append("(version>=");
+ filter.append(pack.getVersion());
+ filter.append(")");
+ }
+ }
+ Map attributes = pack.getAttributes();
+ Set attrs = doImportPackageAttributes(req, filter, attributes);
+ if (attrs.size() > 0) {
+ String del = "";
+ filter.append("(mandatory:<*");
+ for (Iterator i = attrs.iterator(); i.hasNext();) {
+ filter.append(del);
+ filter.append(i.next());
+ del = ", ";
+ }
+ filter.append(")");
+ }
+ filter.append(")");
+ req.setFilter(filter.toString());
+ }
+
+ Set doImportPackageAttributes(RequirementImpl req, StringBuffer filter,
+ Map attributes) {
+ HashSet set = new HashSet();
+
+ if (attributes != null)
+ for (Iterator i = attributes.keySet().iterator(); i.hasNext();) {
+ String attribute = (String) i.next();
+ String value = (String) attributes.get(attribute);
+ if (attribute.equalsIgnoreCase("specification-version")
+ || attribute.equalsIgnoreCase("version"))
+ continue;
+ else if (attribute.equalsIgnoreCase("resolution:")) {
+ req.setOptional(value.equalsIgnoreCase("optional"));
+ }
+ if (attribute.endsWith(":")) {
+ // Ignore
+ }
+ else {
+ filter.append("(");
+ filter.append(attribute);
+ filter.append("=");
+ filter.append(attributes.get(attribute));
+ filter.append(")");
+ set.add(attribute);
+ }
+ }
+ return set;
+ }
+
+ void doBundle(ResourceImpl resource) {
+ CapabilityImpl capability = new CapabilityImpl("bundle");
+ capability.addProperty("symbolicname", manifest.getSymbolicName());
+ if (manifest.getValue("Bundle-Name") != null)
+ capability.addProperty(
+ Resource.PRESENTATION_NAME,
+ translated("Bundle-Name"));
+ capability.addProperty("version", manifest.getVersion());
+ capability
+ .addProperty("manifestversion", manifest.getManifestVersion());
+
+ /**
+ * Is this needed TODO
+ */
+ ManifestEntry host = manifest.getHost();
+ if (host != null) {
+ capability.addProperty("host", host.getName());
+ if (host.getVersion() != null)
+ capability.addProperty("version", host.getVersion());
+ }
+ resource.addCapability(capability);
+ }
+
+ void doExports(ResourceImpl resource) {
+ List capabilities = new ArrayList();
+ List packages = manifest.getExports();
+ if (packages != null) {
+ for (Iterator i = packages.iterator(); i.hasNext();) {
+ ManifestEntry pack = (ManifestEntry) i.next();
+ CapabilityImpl capability = createCapability("package", pack);
+ capabilities.add(capability);
+ }
+ }
+ for (Iterator i = capabilities.iterator(); i.hasNext();)
+ resource.addCapability((CapabilityImpl) i.next());
+ }
+
+ CapabilityImpl createServiceCapability(ManifestEntry pack) {
+ CapabilityImpl capability = new CapabilityImpl("service");
+ capability.addProperty("service", pack.getName());
+ return capability;
+ }
+
+ CapabilityImpl createCapability(String name, ManifestEntry pack) {
+ CapabilityImpl capability = new CapabilityImpl(name);
+ capability.addProperty(name, pack.getName());
+ capability.addProperty("version", pack.getVersion());
+ Map attributes = pack.getAttributes();
+ if (attributes != null)
+ for (Iterator at = attributes.keySet().iterator(); at.hasNext();) {
+ String key = (String) at.next();
+ if (key.equalsIgnoreCase("specification-version")
+ || key.equalsIgnoreCase("version"))
+ continue;
+ else {
+ Object value = attributes.get(key);
+ capability.addProperty(key, value);
+ }
+ }
+ return capability;
+ }
+
+ String translate(String s) {
+ if (s == null)
+ return null;
+
+ if (!s.startsWith("%")) {
+ return s;
+ }
+
+ if (localization == null)
+ try {
+ localization = new Properties();
+ String path = manifest
+ .getValue("Bundle-Localization", "bundle");
+ path += ".properties";
+ InputStream in = jar.getInputStream(new ZipEntry(path));
+ if (in != null) {
+ localization.load(in);
+ in.close();
+ }
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ s = s.substring(1);
+ return localization.getProperty(s, s);
+ }
+
+ File getZipFile() {
+ return bundleJar;
+ }
+}
\ No newline at end of file
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/CapabilityImpl.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/CapabilityImpl.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/CapabilityImpl.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/CapabilityImpl.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,109 @@
+/*
+ * $Id: CapabilityImpl.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.*;
+
+import org.osgi.service.obr.Capability;
+import org.xmlpull.v1.XmlPullParser;
+
+
+
+public class CapabilityImpl implements Capability {
+ String name;
+ Map properties = new TreeMap();
+
+ public CapabilityImpl(String name) {
+ this.name = name;
+ }
+
+ public CapabilityImpl(XmlPullParser parser) throws Exception {
+ parser.require(XmlPullParser.START_TAG, null, "capability");
+ name = parser.getAttributeValue(null,"name");
+ while ( parser.nextTag() == XmlPullParser.START_TAG ) {
+ if ( parser.getName().equals("p")) {
+ String name = parser.getAttributeValue(null,"n");
+ String value = parser.getAttributeValue(null,"v");
+ String type = parser.getAttributeValue(null,"t");
+ Object v = value;
+
+ if ( "nummeric".equals(type))
+ v = new Long(value);
+ else if ( "version".equals(type))
+ v = new VersionRange(value);
+ addProperty(name,v);
+ }
+ parser.next();
+ parser.require(XmlPullParser.END_TAG, null, "p" );
+ }
+ parser.require(XmlPullParser.END_TAG, null, "capability" );
+ }
+
+
+ public void addProperty(String key, Object value) {
+ List values = (List) properties.get(key);
+ if (values == null) {
+ values = new ArrayList();
+ properties.put(key, values);
+ }
+ values.add(value);
+ }
+
+ public Tag toXML() {
+ return toXML(this);
+ }
+
+ public static Tag toXML(Capability capability) {
+ Tag tag = new Tag("capability");
+ tag.addAttribute("name", capability.getName());
+ Map properties = capability.getProperties();
+ for ( Iterator k= properties.keySet().iterator(); k.hasNext(); ) {
+ String key = (String) k.next();
+ List values = (List) properties.get(key);
+ for ( Iterator v = values.iterator(); v.hasNext(); ) {
+ Object value = v.next();
+ Tag p = new Tag("p");
+ tag.addContent(p);
+ p.addAttribute("n", key);
+ if ( value != null )
+ p.addAttribute("v", value.toString());
+ else
+ System.out.println("Missing value " + key);
+ String type = null;
+ if (value instanceof Number )
+ type = "number";
+ else if (value.getClass() == VersionRange.class)
+ type = "version";
+ if (type != null)
+ p.addAttribute("t", type);
+ }
+ }
+ return tag;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+
+ public Map getProperties() {
+ return properties;
+ }
+
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/FilterImpl.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/FilterImpl.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/FilterImpl.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/FilterImpl.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,480 @@
+/*
+ * $Id: FilterImpl.java 44 2007-07-13 20:49:41Z hargrave@us.ibm.com $
+ *
+ * Copyright (c) 2000 Gatespace AB. All Rights Reserved.
+ * 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.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+public class FilterImpl {
+ final char WILDCARD = 65535;
+
+ final int EQ = 0;
+ final int LE = 1;
+ final int GE = 2;
+ final int APPROX = 3;
+ final int LESS = 4;
+ final int GREATER = 5;
+ final int SUBSET = 6;
+ final int SUPERSET = 7;
+
+ private String filter;
+
+ abstract class Query {
+ static final String GARBAGE = "Trailing garbage";
+ static final String MALFORMED = "Malformed query";
+ static final String EMPTY = "Empty list";
+ static final String SUBEXPR = "No subexpression";
+ static final String OPERATOR = "Undefined operator";
+ static final String TRUNCATED = "Truncated expression";
+ static final String EQUALITY = "Only equality supported";
+
+ private String tail;
+
+ boolean match() throws IllegalArgumentException {
+ tail = filter;
+ boolean val = doQuery();
+ if (tail.length() > 0) {
+ error(GARBAGE);
+ }
+ return val;
+ }
+
+ private boolean doQuery() throws IllegalArgumentException {
+ if ((tail.length() < 3) || !prefix("(")) {
+ error(MALFORMED);
+ }
+ boolean val;
+
+ switch (tail.charAt(0)) {
+ case '&' :
+ val = doAnd();
+ break;
+ case '|' :
+ val = doOr();
+ break;
+ case '!' :
+ val = doNot();
+ break;
+ default :
+ val = doSimple();
+ break;
+ }
+
+ if (!prefix(")")) {
+ error(MALFORMED);
+ }
+ return val;
+ }
+
+ private boolean doAnd() throws IllegalArgumentException {
+ tail = tail.substring(1);
+ boolean val = true;
+ if (!tail.startsWith("(")) {
+ error(EMPTY);
+ }
+ do {
+ if (!doQuery()) {
+ val = false;
+ }
+ } while (tail.startsWith("("));
+ return val;
+ }
+
+ private boolean doOr() throws IllegalArgumentException {
+ tail = tail.substring(1);
+ boolean val = false;
+ if (!tail.startsWith("(")) {
+ error(EMPTY);
+ }
+ do {
+ if (doQuery()) {
+ val = true;
+ }
+ } while (tail.startsWith("("));
+ return val;
+ }
+
+ private boolean doNot() throws IllegalArgumentException {
+ tail = tail.substring(1);
+ if (!tail.startsWith("(")) {
+ error(SUBEXPR);
+ }
+ return !doQuery();
+ }
+
+ private boolean doSimple() throws IllegalArgumentException {
+ int op = 0;
+ Object attr = getAttr();
+
+ if (prefix("=")) {
+ op = EQ;
+ }
+ else if (prefix("<=")) {
+ op = LE;
+ }
+ else if (prefix(">=")) {
+ op = GE;
+ }
+ else if (prefix("~=")) {
+ op = APPROX;
+ }
+ else if (prefix("*>")) {
+ op = SUPERSET;
+ }
+ else if (prefix("<*")) {
+ op = SUBSET;
+ }
+ else if (prefix("<")) {
+ op = LESS;
+ }
+ else if (prefix(">")) {
+ op = GREATER;
+ }
+ else {
+ error(OPERATOR);
+ }
+
+ return compare(attr, op, getValue());
+ }
+
+ private boolean prefix(String pre) {
+ if (!tail.startsWith(pre)) {
+ return false;
+ }
+ tail = tail.substring(pre.length());
+ return true;
+ }
+
+ private Object getAttr() {
+ int len = tail.length();
+ int ix = 0;
+ label: for (; ix < len; ix++) {
+ switch (tail.charAt(ix)) {
+ case '(' :
+ case ')' :
+ case '<' :
+ case '>' :
+ case '=' :
+ case '~' :
+ case '*' :
+ case '}' :
+ case '{' :
+ case '\\' :
+ break label;
+ }
+ }
+ String attr = tail.substring(0, ix).toLowerCase();
+ tail = tail.substring(ix);
+ return getProp(attr);
+ }
+
+ abstract Object getProp(String key);
+
+ private String getValue() {
+ StringBuffer sb = new StringBuffer();
+ int len = tail.length();
+ int ix = 0;
+ label: for (; ix < len; ix++) {
+ char c = tail.charAt(ix);
+ switch (c) {
+ case '(' :
+ case ')' :
+ break label;
+ case '*' :
+ sb.append(WILDCARD);
+ break;
+ case '\\' :
+ if (ix == len - 1) {
+ break label;
+ }
+ sb.append(tail.charAt(++ix));
+ break;
+ default :
+ sb.append(c);
+ break;
+ }
+ }
+ tail = tail.substring(ix);
+ return sb.toString();
+ }
+
+ private void error(String m) throws IllegalArgumentException {
+ throw new IllegalArgumentException(m + " " + tail);
+ }
+
+ private boolean compare(Object obj, int op, String s) {
+ if (obj == null) {
+ // No value is ok for a subset
+ if (op == SUBSET) {
+ return true;
+ }
+
+ // No value is ok for a superset when the value is
+ // empty
+ if (op == SUPERSET) {
+ return s.trim().length() == 0;
+ }
+
+ return false;
+ }
+ try {
+ Class numClass = obj.getClass();
+ if (numClass == String.class) {
+ return compareString((String) obj, op, s);
+ }
+ else if (numClass == Character.class) {
+ return compareString(obj.toString(), op, s);
+ }
+ else if (numClass == Long.class) {
+ return compareSign(op, Long.valueOf(s)
+ .compareTo((Long) obj));
+ }
+ else if (numClass == Integer.class) {
+ return compareSign(op, Integer.valueOf(s).compareTo(
+ (Integer) obj));
+ }
+ else if (numClass == Short.class) {
+ return compareSign(op, Short.valueOf(s).compareTo(
+ (Short) obj));
+ }
+ else if (numClass == Byte.class) {
+ return compareSign(op, Byte.valueOf(s)
+ .compareTo((Byte) obj));
+ }
+ else if (numClass == Double.class) {
+ return compareSign(op, Double.valueOf(s).compareTo(
+ (Double) obj));
+ }
+ else if (numClass == Float.class) {
+ return compareSign(op, Float.valueOf(s).compareTo(
+ (Float) obj));
+ }
+ else if (numClass == Boolean.class) {
+ if (op != EQ) {
+ return false;
+ }
+ int a = Boolean.valueOf(s).booleanValue() ? 1 : 0;
+ int b = ((Boolean) obj).booleanValue() ? 1 : 0;
+ return compareSign(op, a - b);
+ }
+ else if (numClass == BigInteger.class) {
+ return compareSign(op, new BigInteger(s)
+ .compareTo((BigInteger) obj));
+ }
+ else if (obj instanceof Collection) {
+ if ((op == SUBSET) || (op == SUPERSET)) {
+ StringSet set = new StringSet(s);
+ if (op == SUBSET) {
+ return set.containsAll((Collection) obj);
+ }
+ else {
+ return ((Collection) obj).containsAll(set);
+ }
+ }
+
+ for (Iterator i = ((Collection) obj).iterator(); i
+ .hasNext();) {
+ Object element = i.next();
+ if (compare(element, op, s)) {
+ return true;
+ }
+ }
+ }
+ else if (numClass.isArray()) {
+ int len = Array.getLength(obj);
+ for (int i = 0; i < len; i++) {
+ if (compare(Array.get(obj, i), op, s)) {
+ return true;
+ }
+ }
+ }
+ else {
+ try {
+ if ((op == SUPERSET) || (op == SUBSET)) {
+ StringSet set = new StringSet(s);
+ if (op == SUPERSET) {
+ return set.contains(obj);
+ }
+ else {
+ return (set.size() == 0)
+ || ((set.size() == 1) && set.iterator()
+ .next().equals(obj));
+ }
+ }
+ else {
+ Constructor constructor = numClass
+ .getConstructor(new Class[] {String.class});
+ Object instance = constructor
+ .newInstance(new Object[] {s});
+ switch (op) {
+ case EQ :
+ return obj.equals(instance);
+ case LESS :
+ return ((Comparable) obj)
+ .compareTo(instance) < 0;
+ case GREATER :
+ return ((Comparable) obj)
+ .compareTo(instance) > 0;
+ case LE :
+ return ((Comparable) obj)
+ .compareTo(instance) <= 0;
+ case GE :
+ return ((Comparable) obj)
+ .compareTo(instance) >= 0;
+ }
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ // Ignore
+ }
+ }
+ }
+ catch (Exception e) {
+ }
+ return false;
+ }
+ }
+
+ class DictQuery extends Query {
+ private Map dict;
+
+ DictQuery(Map dict) {
+ this.dict = dict;
+ }
+
+ @Override
+ Object getProp(String key) {
+ return dict.get(key);
+ }
+ }
+
+ public FilterImpl(String filter) throws IllegalArgumentException {
+ // NYI: Normalize the filter string?
+ this.filter = filter;
+ if ((filter == null) || (filter.length() == 0)) {
+ throw new IllegalArgumentException("Null query");
+ }
+ }
+
+ public boolean match(Map dict) {
+ try {
+ return new DictQuery(dict).match();
+ }
+ catch (IllegalArgumentException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return filter;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj != null) && (obj instanceof FilterImpl)
+ && filter.equals(((FilterImpl) obj).filter);
+ }
+
+ @Override
+ public int hashCode() {
+ return filter.hashCode();
+ }
+
+ boolean compareString(String s1, int op, String s2) {
+ switch (op) {
+ case EQ :
+ return patSubstr(s1, s2);
+ case APPROX :
+ return patSubstr(fixupString(s1), fixupString(s2));
+ default :
+ return compareSign(op, s2.compareTo(s1));
+ }
+ }
+
+ boolean compareSign(int op, int cmp) {
+ switch (op) {
+ case LE :
+ return cmp >= 0;
+ case GE :
+ return cmp <= 0;
+ case EQ :
+ return cmp == 0;
+ default : /* APPROX */
+ return cmp == 0;
+ }
+ }
+
+ String fixupString(String s) {
+ StringBuffer sb = new StringBuffer();
+ int len = s.length();
+ boolean isStart = true;
+ boolean isWhite = false;
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (Character.isWhitespace(c)) {
+ isWhite = true;
+ }
+ else {
+ if (!isStart && isWhite) {
+ sb.append(' ');
+ }
+ if (Character.isUpperCase(c)) {
+ c = Character.toLowerCase(c);
+ }
+ sb.append(c);
+ isStart = false;
+ isWhite = false;
+ }
+ }
+ return sb.toString();
+ }
+
+ boolean patSubstr(String s, String pat) {
+ if (s == null) {
+ return false;
+ }
+ if (pat.length() == 0) {
+ return s.length() == 0;
+ }
+ if (pat.charAt(0) == WILDCARD) {
+ pat = pat.substring(1);
+ for (;;) {
+ if (patSubstr(s, pat)) {
+ return true;
+ }
+ if (s.length() == 0) {
+ return false;
+ }
+ s = s.substring(1);
+ }
+ }
+ else {
+ if ((s.length() == 0) || (s.charAt(0) != pat.charAt(0))) {
+ return false;
+ }
+ return patSubstr(s.substring(1), pat.substring(1));
+ }
+ }
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Manifest.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Manifest.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Manifest.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Manifest.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,402 @@
+/*
+ * $Id: Manifest.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.util.*;
+
+
+public class Manifest extends Hashtable {
+ static final long serialVersionUID = 1L;
+ List imports;
+ List exports;
+ ManifestEntry name;
+ String activator;
+ String classpath[] = new String[] {"."};
+ int section;
+ String location;
+ Native _native[];
+ Vector duplicates = new Vector();
+ final static String wordparts = "~!@#$%^&*_:/?><.-+";
+ ManifestEntry bsn;
+ VersionRange version;
+ ManifestEntry host;
+ List require;
+
+ public Manifest(InputStream in) throws IOException {
+ parse(new InputStreamReader(in, "UTF8"));
+ }
+
+ public Manifest(Reader in) throws IOException {
+ parse(in);
+ }
+
+ @Override
+ public Object put(Object header, Object value) {
+ if (containsKey(header)) {
+ if (!((String) header).equalsIgnoreCase("comment"))
+ duplicates.add(header + ":" + value);
+ }
+ return super.put(header, value);
+ }
+
+ void parse(Reader in) throws IOException {
+ BufferedReader rdr = new BufferedReader(in);
+ String current = " ";
+ String buffer = rdr.readLine();
+ int section = 0;
+ if (buffer != null && !buffer.startsWith("Manifest-Version")) {
+ System.err
+ .println("The first line of a manifest file must be the Manifest-Version attribute");
+ throw new IOException(
+ "The first line of a manifest file must be the Manifest-Version attribute");
+ }
+ while (buffer != null && current != null && section == 0) {
+ if (current.startsWith(" ")) {
+ buffer += current.substring(1);
+ }
+ else {
+ section += entry(buffer);
+ buffer = current;
+ }
+ current = rdr.readLine();
+ }
+ entry(buffer);
+ }
+
+ int entry(String line) throws IOException {
+ if (line.length() < 2)
+ return 1;
+ int colon = line.indexOf(':');
+ if (colon < 1) {
+ error("Invalid header '" + line + "'");
+ }
+ else {
+ String header = line.substring(0, colon).toLowerCase();
+ String alphanum = "abcdefghijklmnopqrstuvwxyz0123456789";
+ String set = alphanum;
+ if (alphanum.indexOf(header.charAt(0)) < 0)
+ error("Header does not start with alphanum: " + header);
+ for (int i = 0; i < header.length(); i++) {
+ if (set.indexOf(header.charAt(i)) < 0)
+ error("Header contains non alphanum, - _: " + header);
+ set = "_-" + alphanum;
+ }
+ String value = "";
+ if (colon + 2 < line.length())
+ value = line.substring(colon + 2);
+ else
+ error("No value for manifest header " + header);
+ if (section == 0) {
+ if (header.equals("bundle-symbolicname")) {
+ bsn = (ManifestEntry) getEntries(value).get(0);
+ }
+ if (header.equals("bundle-version")) {
+ try {
+ version = new VersionRange(value.trim());
+ }
+ catch (Exception e) {
+ version = new VersionRange("0");
+ System.err.println("Invalid version attr for: " + bsn
+ + " value is " + value);
+ }
+ }
+ if (header.equals("fragment-host"))
+ host = (ManifestEntry) getEntries(value).get(0);
+ if (header.equals("require-bundle"))
+ require = getEntries(value);
+ if (header.equals("import-package"))
+ imports = getEntries(value);
+ else if (header.equals("export-package"))
+ exports = getEntries(value);
+ else if (header.equals("bundle-activator"))
+ activator = value.trim();
+ else if (header.equals("bundle-updatelocation"))
+ location = value.trim();
+ else if (header.equals("bundle-classpath"))
+ classpath = getClasspath(value);
+ else if (header.equals("bundle-nativecode"))
+ _native = getNative(value);
+ put(header, value);
+ }
+ }
+ return 0;
+ }
+
+ void error(String msg) throws IOException {
+ System.err.println("Reading manifest: " + msg);
+ }
+
+ void warning(String msg) throws IOException {
+ System.err.println("Reading manifest: " + msg);
+ }
+
+ StreamTokenizer getStreamTokenizer(String line) {
+ StreamTokenizer st = new StreamTokenizer(new StringReader(line));
+ st.resetSyntax();
+ st.wordChars('a', 'z');
+ st.wordChars('A', 'Z');
+ st.wordChars('0', '9');
+ st.whitespaceChars(0, ' ');
+ st.quoteChar('"');
+ for (int i = 0; i < wordparts.length(); i++)
+ st.wordChars(wordparts.charAt(i), wordparts.charAt(i));
+ return st;
+ }
+
+ String word(StreamTokenizer st) throws IOException {
+ switch (st.nextToken()) {
+ case '"' :
+ case StreamTokenizer.TT_WORD :
+ String result = st.sval;
+ st.nextToken();
+ return result;
+ }
+ return null;
+ }
+
+ Parameter getParameter(StreamTokenizer st) throws IOException {
+
+ Parameter parameter = new Parameter();
+ parameter.key = word(st);
+ if (st.ttype == ':') {
+ st.nextToken();
+ parameter.type = Parameter.DIRECTIVE;
+ }
+ else {
+ parameter.type = Parameter.ATTRIBUTE;
+ }
+
+ if (st.ttype == '=') {
+ parameter.value = word(st);
+ while (st.ttype == StreamTokenizer.TT_WORD || st.ttype == '"') {
+ parameter.value += " " + st.sval;
+ st.nextToken();
+ }
+ }
+
+ return parameter;
+ }
+
+ public List getEntries(String line) throws IOException {
+ List v = new Vector();
+ Set aliases = new HashSet();
+
+ StreamTokenizer st = getStreamTokenizer(line);
+ do {
+ Parameter parameter = getParameter(st);
+ ManifestEntry p = new ManifestEntry(parameter.key);
+ while (st.ttype == ';') {
+ parameter = getParameter(st);
+ if (parameter.value == null) {
+ aliases.add(parameter.key);
+ }
+ else {
+ if (parameter.type == Parameter.ATTRIBUTE)
+ p.addParameter(parameter);
+ else
+ p.addParameter(parameter);
+ }
+ }
+ v.add(p);
+ for (Iterator a = aliases.iterator(); a.hasNext();) {
+ v.add(p.getAlias((String) a.next()));
+ }
+ } while (st.ttype == ',');
+ return v;
+ }
+
+ Native[] getNative(String line) throws IOException {
+ Vector v = new Vector();
+ StreamTokenizer st = getStreamTokenizer(line);
+ do {
+ Native spec = new Native();
+ Vector names = new Vector();
+ do {
+ Parameter parameter = getParameter(st);
+ if (parameter.value == null)
+ names.add(parameter.key);
+ else if (parameter.is("processor", Parameter.ATTRIBUTE))
+ spec.processor = parameter.value;
+ else if (parameter.is("osname", Parameter.ATTRIBUTE))
+ spec.osname = parameter.value;
+ else if (parameter.is("osversion", Parameter.ATTRIBUTE))
+ spec.osversion = parameter.value;
+ else if (parameter.is("language", Parameter.ATTRIBUTE))
+ spec.language = parameter.value;
+ else if (parameter.is("selection-filter", Parameter.DIRECTIVE))
+ spec.filter = parameter.value;
+ else
+ warning("Unknown parameter for native code : " + parameter);
+ } while (st.ttype == ';');
+ spec.paths = new String[names.size()];
+ names.copyInto(spec.paths);
+ v.add(spec);
+ } while (st.ttype == ',');
+ Native[] result = new Native[v.size()];
+ v.copyInto(result);
+ return result;
+ }
+
+ String[] getClasspath(String line) throws IOException {
+ StringTokenizer st = new StringTokenizer(line, " \t,");
+ String result[] = new String[st.countTokens()];
+ for (int i = 0; i < result.length; i++)
+ result[i] = st.nextToken();
+ return result;
+ }
+
+ public List getImports() {
+ return imports;
+ }
+
+ public List getExports() {
+ return exports;
+ }
+
+ public String getActivator() {
+ return activator;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public String[] getClasspath() {
+ return classpath;
+ }
+
+ public Native[] getNative() {
+ return _native;
+ }
+
+ @Override
+ public Object get(Object key) {
+ if (key instanceof String)
+ return super.get(((String) key).toLowerCase());
+ else
+ return null;
+ }
+
+ public String getValue(String key) {
+ return (String) super.get(key.toLowerCase());
+ }
+
+ public String getValue(String key, String deflt) {
+ String s = getValue(key);
+ if (s == null)
+ return deflt;
+ else
+ return s;
+ }
+
+ public String[] getRequiredExecutionEnvironments() {
+ String ees = getValue("Bundle-RequiredExecutionEnvironment");
+ if (ees != null)
+ return ees.trim().split("\\s*,\\s*");
+ else
+ return null;
+ }
+
+ public VersionRange getVersion() {
+ if (version == null)
+ return new VersionRange("0");
+ return version;
+ }
+
+ public String getSymbolicName() {
+ ManifestEntry bsn = getBsn();
+
+ if (bsn == null) {
+ String name = getValue("Bundle-Name");
+ if (name == null)
+ name = "Untitled-" + hashCode();
+ return name;
+ }
+ else
+ return bsn.getName();
+ }
+
+ public String getManifestVersion() {
+ return getValue("Bundle-ManifestVersion", "1");
+ }
+
+ public String getCopyright() {
+ return getValue("Bundle-Copyright");
+ }
+
+ public String getDocumentation() {
+ return getValue("Bundle-DocURL");
+ }
+
+ public String[] getCategories() {
+ String cats = getValue("Bundle-Category");
+ if (cats == null)
+ return new String[0];
+ else
+ return cats.split("\\s*,\\s*");
+ }
+
+ public Native[] get_native() {
+ return _native;
+ }
+
+ public void set_native(Native[] _native) {
+ this._native = _native;
+ }
+
+ public ManifestEntry getBsn() {
+ return bsn;
+ }
+
+ public void setBsn(ManifestEntry bsn) {
+ this.bsn = bsn;
+ }
+
+ public Vector getDuplicates() {
+ return duplicates;
+ }
+
+ public void setDuplicates(Vector duplicates) {
+ this.duplicates = duplicates;
+ }
+
+ public ManifestEntry getHost() {
+ return host;
+ }
+
+ public void setHost(ManifestEntry host) {
+ this.host = host;
+ }
+
+ public List getRequire() {
+ return require;
+ }
+
+}
+
+class Native {
+ String filter;
+ int index = -1;
+ String paths[];
+ String osname;
+ String osversion;
+ String language;
+ String processor;
+
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/ManifestEntry.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/ManifestEntry.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/ManifestEntry.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/ManifestEntry.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,112 @@
+/*
+ * $Id: ManifestEntry.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 ManifestEntry implements Comparable {
+ String name;
+ VersionRange version;
+ Map attributes;
+ public Map directives;
+ public Set uses;
+
+ public ManifestEntry(String name) {
+ this.name = name;
+ }
+
+ public ManifestEntry(String name, VersionRange version) {
+ this.name = name;
+ this.version = version;
+ }
+
+ @Override
+ public String toString() {
+ if (version == null)
+ return name;
+ return name + " ;version=" + version;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public VersionRange getVersion() {
+ if (version != null)
+ return version;
+ return new VersionRange("0");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(Object o) {
+ ManifestEntry p = (ManifestEntry) o;
+ return name.compareTo(p.name);
+ }
+
+ /**
+ * @return
+ */
+ public Object getPath() {
+ return getName().replace('.', '/');
+ }
+
+ public Map getDirectives() {
+ return directives;
+ }
+
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * @param parameter
+ */
+ public void addParameter(Parameter parameter) {
+ switch (parameter.type) {
+ case Parameter.ATTRIBUTE :
+ if (attributes == null)
+ attributes = new HashMap();
+ attributes.put(parameter.key, parameter.value);
+ if (parameter.key.equalsIgnoreCase("version")
+ || parameter.key
+ .equalsIgnoreCase("specification-version"))
+ this.version = new VersionRange(parameter.value);
+ break;
+
+ case Parameter.DIRECTIVE :
+ if (directives == null)
+ directives = new HashMap();
+ directives.put(parameter.key, parameter.value);
+ break;
+ }
+ }
+
+ public ManifestEntry getAlias(String key) {
+ ManifestEntry me = new ManifestEntry(key);
+ me.attributes = attributes;
+ me.directives = directives;
+ me.version = version;
+ return me;
+ }
+
+}
Added: incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Parameter.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Parameter.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Parameter.java (added)
+++ incubator/ace/trunk/server/src/org/osgi/impl/bundle/obr/resource/Parameter.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,50 @@
+/*
+ * $Id: Parameter.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;
+
+class Parameter {
+ final static int ATTRIBUTE = 1;
+ final static int DIRECTIVE = 2;
+ final static int SINGLE = 0;
+
+ int type;
+ String key;
+ String value;
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(key);
+ switch (type) {
+ case ATTRIBUTE :
+ sb.append("=");
+ break;
+ case DIRECTIVE :
+ sb.append(":=");
+ break;
+ case SINGLE :
+ return sb.toString();
+ }
+ sb.append(value);
+ return sb.toString();
+ }
+
+ boolean is(String s, int type) {
+ return this.type == type && key.equalsIgnoreCase(s);
+ }
+}