felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickh...@apache.org
Subject svn commit: r391296 [1/3] - in /incubator/felix/trunk/org.apache.felix.bundlerepository: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/felix/ src/main/java/org/apache/felix/bundlerepository/ src/...
Date Tue, 04 Apr 2006 13:17:26 GMT
Author: rickhall
Date: Tue Apr  4 06:17:11 2006
New Revision: 391296

URL: http://svn.apache.org/viewcvs?rev=391296&view=rev
Log:
Added new bundle repository service implementation.

Added:
    incubator/felix/trunk/org.apache.felix.bundlerepository/   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/pom.xml   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/Activator.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CategoryImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/FileUtil.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/IteratorToEnumeration.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/MapToDictionary.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ObrCommandImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/PropertyImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Attribute.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Directive.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Export.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Import.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Package.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdminImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/RequirementImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceComparator.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/Util.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/VersionRange.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ClassUtility.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ReplaceUtility.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/Capability.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/CapabilityProvider.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/Repository.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/RepositoryAdmin.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/RepositoryPermission.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/Requirement.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/Resolver.java   (with props)
    incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/osgi/service/obr/Resource.java   (with props)

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Apr  4 06:17:11 2006
@@ -0,0 +1,17 @@
+classes
+target
+*.log
+*.ipr
+*.iws
+*.iml
+lib
+bundle
+dist
+.project
+.classpath
+bin
+build
+.settings
+.wtpmodules
+.deployables
+

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/pom.xml
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/pom.xml?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/pom.xml (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/pom.xml Tue Apr  4 06:17:11 2006
@@ -0,0 +1,54 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>osgi-bundle</packaging>
+  <name>Apache Felix Bundle Repository Service</name>
+  <artifactId>org.apache.felix.bundlerepository</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.shell</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>kxml2</groupId>
+      <artifactId>kxml2</artifactId>
+      <version>2.2.2</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.plugins</groupId>
+        <artifactId>maven-osgi-plugin</artifactId>
+        <version>${pom.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>BundleRepository</bundleName>
+            <bundleDescription>Bundle repository service for Felix (or any other OSGi framework).</bundleDescription>
+            <bundleActivator>org.apache.felix.bundlerepository.Activator</bundleActivator>
+            <bundleDocUrl>http://oscar-osgi.sf.net/obr2/bundlerepository/</bundleDocUrl>
+            <bundleSource>http://oscar-osgi.sf.net/obr2/bundlerepository/org.apache.felix.bundlerepository-src.jar</bundleSource>
+            <bundleSymbolicName>org.apache.felix.bundlerepository</bundleSymbolicName>
+            <importPackage>org.osgi.framework</importPackage>
+            <dynamicImportPackage>org.apache.felix.shell</dynamicImportPackage>
+            <exportPackage>org.osgi.service.obr</exportPackage>
+            <exportService>org.osgi.service.obr.RepositoryAdmin</exportService>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/Activator.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/Activator.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/Activator.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/Activator.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,58 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.obr.RepositoryAdmin;
+
+public class Activator implements BundleActivator
+{
+    private transient BundleContext m_context = null;
+    private transient RepositoryAdminImpl m_repoAdmin = null;
+
+    public void start(BundleContext context)
+    {
+        m_context = context;
+
+        // Register bundle repository service.
+        m_repoAdmin = new RepositoryAdminImpl(m_context);
+        context.registerService(
+            RepositoryAdmin.class.getName(),
+            m_repoAdmin, null);
+
+        // We dynamically import the impl service API, so it
+        // might not actually be available, so be ready to catch
+        // the exception when we try to register the command service.
+        try
+        {
+            // Register "obr" impl command service as a
+            // wrapper for the bundle repository service.
+            context.registerService(
+                org.apache.felix.shell.Command.class.getName(),
+                new ObrCommandImpl(m_context, m_repoAdmin), null);
+        }
+        catch (Throwable th)
+        {
+            // Ignore.
+        }
+    }
+
+    public void stop(BundleContext context)
+    {
+    }
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/Activator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,41 @@
+package org.apache.felix.bundlerepository;
+
+import java.util.*;
+
+import org.osgi.service.obr.Capability;
+
+public class CapabilityImpl implements Capability
+{
+    private String m_name = null;
+    private Map m_map = null;
+
+    public CapabilityImpl()
+    {
+        m_map = new TreeMap(new Comparator() {
+            public int compare(Object o1, Object o2)
+            {
+                return o1.toString().compareToIgnoreCase(o2.toString());
+            }
+        });
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+
+    public void setName(String name)
+    {
+        m_name = name;
+    }
+
+    public Map getProperties()
+    {
+        return m_map;
+    }
+
+    public void addP(PropertyImpl prop)
+    {
+        m_map.put(prop.getN(), prop.getV());
+    }
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CategoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CategoryImpl.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CategoryImpl.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CategoryImpl.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,32 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+public class CategoryImpl
+{
+    String m_id = null;
+
+    public void setId(String id)
+    {
+        m_id = id;
+    }
+
+    public String getId()
+    {
+        return m_id;
+    }
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CategoryImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/FileUtil.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/FileUtil.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/FileUtil.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/FileUtil.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,168 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+import java.io.*;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+public class FileUtil
+{
+    public static void downloadSource(
+        PrintStream out, PrintStream err,
+        URL srcURL, String dirStr, boolean extract)
+    {
+        // Get the file name from the URL.
+        String fileName = (srcURL.getFile().lastIndexOf('/') > 0)
+            ? srcURL.getFile().substring(srcURL.getFile().lastIndexOf('/') + 1)
+            : srcURL.getFile();
+
+        try
+        {
+            out.println("Connecting...");
+
+            File dir = new File(dirStr);
+            if (!dir.exists())
+            {
+                err.println("Destination directory does not exist.");
+            }
+            File file = new File(dir, fileName);
+
+            OutputStream os = new FileOutputStream(file);
+            URLConnection conn = srcURL.openConnection();
+            int total = conn.getContentLength();
+            InputStream is = conn.getInputStream();
+
+            if (total > 0)
+            {
+                out.println("Downloading " + fileName
+                    + " ( " + total + " bytes ).");
+            }
+            else
+            {
+                out.println("Downloading " + fileName + ".");
+            }
+            byte[] buffer = new byte[4096];
+            int count = 0;
+            for (int len = is.read(buffer); len > 0; len = is.read(buffer))
+            {
+                count += len;
+                os.write(buffer, 0, len);
+            }
+
+            os.close();
+            is.close();
+
+            if (extract)
+            {
+                is = new FileInputStream(file);
+                JarInputStream jis = new JarInputStream(is);
+                out.println("Extracting...");
+                unjar(jis, dir);
+                jis.close();
+                file.delete();
+            }
+        }
+        catch (Exception ex)
+        {
+            err.println(ex);
+        }
+    }
+
+    public static void unjar(JarInputStream jis, File dir)
+        throws IOException
+    {
+        // Reusable buffer.
+        byte[] buffer = new byte[4096];
+
+        // Loop through JAR entries.
+        for (JarEntry je = jis.getNextJarEntry();
+             je != null;
+             je = jis.getNextJarEntry())
+        {
+            if (je.getName().startsWith("/"))
+            {
+                throw new IOException("JAR resource cannot contain absolute paths.");
+            }
+
+            File target = new File(dir, je.getName());
+
+            // Check to see if the JAR entry is a directory.
+            if (je.isDirectory())
+            {
+                if (!target.exists())
+                {
+                    if (!target.mkdirs())
+                    {
+                        throw new IOException("Unable to create target directory: "
+                            + target);
+                    }
+                }
+                // Just continue since directories do not have content to copy.
+                continue;
+            }
+
+            int lastIndex = je.getName().lastIndexOf('/');
+            String name = (lastIndex >= 0) ?
+                je.getName().substring(lastIndex + 1) : je.getName();
+            String destination = (lastIndex >= 0) ?
+                je.getName().substring(0, lastIndex) : "";
+
+            // JAR files use '/', so convert it to platform separator.
+            destination = destination.replace('/', File.separatorChar);
+            copy(jis, dir, name, destination, buffer);
+        }
+    }
+
+    public static void copy(
+        InputStream is, File dir, String destName, String destDir, byte[] buffer)
+        throws IOException
+    {
+        if (destDir == null)
+        {
+            destDir = "";
+        }
+
+        // Make sure the target directory exists and
+        // that is actually a directory.
+        File targetDir = new File(dir, destDir);
+        if (!targetDir.exists())
+        {
+            if (!targetDir.mkdirs())
+            {
+                throw new IOException("Unable to create target directory: "
+                    + targetDir);
+            }
+        }
+        else if (!targetDir.isDirectory())
+        {
+            throw new IOException("Target is not a directory: "
+                + targetDir);
+        }
+
+        BufferedOutputStream bos = new BufferedOutputStream(
+            new FileOutputStream(new File(targetDir, destName)));
+        int count = 0;
+        while ((count = is.read(buffer)) > 0)
+        {
+            bos.write(buffer, 0, count);
+        }
+        bos.close();
+    }
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/FileUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/IteratorToEnumeration.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/IteratorToEnumeration.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/IteratorToEnumeration.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/IteratorToEnumeration.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,44 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+public class IteratorToEnumeration implements Enumeration
+{
+    private Iterator m_iter = null;
+
+    public IteratorToEnumeration(Iterator iter)
+    {
+        m_iter = iter;
+    }
+
+    public boolean hasMoreElements()
+    {
+        if (m_iter == null)
+            return false;
+        return m_iter.hasNext();
+    }
+
+    public Object nextElement()
+    {
+        if (m_iter == null)
+            return null;
+        return m_iter.next();
+    }
+}

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/IteratorToEnumeration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,331 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+import java.net.URL;
+import java.util.*;
+
+import org.osgi.framework.*;
+import org.osgi.service.obr.*;
+
+public class LocalRepositoryImpl implements Repository
+{
+    private BundleContext m_context = null;
+    private long m_currentTimeStamp = 0;
+    private long m_snapshotTimeStamp = 0;
+    private List m_localResourceList = new ArrayList();
+    private BundleListener m_bundleListener = null;
+
+    public LocalRepositoryImpl(BundleContext context)
+    {
+        m_context = context;
+        initialize();
+    }
+
+    public void dispose()
+    {
+        m_context.removeBundleListener(m_bundleListener);
+    }
+
+    public URL getURL()
+    {
+        return null;
+    }
+
+    public String getName()
+    {
+        return "Locally Installed Repository";
+    }
+
+    public synchronized long getLastModified()
+    {
+        return m_snapshotTimeStamp;
+    }
+
+    public synchronized long getCurrentTimeStamp()
+    {
+        return m_currentTimeStamp;
+    }
+
+    public synchronized Resource[] getResources()
+    {
+        return (Resource[]) m_localResourceList.toArray(new Resource[m_localResourceList.size()]);
+    }
+
+    private void initialize()
+    {
+        // Create a bundle listener to list for events that
+        // change the state of the framework.
+        m_bundleListener = new SynchronousBundleListener() {
+            public void bundleChanged(BundleEvent event)
+            {
+                synchronized (LocalRepositoryImpl.this)
+                {
+                    m_currentTimeStamp = new Date().getTime();
+                }
+            }
+        };
+        m_context.addBundleListener(m_bundleListener);
+
+        // Generate the resource list from the set of installed bundles.
+        // Lock so we can ensure that no bundle events arrive before we 
+        // are done getting our state snapshot.
+        Bundle[] bundles = null;
+        synchronized (this)
+        {
+            m_snapshotTimeStamp = m_currentTimeStamp = new Date().getTime();
+            bundles = m_context.getBundles();
+        }
+
+        // Create a local resource object for each bundle, which will
+        // convert the bundle headers to the appropriate resource metadata.
+        for (int i = 0; (bundles != null) && (i < bundles.length); i++)
+        {
+            m_localResourceList.add(new LocalResourceImpl(bundles[i]));
+        }
+    }
+
+    public static class LocalResourceImpl extends ResourceImpl
+    {
+        private Bundle m_bundle = null;
+
+        LocalResourceImpl(Bundle bundle)
+        {
+            this(null, bundle);
+        }
+
+        LocalResourceImpl(ResourceImpl resource, Bundle bundle)
+        {
+            super(resource);
+            m_bundle = bundle;
+            initialize();
+        }
+
+        public Bundle getBundle()
+        {
+            return m_bundle;
+        }
+
+        private void initialize()
+        {
+            Dictionary dict = m_bundle.getHeaders();
+
+            // Convert bundle manifest header attributes to resource properties.
+            convertAttributesToProperties(dict);
+            
+            // Convert import package declarations into requirements.
+            convertImportPackageToRequirement(dict);
+
+            // Convert import service declarations into requirements.
+            convertImportServiceToRequirement(dict);
+
+            // Convert export package declarations into capabilities.
+            convertExportPackageToCapability(dict);
+
+            // Convert export service declarations into capabilities.
+            convertExportServiceToCapability(dict);
+
+            // For the system bundle, add a special platform capability.
+            if (m_bundle.getBundleId() == 0)
+            {
+/* TODO: OBR - Fix system capabilities.
+                // Create a case-insensitive map.
+                Map map = new TreeMap(new Comparator() {
+                    public int compare(Object o1, Object o2)
+                    {
+                        return o1.toString().compareToIgnoreCase(o2.toString());
+                    }
+                });
+                map.put(
+                    Constants.FRAMEWORK_VERSION,
+                    m_context.getProperty(Constants.FRAMEWORK_VERSION));
+                map.put(
+                    Constants.FRAMEWORK_VENDOR,
+                    m_context.getProperty(Constants.FRAMEWORK_VENDOR));
+                map.put(
+                    Constants.FRAMEWORK_LANGUAGE,
+                    m_context.getProperty(Constants.FRAMEWORK_LANGUAGE));
+                map.put(
+                    Constants.FRAMEWORK_OS_NAME,
+                    m_context.getProperty(Constants.FRAMEWORK_OS_NAME));
+                map.put(
+                    Constants.FRAMEWORK_OS_VERSION,
+                    m_context.getProperty(Constants.FRAMEWORK_OS_VERSION));
+                map.put(
+                    Constants.FRAMEWORK_PROCESSOR,
+                    m_context.getProperty(Constants.FRAMEWORK_PROCESSOR));
+//                map.put(
+//                    FelixConstants.FELIX_VERSION_PROPERTY,
+//                    m_context.getProperty(FelixConstants.FELIX_VERSION_PROPERTY));
+                Map[] capMaps = (Map[]) bundleMap.get("capability");
+                if (capMaps == null)
+                {
+                    capMaps = new Map[] { map };
+                }
+                else
+                {
+                    Map[] newCaps = new Map[capMaps.length + 1];
+                    newCaps[0] = map;
+                    System.arraycopy(capMaps, 0, newCaps, 1, capMaps.length);
+                    capMaps = newCaps;
+                }
+                bundleMap.put("capability", capMaps);
+*/
+            }
+        }
+
+        private void convertAttributesToProperties(Dictionary dict)
+        {
+            for (Enumeration keys = dict.keys(); keys.hasMoreElements(); )
+            {
+                String key = (String) keys.nextElement();
+                if (key.equalsIgnoreCase(Constants.BUNDLE_SYMBOLICNAME))
+                {
+                    put(Resource.SYMBOLIC_NAME, (String) dict.get(key));
+                }
+                else if (key.equalsIgnoreCase(Constants.BUNDLE_NAME))
+                {
+                    put(Resource.PRESENTATION_NAME, (String) dict.get(key));
+                }
+                else if (key.equalsIgnoreCase(Constants.BUNDLE_VERSION))
+                {
+                    put(Resource.VERSION, (String) dict.get(key));
+                }
+                else if (key.equalsIgnoreCase("Bundle-Source"))
+                {
+                    put(Resource.SOURCE_URL, (String) dict.get(key));
+                }
+                else if (key.equalsIgnoreCase(Constants.BUNDLE_DESCRIPTION))
+                {
+                    put(Resource.DESCRIPTION, (String) dict.get(key));
+                }
+                else if (key.equalsIgnoreCase(Constants.BUNDLE_DOCURL))
+                {
+                    put(Resource.DOCUMENTATION_URL, (String) dict.get(key));
+                }
+                else if (key.equalsIgnoreCase(Constants.BUNDLE_COPYRIGHT))
+                {
+                    put(Resource.COPYRIGHT, (String) dict.get(key));
+                }
+                else if (key.equalsIgnoreCase("Bundle-License"))
+                {
+                    put(Resource.LICENSE_URL, (String) dict.get(key));
+                }
+            }
+        }
+
+        private void convertImportPackageToRequirement(Dictionary dict)
+        {
+            String target = (String) dict.get(Constants.IMPORT_PACKAGE);
+            if (target != null)
+            {
+                R4Package[] pkgs = R4Package.parseImportOrExportHeader(target);
+                R4Import[] imports = new R4Import[pkgs.length];
+                for (int i = 0; i < pkgs.length; i++)
+                {
+                    imports[i] = new R4Import(pkgs[i]);
+                }
+
+                for (int impIdx = 0; impIdx < imports.length; impIdx++)
+                {
+                    String low = imports[impIdx].isLowInclusive()
+                        ? "(version>=" + imports[impIdx].getVersion() + ")"
+                        : "(!(version<=" + imports[impIdx].getVersion() + ")";
+
+                    if (imports[impIdx].getVersionHigh() != null)
+                    {
+                        String high = imports[impIdx].isHighInclusive()
+                            ? "(version<=" + imports[impIdx].getVersionHigh() + ")"
+                            : "(!(version>=" + imports[impIdx].getVersionHigh() + ")";
+                        RequirementImpl req = new RequirementImpl();
+                        req.setMultiple("false");
+                        req.setName("package");
+                        req.addText("Import package " + imports[impIdx].toString());
+                        req.setFilter("(&(package="
+                            + imports[impIdx].getName() + ")"
+                            + low + high + ")");
+                        addRequire(req);
+                    }
+                    else
+                    {
+                        RequirementImpl req = new RequirementImpl();
+                        req.setMultiple("false");
+                        req.setName("package");
+                        req.addText("Import package " + imports[impIdx].toString());
+                        req.setFilter(
+                            "(&(package="
+                            + imports[impIdx].getName() + ")"
+                            + low + ")");
+                        addRequire(req);
+                    }
+                }
+            }
+        }
+
+        private void convertImportServiceToRequirement(Dictionary dict)
+        {
+            String target = (String) dict.get(Constants.IMPORT_SERVICE);
+            if (target != null)
+            {
+                R4Package[] pkgs = R4Package.parseImportOrExportHeader(target);
+                for (int pkgIdx = 0; (pkgs != null) && (pkgIdx < pkgs.length); pkgIdx++)
+                {
+                    RequirementImpl req = new RequirementImpl();
+                    req.setMultiple("false");
+                    req.setName("service");
+                    req.addText("Import service " + pkgs[pkgIdx].toString());
+                    req.setFilter("(service="
+                        + pkgs[pkgIdx].getName() + ")");
+                    addRequire(req);
+                }
+            }
+        }
+
+        private void convertExportPackageToCapability(Dictionary dict)
+        {
+            String target = (String) dict.get(Constants.EXPORT_PACKAGE);
+            if (target != null)
+            {
+                R4Package[] pkgs = R4Package.parseImportOrExportHeader(target);
+                for (int pkgIdx = 0; (pkgs != null) && (pkgIdx < pkgs.length); pkgIdx++)
+                {
+                    CapabilityImpl cap = new CapabilityImpl();
+                    cap.setName("package");
+                    cap.addP(new PropertyImpl("package", null, pkgs[pkgIdx].getName()));
+                    cap.addP(new PropertyImpl("version", "version", pkgs[pkgIdx].getVersion().toString()));
+                    addCapability(cap);
+                }
+            }
+        }
+
+        private void convertExportServiceToCapability(Dictionary dict)
+        {
+            String target = (String) dict.get(Constants.EXPORT_SERVICE);
+            if (target != null)
+            {
+                R4Package[] pkgs = R4Package.parseImportOrExportHeader(target);
+                for (int pkgIdx = 0; (pkgs != null) && (pkgIdx < pkgs.length); pkgIdx++)
+                {
+                    CapabilityImpl cap = new CapabilityImpl();
+                    cap.setName("service");
+                    cap.addP(new PropertyImpl("service", null, pkgs[pkgIdx].getName()));
+                    addCapability(cap);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/MapToDictionary.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/MapToDictionary.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/MapToDictionary.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/MapToDictionary.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,97 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+import java.util.*;
+
+
+/**
+ * This is a simple class that implements a <tt>Dictionary</tt>
+ * from a <tt>Map</tt>. The resulting dictionary is immutatable.
+**/
+public class MapToDictionary extends Dictionary
+{
+    /**
+     * Map source.
+    **/
+    private Map m_map = null;
+
+    public MapToDictionary(Map map)
+    {
+        m_map = map;
+    }
+
+    public void setSourceMap(Map map)
+    {
+        m_map = map;
+    }
+
+    public Enumeration elements()
+    {
+        if (m_map == null)
+        {
+            return null;
+        }
+        return new IteratorToEnumeration(m_map.values().iterator());
+    }
+
+    public Object get(Object key)
+    {
+        if (m_map == null)
+        {
+            return null;
+        }
+        return m_map.get(key);
+    }
+
+    public boolean isEmpty()
+    {
+        if (m_map == null)
+        {
+            return true;
+        }
+        return m_map.isEmpty();
+    }
+
+    public Enumeration keys()
+    {
+        if (m_map == null)
+        {
+            return null;
+        }
+        return new IteratorToEnumeration(m_map.keySet().iterator());
+    }
+
+    public Object put(Object key, Object value)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object remove(Object key)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public int size()
+    {
+        if (m_map == null)
+        {
+            return 0;
+        }
+        return m_map.size();
+    }
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/MapToDictionary.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ObrCommandImpl.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ObrCommandImpl.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ObrCommandImpl.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ObrCommandImpl.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,1087 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+import java.io.*;
+import java.lang.reflect.Array;
+import java.net.*;
+import java.util.*;
+
+import org.apache.felix.shell.Command;
+import org.osgi.framework.*;
+import org.osgi.service.obr.*;
+
+public class ObrCommandImpl implements Command
+{
+    private static final String HELP_CMD = "help";
+    private static final String ADDURL_CMD = "add-url";
+    private static final String REMOVEURL_CMD = "remove-url";
+    private static final String LISTURL_CMD = "list-url";
+    private static final String LIST_CMD = "list";
+    private static final String INFO_CMD = "info";
+    private static final String DEPLOY_CMD = "deploy";
+    private static final String START_CMD = "start";
+    private static final String SOURCE_CMD = "source";
+
+    private static final String EXTRACT_SWITCH = "-x";
+
+    private BundleContext m_context = null;
+    private RepositoryAdmin m_repoAdmin = null;
+
+    public ObrCommandImpl(BundleContext context, RepositoryAdmin repoAdmin)
+    {
+        m_context = context;
+        m_repoAdmin = repoAdmin;
+    }
+
+    public String getName()
+    {
+        return "obr";
+    }
+
+    public String getUsage()
+    {
+        return "obr help";
+    }
+
+    public String getShortDescription()
+    {
+        return "OSGi bundle repository.";
+    }
+
+    public synchronized void execute(String commandLine, PrintStream out, PrintStream err)
+    {
+        try
+        {
+            // Parse the commandLine to get the OBR command.
+            StringTokenizer st = new StringTokenizer(commandLine);
+            // Ignore the invoking command.
+            st.nextToken();
+            // Try to get the OBR command, default is HELP command.
+            String command = HELP_CMD;
+            try
+            {
+                command = st.nextToken();
+            }
+            catch (Exception ex)
+            {
+                // Ignore.
+            }
+            
+            // Perform the specified command.
+            if ((command == null) || (command.equals(HELP_CMD)))
+            {
+                help(out, st);
+            }
+            else
+            {
+                if (command.equals(ADDURL_CMD) ||
+                    command.equals(REMOVEURL_CMD) ||
+                    command.equals(LISTURL_CMD))
+                {
+                    urls(commandLine, command, out, err);
+                }
+                else if (command.equals(LIST_CMD))
+                {
+                    list(commandLine, command, out, err);
+                }
+                else if (command.equals(INFO_CMD))
+                {
+                    info(commandLine, command, out, err);
+                }
+                else if (command.equals(DEPLOY_CMD) || command.equals(START_CMD))
+                {
+                    deploy(commandLine, command, out, err);
+                }
+                else if (command.equals(SOURCE_CMD))
+                {
+                    source(commandLine, command, out, err);
+                }
+                else
+                {
+                    err.println("Unknown command: " + command);
+                }
+            }
+        }
+        catch (InvalidSyntaxException ex)
+        {
+            err.println("Syntax error: " + ex.getMessage());
+        }
+        catch (IOException ex)
+        {
+            err.println("Error: " + ex);
+        }
+    }
+
+    private void urls(
+        String commandLine, String command, PrintStream out, PrintStream err)
+        throws IOException
+    {
+        // Parse the commandLine.
+        StringTokenizer st = new StringTokenizer(commandLine);
+        // Ignore the "obr" command.
+        st.nextToken();
+        // Ignore the "url" command.
+        st.nextToken();
+
+        int count = st.countTokens();
+        if (count > 0)
+        {
+            while (st.hasMoreTokens())
+            {
+                if (command.equals(ADDURL_CMD))
+                {
+                    try
+                    {
+                        m_repoAdmin.addRepository(new URL(st.nextToken()));
+                    }
+                    catch (Exception ex)
+                    {
+                        ex.printStackTrace(err);
+                    }
+                }
+                else
+                {
+                    m_repoAdmin.removeRepository(new URL(st.nextToken()));
+                }
+            }
+        }
+        else
+        {
+            Repository[] repos = m_repoAdmin.listRepositories();
+            if ((repos != null) && (repos.length > 0))
+            {
+                for (int i = 0; i < repos.length; i++)
+                {
+                    out.println(repos[i].getURL());
+                }
+            }
+            else
+            {
+                out.println("No repository URLs are set.");
+            }
+        }
+    }
+
+    private void list(
+        String commandLine, String command, PrintStream out, PrintStream err)
+        throws IOException
+    {
+        // Create a stream tokenizer for the command line string,
+        // since the syntax for install/start is more sophisticated.
+        StringReader sr = new StringReader(commandLine);
+        StreamTokenizer tokenizer = new StreamTokenizer(sr);
+        tokenizer.resetSyntax();
+        tokenizer.quoteChar('\'');
+        tokenizer.quoteChar('\"');
+        tokenizer.whitespaceChars('\u0000', '\u0020');
+        tokenizer.wordChars('A', 'Z');
+        tokenizer.wordChars('a', 'z');
+        tokenizer.wordChars('0', '9');
+        tokenizer.wordChars('\u00A0', '\u00FF');
+        tokenizer.wordChars('.', '.');
+        tokenizer.wordChars('-', '-');
+        tokenizer.wordChars('_', '_');
+
+        // Ignore the invoking command name and the OBR command.
+        int type = tokenizer.nextToken();
+        type = tokenizer.nextToken();
+
+        String substr = null;
+    
+        for (type = tokenizer.nextToken();
+            type != StreamTokenizer.TT_EOF;
+            type = tokenizer.nextToken())
+        {
+            // Add a space in between tokens.
+            if (substr == null)
+            {
+                substr = "";
+            }
+            else
+            {
+                substr += " ";
+            }
+                        
+            if ((type == StreamTokenizer.TT_WORD) ||
+                (type == '\'') || (type == '"'))
+            {
+                substr += tokenizer.sval;
+            }
+        }
+
+        StringBuffer sb = new StringBuffer();
+        if ((substr == null) || (substr.length() == 0))
+        {
+            sb.append("(|(presentationname=*)(symbolicname=*))");
+        }
+        else
+        {
+            sb.append("(|(presentationname=*");
+            sb.append(substr);
+            sb.append("*)(symbolicname=*");
+            sb.append(substr);
+            sb.append("*))");
+        }
+        Resource[] resources = m_repoAdmin.discoverResources(sb.toString());
+        for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
+        {
+            String name = resources[resIdx].getPresentationName();
+            Version version = resources[resIdx].getVersion();
+            if (version != null)
+            {
+                out.println(name + " (" + version + ")");
+            }
+            else
+            {
+                out.println(name);
+            }
+        }
+    
+        if (resources == null)
+        {
+            out.println("No matching bundles.");
+        }
+    }
+
+    private void info(
+        String commandLine, String command, PrintStream out, PrintStream err)
+        throws IOException, InvalidSyntaxException
+    {
+        ParsedCommand pc = parseInfo(commandLine);
+        for (int cmdIdx = 0; (pc != null) && (cmdIdx < pc.getTargetCount()); cmdIdx++)                
+        {
+            // Find the target's bundle resource.
+            Resource[] resources = searchRepository(pc.getTargetId(cmdIdx), pc.getTargetVersion(cmdIdx));
+            if (resources == null)
+            {
+                err.println("Unknown bundle and/or version: "
+                    + pc.getTargetId(cmdIdx));
+            }
+            else
+            {
+                for (int resIdx = 0; resIdx < resources.length; resIdx++)
+                {
+                    if (resIdx > 0)
+                    {
+                        out.println("");
+                    }
+                    printResource(out, resources[resIdx]);
+                }
+            }
+        }
+    }
+
+    private void deploy(
+        String commandLine, String command, PrintStream out, PrintStream err)
+        throws IOException, InvalidSyntaxException
+    {
+        ParsedCommand pc = parseInstallStart(commandLine);
+        _deploy(pc, command, out, err);
+    }
+
+    private void _deploy(
+        ParsedCommand pc, String command, PrintStream out, PrintStream err)
+        throws IOException, InvalidSyntaxException
+    {
+        Resolver resolver = m_repoAdmin.resolver();
+        for (int i = 0; (pc != null) && (i < pc.getTargetCount()); i++)                
+        {
+            // Find the target's bundle resource.
+            Resource resource = selectNewestVersion(
+                searchRepository(pc.getTargetId(i), pc.getTargetVersion(i)));
+            if (resource != null)
+            {
+                resolver.add(resource);
+            }
+            else
+            {
+                err.println("Unknown bundle - " + pc.getTargetId(i));
+            }
+        }
+
+        if ((resolver.getAddedResources() != null) &&
+            (resolver.getAddedResources().length > 0))
+        {
+            if (resolver.resolve())
+            {
+                out.println("Target resource(s):");
+                printUnderline(out, 19);
+                Resource[] resources = resolver.getAddedResources();
+                for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
+                {
+                    out.println("   " + resources[resIdx].getPresentationName()
+                        + " (" + resources[resIdx].getVersion() + ")");
+                }
+                resources = resolver.getRequiredResources();
+                if ((resources != null) && (resources.length > 0))
+                {
+                    out.println("\nRequired resource(s):");
+                    printUnderline(out, 21);
+                    for (int resIdx = 0; resIdx < resources.length; resIdx++)
+                    {
+                        out.println("   " + resources[resIdx].getPresentationName()
+                            + " (" + resources[resIdx].getVersion() + ")");
+                    }
+                }
+                resources = resolver.getOptionalResources();
+                if ((resources != null) && (resources.length > 0))
+                {
+                    out.println("\nOptional resource(s):");
+                    printUnderline(out, 21);
+                    for (int resIdx = 0; resIdx < resources.length; resIdx++)
+                    {
+                        out.println("   " + resources[resIdx].getPresentationName()
+                            + " (" + resources[resIdx].getVersion() + ")");
+                    }
+                }
+    
+                try
+                {
+                    out.print("\nDeploying...");
+                    resolver.deploy(command.equals(START_CMD));
+                    out.println("done.");
+                }
+                catch (IllegalStateException ex)
+                {
+                    err.println(ex);
+                }
+            }
+            else
+            {
+                Requirement[] reqs = resolver.getUnsatisfiedRequirements();
+                if ((reqs != null) && (reqs.length > 0))
+                {
+                    out.println("Unsatisfied requirement(s):");
+                    printUnderline(out, 27);
+                    for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++)
+                    {
+                        out.println("   " + reqs[reqIdx].getFilter());
+                        Resource[] resources = resolver.getResources(reqs[reqIdx]);
+                        for (int resIdx = 0; resIdx < resources.length; resIdx++)
+                        {
+                            out.println("      " + resources[resIdx].getPresentationName());
+                        }
+                    }
+                }
+                else
+                {
+                    out.println("Could not resolve targets.");
+                }
+            }
+        }
+    }
+
+    private void source(
+        String commandLine, String command, PrintStream out, PrintStream err)
+        throws IOException, InvalidSyntaxException
+    {
+        // Parse the command line to get all local targets to update.
+        ParsedCommand pc = parseSource(commandLine);
+        for (int i = 0; i < pc.getTargetCount(); i++)
+        {
+            Resource resource = selectNewestVersion(
+                searchRepository(pc.getTargetId(i), pc.getTargetVersion(i)));
+            if (resource == null)
+            {
+                err.println("Unknown bundle and/or version: "
+                    + pc.getTargetId(i));
+            }
+            else
+            {
+                URL srcURL = (URL) resource.getProperties().get(Resource.SOURCE_URL);
+                if (srcURL != null)
+                {
+                    FileUtil.downloadSource(
+                        out, err, srcURL, pc.getDirectory(), pc.isExtract());
+                }
+                else
+                {
+                    err.println("Missing source URL: " + pc.getTargetId(i));
+                }
+            }
+        }
+    }
+
+    private Resource[] searchRepository(String targetId, String targetVersion)
+    {
+        // Try to see if the targetId is a bundle ID.
+        try
+        {
+            Bundle bundle = m_context.getBundle(Long.parseLong(targetId));
+            targetId = bundle.getSymbolicName();
+        }
+        catch (NumberFormatException ex)
+        {
+            // It was not a number, so ignore.
+        }
+
+        // The targetId may be a bundle name or a bundle symbolic name,
+        // so create the appropriate LDAP query.
+        StringBuffer sb = new StringBuffer("(|(presentationname=");
+        sb.append(targetId);
+        sb.append(")(symbolicname=");
+        sb.append(targetId);
+        sb.append("))");
+        if (targetVersion != null)
+        {
+            sb.insert(0, "(&");
+            sb.append("(version=");
+            sb.append(targetVersion);
+            sb.append("))");
+        }
+        return m_repoAdmin.discoverResources(sb.toString());
+    }
+
+    public Resource selectNewestVersion(Resource[] resources)
+    {
+        int idx = -1;
+        Version v = null;
+        for (int i = 0; (resources != null) && (i < resources.length); i++)
+        {
+            if (i == 0)
+            {
+                idx = 0;
+                v = resources[i].getVersion();
+            }
+            else
+            {
+                Version vtmp = resources[i].getVersion();
+                if (vtmp.compareTo(v) > 0)
+                {
+                    idx = i;
+                    v = vtmp;
+                }
+            }
+        }
+
+        return (idx < 0) ? null : resources[idx];
+    }
+
+    private void printResource(PrintStream out, Resource resource)
+    {
+        printUnderline(out, resource.getPresentationName().length());
+        out.println(resource.getPresentationName());
+        printUnderline(out, resource.getPresentationName().length());
+
+        Map map = resource.getProperties();
+        for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) iter.next();
+            if (entry.getValue().getClass().isArray())
+            {
+                out.println(entry.getKey() + ":");
+                for (int j = 0; j < Array.getLength(entry.getValue()); j++)
+                {
+                    out.println("   " + Array.get(entry.getValue(), j));
+                }
+            }
+            else
+            {
+                out.println(entry.getKey() + ": " + entry.getValue());
+            }
+        }
+ 
+        Requirement[] reqs = resource.getRequirements();
+        if ((reqs != null) && (reqs.length > 0))
+        {
+            out.println("Requires:");
+            for (int i = 0; i < reqs.length; i++)
+            {
+                out.println("   " + reqs[i].getFilter());
+            }
+        }
+        
+        Capability[] caps = resource.getCapabilities();
+        if ((caps != null) && (caps.length > 0))
+        {
+            out.println("Capabilities:");
+            for (int i = 0; i < caps.length; i++)
+            {
+                out.println("   " + caps[i].getProperties());
+            }
+        }
+    }
+
+    private static void printUnderline(PrintStream out, int length)
+    {
+        for (int i = 0; i < length; i++)
+        {
+            out.print('-');
+        }
+        out.println("");
+    }
+
+    private ParsedCommand parseInfo(String commandLine)
+        throws IOException, InvalidSyntaxException
+    {
+        // Create a stream tokenizer for the command line string,
+        // since the syntax for install/start is more sophisticated.
+        StringReader sr = new StringReader(commandLine);
+        StreamTokenizer tokenizer = new StreamTokenizer(sr);
+        tokenizer.resetSyntax();
+        tokenizer.quoteChar('\'');
+        tokenizer.quoteChar('\"');
+        tokenizer.whitespaceChars('\u0000', '\u0020');
+        tokenizer.wordChars('A', 'Z');
+        tokenizer.wordChars('a', 'z');
+        tokenizer.wordChars('0', '9');
+        tokenizer.wordChars('\u00A0', '\u00FF');
+        tokenizer.wordChars('.', '.');
+        tokenizer.wordChars('-', '-');
+        tokenizer.wordChars('_', '_');
+    
+        // Ignore the invoking command name and the OBR command.
+        int type = tokenizer.nextToken();
+        type = tokenizer.nextToken();
+    
+        int EOF = 1;
+        int SWITCH = 2;
+        int TARGET = 4;
+        int VERSION = 8;
+        int VERSION_VALUE = 16;
+
+        // Construct an install record.
+        ParsedCommand pc = new ParsedCommand();
+        String currentTargetName = null;
+
+        // The state machine starts by expecting either a
+        // SWITCH or a TARGET.
+        int expecting = (TARGET);
+        while (true)
+        {
+            // Get the next token type.
+            type = tokenizer.nextToken();
+            switch (type)
+            {
+                // EOF received.
+                case StreamTokenizer.TT_EOF:
+                    // Error if we weren't expecting EOF.
+                    if ((expecting & EOF) == 0)
+                    {
+                        throw new InvalidSyntaxException(
+                            "Expecting more arguments.", null);
+                    }
+                    // Add current target if there is one.
+                    if (currentTargetName != null)
+                    {
+                        pc.addTarget(currentTargetName, null);
+                    }
+                    // Return cleanly.
+                    return pc;
+
+                // WORD or quoted WORD received.
+                case StreamTokenizer.TT_WORD:
+                case '\'':
+                case '\"':
+                    // If we are expecting a target, the record it.
+                    if ((expecting & TARGET) > 0)
+                    {
+                        // Add current target if there is one.
+                        if (currentTargetName != null)
+                        {
+                            pc.addTarget(currentTargetName, null);
+                        }
+                        // Set the new target as the current target.
+                        currentTargetName = tokenizer.sval;
+                        expecting = (EOF | TARGET | VERSION);
+                    }
+                    else if ((expecting & VERSION_VALUE) > 0)
+                    {
+                        pc.addTarget(currentTargetName, tokenizer.sval);
+                        currentTargetName = null;
+                        expecting = (EOF | TARGET);
+                    }
+                    else
+                    {
+                        throw new InvalidSyntaxException(
+                            "Not expecting '" + tokenizer.sval + "'.", null);
+                    }
+                    break;
+
+                // Version separator character received.
+                case ';':
+                    // Error if we weren't expecting the version separator.
+                    if ((expecting & VERSION) == 0)
+                    {
+                        throw new InvalidSyntaxException(
+                            "Not expecting version.", null);
+                    }
+                    // Otherwise, we will only expect a version value next.
+                    expecting = (VERSION_VALUE);
+                    break;
+            }
+        }
+    }
+
+    private ParsedCommand parseInstallStart(String commandLine)
+        throws IOException, InvalidSyntaxException
+    {
+        // Create a stream tokenizer for the command line string,
+        // since the syntax for install/start is more sophisticated.
+        StringReader sr = new StringReader(commandLine);
+        StreamTokenizer tokenizer = new StreamTokenizer(sr);
+        tokenizer.resetSyntax();
+        tokenizer.quoteChar('\'');
+        tokenizer.quoteChar('\"');
+        tokenizer.whitespaceChars('\u0000', '\u0020');
+        tokenizer.wordChars('A', 'Z');
+        tokenizer.wordChars('a', 'z');
+        tokenizer.wordChars('0', '9');
+        tokenizer.wordChars('\u00A0', '\u00FF');
+        tokenizer.wordChars('.', '.');
+        tokenizer.wordChars('-', '-');
+        tokenizer.wordChars('_', '_');
+    
+        // Ignore the invoking command name and the OBR command.
+        int type = tokenizer.nextToken();
+        type = tokenizer.nextToken();
+    
+        int EOF = 1;
+        int SWITCH = 2;
+        int TARGET = 4;
+        int VERSION = 8;
+        int VERSION_VALUE = 16;
+
+        // Construct an install record.
+        ParsedCommand pc = new ParsedCommand();
+        String currentTargetName = null;
+
+        // The state machine starts by expecting either a
+        // SWITCH or a TARGET.
+        int expecting = (SWITCH | TARGET);
+        while (true)
+        {
+            // Get the next token type.
+            type = tokenizer.nextToken();
+            switch (type)
+            {
+                // EOF received.
+                case StreamTokenizer.TT_EOF:
+                    // Error if we weren't expecting EOF.
+                    if ((expecting & EOF) == 0)
+                    {
+                        throw new InvalidSyntaxException(
+                            "Expecting more arguments.", null);
+                    }
+                    // Add current target if there is one.
+                    if (currentTargetName != null)
+                    {
+                        pc.addTarget(currentTargetName, null);
+                    }
+                    // Return cleanly.
+                    return pc;
+
+                // WORD or quoted WORD received.
+                case StreamTokenizer.TT_WORD:
+                case '\'':
+                case '\"':
+                    // If we are expecting a target, the record it.
+                    if ((expecting & TARGET) > 0)
+                    {
+                        // Add current target if there is one.
+                        if (currentTargetName != null)
+                        {
+                            pc.addTarget(currentTargetName, null);
+                        }
+                        // Set the new target as the current target.
+                        currentTargetName = tokenizer.sval;
+                        expecting = (EOF | TARGET | VERSION);
+                    }
+                    else if ((expecting & VERSION_VALUE) > 0)
+                    {
+                        pc.addTarget(currentTargetName, tokenizer.sval);
+                        currentTargetName = null;
+                        expecting = (EOF | TARGET);
+                    }
+                    else
+                    {
+                        throw new InvalidSyntaxException(
+                            "Not expecting '" + tokenizer.sval + "'.", null);
+                    }
+                    break;
+
+                // Version separator character received.
+                case ';':
+                    // Error if we weren't expecting the version separator.
+                    if ((expecting & VERSION) == 0)
+                    {
+                        throw new InvalidSyntaxException(
+                            "Not expecting version.", null);
+                    }
+                    // Otherwise, we will only expect a version value next.
+                    expecting = (VERSION_VALUE);
+                    break;
+            }
+        }
+    }
+
+    private ParsedCommand parseSource(String commandLine)
+        throws IOException, InvalidSyntaxException
+    {
+        // Create a stream tokenizer for the command line string,
+        // since the syntax for install/start is more sophisticated.
+        StringReader sr = new StringReader(commandLine);
+        StreamTokenizer tokenizer = new StreamTokenizer(sr);
+        tokenizer.resetSyntax();
+        tokenizer.quoteChar('\'');
+        tokenizer.quoteChar('\"');
+        tokenizer.whitespaceChars('\u0000', '\u0020');
+        tokenizer.wordChars('A', 'Z');
+        tokenizer.wordChars('a', 'z');
+        tokenizer.wordChars('0', '9');
+        tokenizer.wordChars('\u00A0', '\u00FF');
+        tokenizer.wordChars('.', '.');
+        tokenizer.wordChars('-', '-');
+        tokenizer.wordChars('_', '_');
+        tokenizer.wordChars('/', '/');
+        tokenizer.wordChars('\\', '\\');
+        tokenizer.wordChars(':', ':');
+    
+        // Ignore the invoking command name and the OBR command.
+        int type = tokenizer.nextToken();
+        type = tokenizer.nextToken();
+    
+        int EOF = 1;
+        int SWITCH = 2;
+        int DIRECTORY = 4;
+        int TARGET = 8;
+        int VERSION = 16;
+        int VERSION_VALUE = 32;
+
+        // Construct an install record.
+        ParsedCommand pc = new ParsedCommand();
+        String currentTargetName = null;
+
+        // The state machine starts by expecting either a
+        // SWITCH or a DIRECTORY.
+        int expecting = (SWITCH | DIRECTORY);
+        while (true)
+        {
+            // Get the next token type.
+            type = tokenizer.nextToken();
+            switch (type)
+            {
+                // EOF received.
+                case StreamTokenizer.TT_EOF:
+                    // Error if we weren't expecting EOF.
+                    if ((expecting & EOF) == 0)
+                    {
+                        throw new InvalidSyntaxException(
+                            "Expecting more arguments.", null);
+                    }
+                    // Add current target if there is one.
+                    if (currentTargetName != null)
+                    {
+                        pc.addTarget(currentTargetName, null);
+                    }
+                    // Return cleanly.
+                    return pc;
+
+                // WORD or quoted WORD received.
+                case StreamTokenizer.TT_WORD:
+                case '\'':
+                case '\"':
+                    // If we are expecting a command SWITCH and the token
+                    // equals a command SWITCH, then record it.
+                    if (((expecting & SWITCH) > 0) && tokenizer.sval.equals(EXTRACT_SWITCH))
+                    {
+                        pc.setExtract(true);
+                        expecting = (DIRECTORY);
+                    }
+                    // If we are expecting a directory, the record it.
+                    else if ((expecting & DIRECTORY) > 0)
+                    {
+                        // Set the directory for the command.
+                        pc.setDirectory(tokenizer.sval);
+                        expecting = (TARGET);
+                    }
+                    // If we are expecting a target, the record it.
+                    else if ((expecting & TARGET) > 0)
+                    {
+                        // Add current target if there is one.
+                        if (currentTargetName != null)
+                        {
+                            pc.addTarget(currentTargetName, null);
+                        }
+                        // Set the new target as the current target.
+                        currentTargetName = tokenizer.sval;
+                        expecting = (EOF | TARGET | VERSION);
+                    }
+                    else if ((expecting & VERSION_VALUE) > 0)
+                    {
+                        pc.addTarget(currentTargetName, tokenizer.sval);
+                        currentTargetName = null;
+                        expecting = (EOF | TARGET);
+                    }
+                    else
+                    {
+                        throw new InvalidSyntaxException(
+                            "Not expecting '" + tokenizer.sval + "'.", null);
+                    }
+                    break;
+
+                // Version separator character received.
+                case ';':
+                    // Error if we weren't expecting the version separator.
+                    if ((expecting & VERSION) == 0)
+                    {
+                        throw new InvalidSyntaxException(
+                            "Not expecting version.", null);
+                    }
+                    // Otherwise, we will only expect a version value next.
+                    expecting = (VERSION_VALUE);
+                    break;
+            }
+        }
+    }
+
+    private void help(PrintStream out, StringTokenizer st)
+    {
+        String command = HELP_CMD;
+        if (st.hasMoreTokens())
+        {
+            command = st.nextToken();
+        }
+        if (command.equals(ADDURL_CMD))
+        {
+            out.println("");
+            out.println("obr " + ADDURL_CMD + " [<repository-url> ...]");
+            out.println("");
+            out.println(
+                "This command adds the space-delimited list of repository URLs to\n" +
+                "the repository service.");
+            out.println("");
+        }
+        else if (command.equals(REMOVEURL_CMD))
+        {
+            out.println("");
+            out.println("obr " + REMOVEURL_CMD + " [<repository-url> ...]");
+            out.println("");
+            out.println(
+                "This command removes the space-delimited list of repository URLs\n" +
+                "from the repository service.");
+            out.println("");
+        }
+        else if (command.equals(LISTURL_CMD))
+        {
+            out.println("");
+            out.println("obr " + LISTURL_CMD);
+            out.println("");
+            out.println(
+                "This command displays the repository URLs currently associated\n" +
+                "with the repository service.");
+            out.println("");
+        }
+        else if (command.equals(LIST_CMD))
+        {
+            out.println("");
+            out.println("obr " + LIST_CMD + " [<string> ...]");
+            out.println("");
+            out.println(
+                "This command lists bundles available in the bundle repository.\n" +
+                "If no arguments are specified, then all available bundles are\n" +
+                "listed, otherwise any arguments are concatenated with spaces\n" +
+                "and used as a substring filter on the bundle names.");
+            out.println("");
+        }
+        else if (command.equals(INFO_CMD))
+        {
+            out.println("");
+            out.println("obr " + INFO_CMD
+                + " <bundle-name>|<bundle-symbolic-name>|<bundle-id>[;<version>] ...");
+            out.println("");
+            out.println(
+                "This command displays the meta-data for the specified bundles.\n" +
+                "If a bundle's name contains spaces, then it must be surrounded\n" +
+                "by quotes. It is also possible to specify a precise version\n" +
+                "if more than one version exists, such as:\n" +
+                "\n" +
+                "    obr info \"Bundle Repository\";1.0.0\n" +
+                "\n" +
+                "The above example retrieves the meta-data for version \"1.0.0\"\n" +
+                "of the bundle named \"Bundle Repository\".");
+            out.println("");
+        }
+        else if (command.equals(DEPLOY_CMD))
+        {
+            out.println("");
+            out.println("obr " + DEPLOY_CMD
+                + " <bundle-name>|<bundle-symbolic-name>|<bundle-id>[;<version>] ... ");
+            out.println("");
+            out.println(
+                "This command tries to install or update the specified bundles\n" +
+                "and all of their dependencies. You can specify either the bundle\n" +
+                "name or the bundle identifier. If a bundle's name contains spaces,\n" +
+                "then it must be surrounded by quotes. It is also possible to\n" +
+                "specify a precise version if more than one version exists, such as:\n" +
+                "\n" +
+                "    obr deploy \"Bundle Repository\";1.0.0\n" +
+                "\n" +
+                "For the above example, if version \"1.0.0\" of \"Bundle Repository\" is\n" +
+                "already installed locally, then the command will attempt to update it\n" +
+                "and all of its dependencies; otherwise, the command will install it\n" +
+                "and all of its dependencies.");
+            out.println("");
+        }
+        else if (command.equals(START_CMD))
+        {
+            out.println("");
+            out.println("obr " + START_CMD
+                + " <bundle-name>|<bundle-symbolic-name>|<bundle-id>[;<version>] ...");
+            out.println("");
+            out.println(
+                "This command installs and starts the specified bundles and all\n" +
+                "of their dependencies. If a bundle's name contains spaces, then\n" +
+                "it must be surrounded by quotes. If a specified bundle is already\n" +                "installed, then this command has no effect. It is also possible\n" +                "to specify a precise version if more than one version exists,\n" +                "such as:\n" +
+                "\n" +
+                "    obr start \"Bundle Repository\";1.0.0\n" +
+                "\n" +
+                "The above example installs and starts version \"1.0.0\" of the\n" +
+                "bundle named \"Bundle Repository\" and its dependencies.");
+            out.println("");
+        }
+        else if (command.equals(SOURCE_CMD))
+        {
+            out.println("");
+            out.println("obr " + SOURCE_CMD
+                + " [" + EXTRACT_SWITCH
+                + "] <local-dir> <bundle-name>[;<version>] ...");
+            out.println("");
+            out.println(
+                "This command retrieves the source archives of the specified\n" +
+                "bundles and saves them to the specified local directory; use\n" +
+                "the \"" + EXTRACT_SWITCH + "\" switch to automatically extract the source archives.\n" +
+                "If a bundle name contains spaces, then it must be surrounded\n" +
+                "by quotes. It is also possible to specify a precise version if\n" +                "more than one version exists, such as:\n" +
+                "\n" +
+                "    obr source /home/rickhall/tmp \"Bundle Repository\";1.0.0\n" +
+                "\n" +
+                "The above example retrieves the source archive of version \"1.0.0\"\n" +
+                "of the bundle named \"Bundle Repository\" and saves it to the\n" +
+                "specified local directory.");
+            out.println("");
+        }
+        else
+        {
+            out.println("obr " + HELP_CMD
+                + " [" + ADDURL_CMD
+                + " | " + REMOVEURL_CMD
+                + " | " + LISTURL_CMD
+                + " | " + LIST_CMD
+                + " | " + INFO_CMD
+                + " | " + DEPLOY_CMD + " | " + START_CMD
+                + " | " + SOURCE_CMD + "]");
+            out.println("obr " + ADDURL_CMD + " [<repository-file-url> ...]");
+            out.println("obr " + REMOVEURL_CMD + " [<repository-file-url> ...]");
+            out.println("obr " + LISTURL_CMD);
+            out.println("obr " + LIST_CMD + " [<string> ...]");
+            out.println("obr " + INFO_CMD
+                + " <bundle-name>|<bundle-symbolic-name>|<bundle-id>[;<version>] ...");
+            out.println("obr " + DEPLOY_CMD
+                + " <bundle-name>|<bundle-symbolic-name>|<bundle-id>[;<version>] ...");
+            out.println("obr " + START_CMD
+                + " <bundle-name>|<bundle-symbolic-name>|<bundle-id>[;<version>] ...");
+            out.println("obr " + SOURCE_CMD
+                + " [" + EXTRACT_SWITCH
+                + "] <local-dir> <bundle-name>[;<version>] ...");
+        }
+    }
+
+    private static class ParsedCommand
+    {
+        private static final int NAME_IDX = 0;
+        private static final int VERSION_IDX = 1;
+
+        private boolean m_isResolve = true;
+        private boolean m_isCheck = false;
+        private boolean m_isExtract = false;
+        private String m_dir = null;
+        private String[][] m_targets = new String[0][];
+        
+        public boolean isResolve()
+        {
+            return m_isResolve;
+        }
+        
+        public void setResolve(boolean b)
+        {
+            m_isResolve = b;
+        }
+
+        public boolean isCheck()
+        {
+            return m_isCheck;
+        }
+        
+        public void setCheck(boolean b)
+        {
+            m_isCheck = b;
+        }
+
+        public boolean isExtract()
+        {
+            return m_isExtract;
+        }
+        
+        public void setExtract(boolean b)
+        {
+            m_isExtract = b;
+        }
+
+        public String getDirectory()
+        {
+            return m_dir;
+        }
+        
+        public void setDirectory(String s)
+        {
+            m_dir = s;
+        }
+
+        public int getTargetCount()
+        {
+            return m_targets.length;
+        }
+        
+        public String getTargetId(int i)
+        {
+            if ((i < 0) || (i >= getTargetCount()))
+            {
+                return null;
+            }
+            return m_targets[i][NAME_IDX];
+        }
+        
+        public String getTargetVersion(int i)
+        {
+            if ((i < 0) || (i >= getTargetCount()))
+            {
+                return null;
+            }
+            return m_targets[i][VERSION_IDX];
+        }
+
+        public void addTarget(String name, String version)
+        {
+            String[][] newTargets = new String[m_targets.length + 1][];
+            System.arraycopy(m_targets, 0, newTargets, 0, m_targets.length);
+            newTargets[m_targets.length] = new String[] { name, version };
+            m_targets = newTargets;
+        }
+    }
+}

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ObrCommandImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/PropertyImpl.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/PropertyImpl.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/PropertyImpl.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/PropertyImpl.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,97 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+import java.net.*;
+
+import org.osgi.framework.Version;
+import org.osgi.service.obr.Resource;
+
+public class PropertyImpl
+{
+    private String m_name = null;
+    private String m_type = null;
+    private Object m_value = null;
+
+    public PropertyImpl()
+    {
+    }
+
+    public PropertyImpl(String name, String type, String value)
+    {
+        setN(name);
+        setT(type);
+        setV(value);
+    }
+
+    public void setN(String name)
+    {
+        m_name = name;
+    }
+
+    public String getN()
+    {
+        return m_name;
+    }
+
+    public void setT(String type)
+    {
+        m_type = type;
+
+        // If there is an existing value, then convert
+        // it based on the new type.
+        if (m_value != null)
+        {
+            m_value = convertType(m_value.toString());
+        }
+    }
+
+    public String getT()
+    {
+        return m_type;
+    }
+
+    public void setV(String value)
+    {
+        m_value = convertType(value);
+    }
+
+    public Object getV()
+    {
+        return m_value;
+    }
+
+    private Object convertType(String value)
+    {
+        if ((m_type != null) && (m_type.equalsIgnoreCase(Resource.VERSION)))
+        {
+            return new Version(value);
+        }
+        else if ((m_type != null) && (m_type.equalsIgnoreCase(Resource.URL)))
+        {
+            try
+            {
+                return new URL(value);
+            }
+            catch (MalformedURLException ex)
+            {
+                ex.printStackTrace();
+            }
+        }
+        return value;
+    }
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/PropertyImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Attribute.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Attribute.java?rev=391296&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Attribute.java (added)
+++ incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Attribute.java Tue Apr  4 06:17:11 2006
@@ -0,0 +1,46 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   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.apache.felix.bundlerepository;
+
+public class R4Attribute
+{
+    private String m_name = "";
+    private String m_value = "";
+    private boolean m_isMandatory = false;
+    
+    public R4Attribute(String name, String value, boolean isMandatory)
+    {
+        m_name = name;
+        m_value = value;
+        m_isMandatory = isMandatory;
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+
+    public String getValue()
+    {
+        return m_value;
+    }
+
+    public boolean isMandatory()
+    {
+        return m_isMandatory;
+    }
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/R4Attribute.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message