You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2005/08/16 20:34:41 UTC

svn commit: r233031 [16/21] - in /incubator/oscar/trunk: ./ etc/ lib/ src/ src/org/ src/org/apache/ src/org/apache/osgi/ src/org/apache/osgi/bundle/ src/org/apache/osgi/bundle/bundlerepository/ src/org/apache/osgi/bundle/bundlerepository/kxmlsax/ src/o...

Added: incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/BundleRecord.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/BundleRecord.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/BundleRecord.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/BundleRecord.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,203 @@
+/*
+ *   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.osgi.service.bundlerepository;
+
+import java.io.PrintStream;
+import java.lang.reflect.Array;
+import java.util.*;
+
+/**
+ * A simple interface used to hold meta-data about bundles
+ * contained in a bundle repository.
+**/
+public class BundleRecord
+{
+    public static final String BUNDLE_NAME = "Bundle-Name";
+    public static final String BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName";
+    public static final String BUNDLE_VERSION = "Bundle-Version";
+    public static final String BUNDLE_UPDATELOCATION = "Bundle-UpdateLocation";
+    public static final String BUNDLE_URL = "Bundle-URL";
+    public static final String BUNDLE_SOURCEURL = "Bundle-SourceURL";
+    public static final String BUNDLE_DOCURL = "Bundle-DocURL";
+    public static final String BUNDLE_LICENSEURL = "Bundle-LicenseURL";
+    public static final String BUNDLE_DESCRIPTION = "Bundle-Description";
+    public static final String BUNDLE_CATEGORY = "Bundle-Category";
+    public static final String BUNDLE_VENDOR = "Bundle-Vendor";
+    public static final String BUNDLE_CONTACTADDRESS = "Bundle-ContactAddress";
+    public static final String BUNDLE_COPYRIGHT = "Bundle-Copyright";
+    public static final String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
+    public static final String BUNDLE_NATIVECODE = "Bundle-NativeCode";
+    public static final String IMPORT_PACKAGE = "Import-Package";
+    public static final String EXPORT_PACKAGE = "Export-Package";
+    public static final String DYNAMICIMPORT_PACKAGE = "DynamicImport-Package";
+    public static final String REQUIRE_SERVICE = "Require-Service";
+    public static final String PROVIDE_SERVICE = "Provide-Service";
+
+    private Map m_attrMap = null;
+    private Dictionary m_dict = null;
+
+    /**
+     * <p>
+     * Constructs a bundle record using the values of the supplied
+     * map as the meta-data values for the bundle. The supplied map
+     * is copied, but its values are not.
+     * </p>
+     * @param attrMap a map containing attribute-value pairs of meta-data
+     *        for a bundle.
+    **/
+    public BundleRecord(Map attrMap)
+    {
+        // Create a case insensitive map.
+        m_attrMap = new TreeMap(new Comparator() {
+            public int compare(Object o1, Object o2)
+            {
+                return o1.toString().compareToIgnoreCase(o2.toString());
+            }
+        });
+        m_attrMap.putAll(attrMap);
+    }
+
+    /**
+     * <p>
+     * Returns a dictionary object which can be used with
+     * <tt>org.osgi.framework.Filter</tt>, for example. The returned
+     * dictionary object is a minimum implementation, where only
+     * the <tt>get()</tt>, <tt>size()</tt>, and <tt>isEmpty()</tt>
+     * methods do anything useful.
+     * </p>
+     * @return a dictionary object for accessing the bundle record attributes.
+    **/
+    public synchronized Dictionary getDictionary()
+    {
+        if (m_dict == null)
+        {
+            m_dict = new Dictionary() {
+                public int size()
+                {
+                    return m_attrMap.size();
+                }
+
+                public boolean isEmpty()
+                {
+                    return m_attrMap.isEmpty();
+                }
+
+                public Enumeration elements()
+                {
+                    throw new UnsupportedOperationException("Not implemented.");
+                }
+
+                public Enumeration keys()
+                {
+                    throw new UnsupportedOperationException("Not implemented.");
+                }
+
+                public Object get(Object key)
+                {
+                    return m_attrMap.get(key);
+                }
+
+                public Object remove(Object key)
+                {
+                    throw new UnsupportedOperationException("Not implemented.");
+                }
+
+                public Object put(Object key, Object value)
+                {
+                    throw new UnsupportedOperationException("Not implemented.");
+                }
+            };
+        }
+
+        return m_dict;
+    }
+
+    /**
+     * <p>
+     * Returns an array containing all attribute names associated with
+     * the bundle record. The return array is a copy and can be freely
+     * modified.
+     * </p>
+     * @return an array containing the attribute names contained in the
+     *         bundle record.
+    **/
+    public String[] getAttributes()
+    {
+        return (String[]) m_attrMap.keySet().toArray(new String[m_attrMap.size()]);
+    }
+
+    /**
+     * <p>
+     * Returns the value of the specified attribute. If the value is an array,
+     * then a copy is returned.
+     * </p>
+     * @param name the attribute name for which to retrieve its value.
+     * @return the value of the specified attribute or <tt>null</tt> if
+     *         the specified attribute does not exist.
+    **/
+    public Object getAttribute(String name)
+    {
+        Object obj = m_attrMap.get(name);
+        // If the value is an array, then make a copy
+        // since arrays are mutable.
+        if ((obj != null) && obj.getClass().isArray())
+        {
+            Class clazz = obj.getClass().getComponentType();
+            int len = Array.getLength(obj);
+            Object copy = Array.newInstance(obj.getClass().getComponentType(), len);
+            System.arraycopy(obj, 0, copy, 0, len);
+            obj = copy;
+        }
+        return obj;
+    }
+
+    /**
+     * <p>
+     * Dumps the contents of the bundle record to the specified print stream.
+     * </p>
+     * @param out the print stream to use for printing.
+    **/    
+    public void printAttributes(PrintStream out)
+    {
+        String[] attrs = getAttributes();
+        if (attrs != null)
+        {
+            Arrays.sort(attrs);
+            for (int i = 0; (attrs != null) && (i < attrs.length); i++)
+            {
+                Object obj = getAttribute(attrs[i]);
+                if (obj.getClass().isArray())
+                {
+                    out.println(attrs[i] + ":");
+                    for (int j = 0; j < Array.getLength(obj); j++)
+                    {
+                        out.println("   " + Array.get(obj, j));
+                    }
+                }
+                else
+                {
+                    out.println(attrs[i] + ": " + getAttribute(attrs[i]));
+                }
+            }
+        }
+    }
+
+    public String toString()
+    {
+        return (String) m_attrMap.get(BUNDLE_NAME);
+    }
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/BundleRepository.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/BundleRepository.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/BundleRepository.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/BundleRepository.java Tue Aug 16 11:33:34 2005
@@ -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.osgi.service.bundlerepository;
+
+import java.io.PrintStream;
+
+/**
+ * This interface defines a simple bundle repository service.
+**/
+public interface BundleRepository
+{
+    /**
+     * Get URL list of repositories.
+     * @return a space separated list of URLs to use or <tt>null</tt>
+     *         to refresh the cached list of bundles.
+    **/
+    public String[] getRepositoryURLs();
+
+    /**
+     * Set URL list of repositories.
+     * @param url a space separated list of URLs to use or <tt>null</tt>
+     *        to refresh the cached list of bundles.
+    **/
+    public void setRepositoryURLs(String[] urls);
+
+    /**
+     * Returns an array of the bundle symbolic names available
+     * in the repository.
+     * @return An arry of available bundle symbolic names.
+    **/
+    public BundleRecord[] getBundleRecords();
+
+    /**
+     * Get the specified bundle record from the repository.
+     * @param i the bundle record index to retrieve.
+     * @return the associated bundle record or <tt>null</tt>.
+    **/
+    public BundleRecord[] getBundleRecords(String symname);
+
+    /**
+     * Get bundle record for the bundle with the specified name
+     * and version from the repository.
+     * @param name the bundle record name to retrieve.
+     * @param version three-interger array of the version associated with
+     *        the name to retrieve.
+     * @return the associated bundle record or <tt>null</tt>.
+    **/
+    public BundleRecord getBundleRecord(String symname, int[] version);
+
+    /**
+     * Deploys the bundle in the repository that corresponds to
+     * the specified update location. The action taken depends on
+     * whether the specified bundle is already installed in the local
+     * framework. If the bundle is already installed, then this
+     * method will attempt to update it. If the bundle is not already
+     * installed, then this method will attempt to install it.
+     * @param out the stream to use for informational messages.
+     * @param err the stream to use for error messages.
+     * @param symname the symbolic name of the bundle to deploy.
+     * @param isResolve a flag to indicates whether dependencies should
+     *        should be resolved.
+     * @param isStart a flag to indicate whether installed bundles should
+     *        be started.
+     * @return <tt>true</tt> if successful, <tt>false</tt> otherwise.
+    **/
+    public boolean deployBundle(
+        PrintStream out, PrintStream err, String symname, int[] version,
+        boolean isResolve, boolean isStart);
+
+    /**
+     * Returns an array containing all bundle records in the
+     * repository that resolve the transitive closure of the
+     * passed in array of package declarations.
+     * @param pkgs an array of package declarations to resolve.
+     * @return an array containing all bundle records in the
+     *         repository that resolve the transitive closure of
+     *         the passed in array of package declarations.
+     * @throws ResolveException if any packages in the transitive
+     *         closure of packages cannot be resolved.
+    **/
+    public BundleRecord[] resolvePackages(IPackage[] pkgs)
+        throws ResolveException;
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IAttribute.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IAttribute.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IAttribute.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IAttribute.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,26 @@
+/*
+ *   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.osgi.service.bundlerepository;
+
+public interface IAttribute
+{
+    public String getName();
+
+    public String getValue();
+
+    public boolean isMandatory();
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IDirective.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IDirective.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IDirective.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IDirective.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,24 @@
+/*
+ *   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.osgi.service.bundlerepository;
+
+public interface IDirective
+{
+    public String getName();
+
+    public String getValue();
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IPackage.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IPackage.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IPackage.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IPackage.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,34 @@
+/*
+ *   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.osgi.service.bundlerepository;
+
+public interface IPackage
+{
+    public String getId();
+
+    public IDirective[] getDirectives();
+
+    public IAttribute[] getAttributes();
+
+    public IVersion getVersionLow();
+
+    public IVersion getVersionHigh();
+
+    public boolean isOptional();
+
+    public boolean doesSatisfy(IPackage pkg);
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IVersion.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IVersion.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IVersion.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/IVersion.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,36 @@
+/*
+ *   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.osgi.service.bundlerepository;
+
+public interface IVersion extends Comparable
+{
+    public boolean equals(Object object);
+
+    public int getMajorComponent();
+
+    public int getMinorComponent();
+
+    public int getMicroComponent();
+
+    public String getQualifierComponent();
+
+    public boolean isInclusive();
+
+    public int compareTo(Object o);
+
+    public String toString();
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/ResolveException.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/ResolveException.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/ResolveException.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/bundlerepository/ResolveException.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,32 @@
+/*
+ *   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.osgi.service.bundlerepository;
+
+public class ResolveException extends Exception
+{
+    private IPackage m_pkg = null;
+
+    public ResolveException(IPackage pkg)
+    {
+        m_pkg = pkg;
+    }
+    
+    public IPackage getPackage()
+    {
+        return m_pkg;
+    }
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/service/shell/CdCommand.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/shell/CdCommand.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/shell/CdCommand.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/shell/CdCommand.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,49 @@
+/*
+ *   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.osgi.service.shell;
+
+/**
+ * This interface defines the <tt>cd</tt> command service interface for the
+ * Felix shell service. The <tt>cd</tt> command does not really change the
+ * directory of the shell, rather it maintains a base URL for
+ * simplifying URL entry.
+ * <p>
+ * For example, if the base URL is <tt>http://www.foo.com/<tt> and you
+ * try to install a bundle <tt>foo.jar</tt>, the actual URL will be
+ * expanded to <tt>http://www.foo.com/foo.jar</tt>. Any bundles wishing
+ * to retrieve or set the current directory of the shell can use this
+ * service interface.
+**/
+public interface CdCommand extends Command
+{
+    /**
+     * Property used to configure the base URL.
+    **/
+    public static final String BASE_URL_PROPERTY = "felix.shell.baseurl";
+
+    /**
+     * Returns the current <i>directory</i> of the shell service.
+     * @return the current shell directory.
+    **/
+    public String getBaseURL();
+
+    /**
+     * Sets the current <i>directory</i> of the shell service.
+     * @param s the new value for the base URL.
+    **/
+    public void setBaseURL(String s);
+}

Added: incubator/oscar/trunk/src/org/apache/osgi/service/shell/Command.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/shell/Command.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/shell/Command.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/shell/Command.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,68 @@
+/*
+ *   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.osgi.service.shell;
+
+import java.io.PrintStream;
+
+/**
+ * This interface is used to define commands for the Felix shell
+ * service. Any bundle wishing to create commands for the
+ * shell service simply needs to create a service object that
+ * implements this interface and then register it with the OSGi
+ * framework. The shell service automatically includes any
+ * registered command services in its list of available commands.
+**/
+public interface Command
+{
+    /**
+     * Returns the name of the command that is implemented by the
+     * interface. The command name should not contain whitespace
+     * and should also be unique.
+     * @return the name of the command.
+    **/
+    public String getName();
+
+    /**
+     * Returns the usage string for the command. The usage string is
+     * a short string that illustrates how to use the command on the
+     * command line. This information is used when generating command
+     * help information. An example usage string for the <tt>install</tt>
+     * command is:
+     * <pre>
+     *     install <URL> [<URL> ...]
+     * </pre>
+     * @return the usage string for the command.
+    **/
+    public String getUsage();
+
+    /**
+     * Returns a short description of the command; this description
+     * should be as short as possible. This information is used when
+     * generating the command help information.
+     * @return a short description of the command.
+    **/
+    public String getShortDescription();
+
+    /**
+     * Executes the command using the supplied command line, output
+     * print stream, and error print stream.
+     * @param line the complete command line, including the command name.
+     * @param out the print stream to use for standard output.
+     * @param err the print stream to use for standard error.
+    **/
+    public void execute(String line, PrintStream out, PrintStream err);
+}

Added: incubator/oscar/trunk/src/org/apache/osgi/service/shell/ShellService.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/service/shell/ShellService.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/service/shell/ShellService.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/service/shell/ShellService.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,95 @@
+/*
+ *   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.osgi.service.shell;
+
+import java.io.PrintStream;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This interface defines the Felix shell service. The shell service
+ * is an extensible, user interface neutral shell for controlling and
+ * interacting with the framework. In general, the shell service assumes that
+ * it is operating in a command line fashion, i.e., it receives a
+ * complete command line, parses it, and executes the corresponding
+ * command, but graphical interfaces are also possible.
+ * <p>
+ * All commands in the shell service are actually implemented as OSGi
+ * services; these services implement the <tt>Command</tt> service
+ * interface. Any bundle can implement custom commands by creating
+ * command services and registering them with the OSGi framework.
+**/
+public interface ShellService
+{
+    /**
+     * Returns an array of command names available in the shell service.
+     * @return an array of available command names or an empty array.
+    **/
+    public String[] getCommands();
+
+    /**
+     * Returns the usage string associated with the specified command name.
+     * @param name the name of the target command.
+     * @return the usage string of the specified command or null.
+    **/
+    public String getCommandUsage(String name);
+
+    /**
+     * Returns the description associated with the specified command name.
+     * @param name the name of the target command.
+     * @return the description of the specified command or null.
+    **/
+    public String getCommandDescription(String name);
+
+    /**
+     * Returns the service reference associated with the specified
+     * command name.
+     * @param name the name of the target command.
+     * @return the description of the specified command or null.
+    **/
+    public ServiceReference getCommandReference(String name);
+
+    /**
+     *
+     * This method executes the supplied command line using the
+     * supplied output and error print stream. The assumption of
+     * this method is that a command line will be typed by the user
+     * (or perhaps constructed by a GUI) and passed into it for
+     * execution. The command line is interpretted in a very
+     * simplistic fashion; it takes the leading string of characters
+     * terminated by a space character (not including it) and
+     * assumes that this leading token is the command name. For an
+     * example, consider the following command line:
+     * </p>
+     * <pre>
+     *     update 3 http://www.foo.com/bar.jar
+     * </pre>
+     * <p>
+     * This is interpretted as an <tt>update</tt> command; as a
+     * result, the entire command line (include command name) is
+     * passed into the <tt>execute()</tt> method of the command
+     * service with the name <tt>update</tt> if one exists. If the
+     * corresponding command service is not found, then an error
+     * message is printed to the error print stream.
+     * @param commandLine the command line to execute.
+     * @param out the standard output print stream.
+     * @param err the standard error print stream.
+    **/
+    public void executeCommand(
+        String commandLine, PrintStream out, PrintStream err)
+        throws Exception;
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/osgi/framework/AdminPermission.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/osgi/framework/AdminPermission.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/osgi/framework/AdminPermission.java (added)
+++ incubator/oscar/trunk/src/org/osgi/framework/AdminPermission.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,932 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/AdminPermission.java,v 1.12 2005/05/13 20:32:54 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this 
+ * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.*;
+import java.util.*;
+import org.apache.osgi.framework.FilterImpl;
+
+/**
+ * Indicates the caller's authority to perform specific privileged administrative 
+ * operations on or to get sensitive information about a bundle.
+ * 
+ * <ul>
+ *   <li>The <code>{@link AdminPermission#METADATA}</code> action allows calls to
+ *   	<ul>
+ *         <li>{@link Bundle#getHeaders()}
+ *         <li>{@link Bundle#getHeaders(String)}
+ *         <li>{@link Bundle#getLocation()}
+ *         </ul>
+ *   <li>The <code>{@link AdminPermission#RESOURCE}</code> action allows calls to
+ *   	<ul>
+ *   		<li>{@link Bundle#getResource(String)}
+ *   		<li>{@link Bundle#getEntry(String)}
+ *   		<li>{@link Bundle#getEntryPaths(String)}
+ *   		<li>Bundle resource/entry URL creation
+ *   	</ul>
+ *   <li>The <code>{@link AdminPermission#METADATA}</code> action allows calls to
+ *   	<ul>
+ *   		<li>{@link Bundle#loadClass(String)}
+ *   	</ul>
+ *   <li>The <code>{@link AdminPermission#LIFECYCLE}</code> action allows calls to
+ *   	<ul>
+ *   		<li>{@link BundleContext#installBundle(String)}
+ *   		<li>{@link BundleContext#installBundle(String, InputStream)}
+ *   		<li>{@link Bundle#update()}
+ *   		<li>{@link Bundle#update(InputStream)}
+ *   		<li>{@link Bundle#uninstall()}
+ *   	</ul>
+ *   <li>The <code>{@link AdminPermission#EXECUTE}</code> action allows calls to
+ *   	<ul>
+ *   		<li>{@link Bundle#start()}
+ *   		<li>{@link Bundle#stop()}
+ *   		<li>{@link org.osgi.service.startlevel.StartLevel#setBundleStartLevel(Bundle, int)}
+ *   	</ul>
+ *   <li>The <code>{@link AdminPermission#LISTENER}</code> action allows calls to
+ *   	<ul>
+ *   		<li>{@link BundleContext#addBundleListener(BundleListener)} for 
+ *   				<code>SynchronousBundleListener</code>
+ *   		<li>{@link BundleContext#removeBundleListener(BundleListener)} for 
+ *   				<code>SynchronousBundleListener</code>
+ *   	</ul>
+ *   <li>The <code>{@link AdminPermission#PERMISSION}</code> action allows calls to
+ *   	<ul>
+ *   		<li>{@link org.osgi.service.permissionadmin.PermissionAdmin#setPermissions(String, PermissionInfo[])}
+ *   		<li>{@link org.osgi.service.permissionadmin.PermissionAdmin#setDefaultPermissions(PermissionInfo[])}
+ *   	</ul>
+ *   <li>The <code>{@link AdminPermission#RESOLVE}</code> action allows calls to
+ *   	<ul>
+ *   		<li>{@link org.osgi.service.packageadmin.PackageAdmin#refreshPackages(Bundle[])}</code>
+ *   		<li>{@link org.osgi.service.packageadmin.PackageAdmin#resolveBundles(Bundle[])}</code>
+ *   	</ul>
+ *   <li>The <code>{@link AdminPermission#STARTLEVEL}</code> action allows calls to
+ *   	<ul>
+ *   		<li>{@link org.osgi.service.startlevel.StartLevel#setStartLevel(int)}
+ *   		<li>{@link org.osgi.service.startlevel.StartLevel#setInitialBundleStartLevel(int)}
+ *   	</ul>
+ * </ul>
+ * 
+ * The special action "*" will represent all actions.
+ * 
+ * @version $Revision: 1.12 $
+ */
+
+public final class AdminPermission extends Permission
+{
+	static final long	serialVersionUID	= 207051004521261705L;
+
+    /**
+     * The action string <code>class</code> (Value is "class").
+     */
+    public final static String CLASS = "class"; //$NON-NLS-1$
+
+    /**
+     * The action string <code>execute</code> (Value is "execute").
+     */
+    public final static String EXECUTE = "execute"; //$NON-NLS-1$
+    
+    /**
+     * The action string <code>lifecycle</code> (Value is "lifecycle").
+     */
+    public final static String LIFECYCLE = "lifecycle"; //$NON-NLS-1$
+    
+    /**
+     * The action string <code>listener</code> (Value is "listener").
+     */
+    public final static String LISTENER = "listener"; //$NON-NLS-1$
+    
+    /**
+     * The action string <code>metadata</code> (Value is "metadata").
+     */
+    public final static String METADATA = "metadata"; //$NON-NLS-1$
+
+    /**
+     * The action string <code>permission</code> (Value is "permission").
+     */
+    public final static String PERMISSION = "permission"; //$NON-NLS-1$
+	
+    /**
+     * The action string <code>resolve</code> (Value is "resolve").
+     */
+    public final static String RESOLVE = "resolve"; //$NON-NLS-1$
+
+    /**
+     * The action string <code>resource</code> (Value is "resource").
+     */
+    public final static String RESOURCE = "resource"; //$NON-NLS-1$
+    
+    /**
+     * The action string <code>startlevel</code> (Value is "startlevel").
+     */
+    public final static String STARTLEVEL = "startlevel"; //$NON-NLS-1$
+
+    /**
+     * The action string <code>extensionLifecycle</code> (Value is "extensionLifecycle").
+     */
+    public final static String EXTENSIONLIFECYCLE = "extensionLifecycle"; //$NON-NLS-1$
+
+    private final static int ACTION_CLASS				= 0x00000001;
+    private final static int ACTION_EXECUTE				= 0x00000002;
+    private final static int ACTION_LIFECYCLE			= 0x00000004;
+    private final static int ACTION_LISTENER			= 0x00000008;
+    private final static int ACTION_METADATA			= 0x00000010;
+    private final static int ACTION_PERMISSION			= 0x00000020;
+    private final static int ACTION_RESOLVE				= 0x00000040;
+    private final static int ACTION_RESOURCE			= 0x00000080;
+    private final static int ACTION_STARTLEVEL			= 0x00000100;
+	private final static int ACTION_EXTENSIONLIFECYCLE	= 0x00000200;
+    private final static int ACTION_ALL = 
+		ACTION_CLASS 				|
+		ACTION_EXECUTE 				|
+		ACTION_LIFECYCLE 			|
+		ACTION_LISTENER 			|
+    	ACTION_METADATA 			|
+		ACTION_PERMISSION			|
+		ACTION_RESOLVE 				|
+		ACTION_RESOURCE 			|
+		ACTION_STARTLEVEL			|
+		ACTION_EXTENSIONLIFECYCLE;
+    private final static int ACTION_NONE = 0;
+	
+	/**
+	 * Indicates that this AdminPermission refers to all bundles
+	 * @serial
+	 */
+	private boolean wildcard;
+	
+	/**
+	 * An x.500 distinguished name used to match a bundle's signature - only used if
+	 * wildcard is false and bundle = null
+	 * @serial
+	 */
+	private String filter;
+
+    /**
+     * The actions in canonical form.
+     *
+     * @serial
+     */
+    private String actions = null;
+
+    /**
+     * The actions mask.
+     */
+	private transient int action_mask = ACTION_NONE;
+
+	/**
+	 * The bundle governed by this AdminPermission - only used if 
+	 * wildcard is false and filter == null
+	 */
+	private transient Bundle bundle;
+
+    /**
+     * If this AdminPermission was constructed with a bundle, this dictionary holds
+     * the properties of that bundle, used to match a filter in implies.
+     * This is not initialized until necessary, and then cached in this object.
+     */
+    private transient Dictionary bundleProperties;
+    
+    /**
+     * If this AdminPermission was constructed with a filter, this dictionary holds
+     * a Filter matching object used to evaluate the filter in implies.
+     * This is not initialized until necessary, and then cached in this object
+     */
+    private transient Filter filterImpl;
+    
+	/**
+     * Creates a new <code>AdminPermission</code> object that matches 
+     * all bundles and has all actions.  Equivalent to 
+     * AdminPermission("*","*");
+     */
+    public AdminPermission()
+    {
+    	this("*",AdminPermission.ACTION_ALL); //$NON-NLS-1$
+    }
+    
+    /**
+     * Creates a new <code>AdminPermission</code> object for use by the <code>Policy</code>
+     * object to instantiate new <code>Permission</code> objects.
+     * 
+     * Null arguments are equivalent to "*"
+     *
+     * @param filter an X.500 Distinguished Name suffix or "*" to match all bundles
+     * @param actions <code>class</code>, <code>execute</code>, <code>lifecycle</code>, 
+     * <code>listener</code>, <code>metadata</code>, <code>permission</code>, <code>resolve</code>, 
+     * <code>resource</code>, <code>startlevel</code>, or "*" to indicate all actions
+     */
+    public AdminPermission(String filter, String actions)
+    {
+    	//arguments will be null if called from a PermissionInfo defined with
+    	//no args
+    	this(
+    			(filter == null ? "*" : filter), //$NON-NLS-1$
+				getMask((actions == null ? "*" : actions)) //$NON-NLS-1$
+				);
+    }
+
+    /**
+     * Creates a new <code>AdminPermission</code> object for use by the <code>Policy</code>
+     * object to instantiate new <code>Permission</code> objects.
+     * 
+     * @param bundle A bundle
+     * @param actions <code>class</code>, <code>execute</code>, <code>lifecycle</code>, 
+     * <code>listener</code>, <code>metadata</code>, <code>permission</code>, <code>resolve</code>, 
+     * <code>resource</code>, <code>startlevel</code>, or "*" to indicate all actions
+     */
+    public AdminPermission(Bundle bundle, String actions) {
+    	super(bundle.toString());
+    	this.bundle = bundle;
+    	this.wildcard = false;
+    	this.filter = null;
+    	this.action_mask = getMask(actions);
+    }
+ 
+    /**
+     * Package private constructor used by AdminPermissionCollection.
+     *
+     * @param filter name filter
+     * @param action_mask mask
+     */
+    AdminPermission(String filter, int action_mask) {
+    	super(filter);
+    	
+    	//name must be either * or a filter
+    	if (filter.equals("*")) { //$NON-NLS-1$
+    		this.wildcard = true;
+    		this.filter = null;
+    	} else {
+			this.wildcard = false;
+			this.filter = filter;
+    	}
+    	this.bundle = null;
+    	this.action_mask = action_mask;
+    }
+
+    /**
+     * Parse action string into action mask.
+     *
+     * @param actions Action string.
+     * @return action mask.
+     */
+    private static int getMask(String actions) {
+    
+    	boolean seencomma = false;
+
+    	int mask = ACTION_NONE;
+
+    	if (actions == null) {
+    		return mask;
+    	}
+
+    	char[] a = actions.toCharArray();
+
+    	int i = a.length - 1;
+    	if (i < 0)
+    		return mask;
+
+    	while (i != -1) {
+    		char c;
+
+    		// skip whitespace
+    		while ((i!=-1) && ((c = a[i]) == ' ' ||
+    				c == '\r' ||
+					c == '\n' ||
+					c == '\f' ||
+					c == '\t'))
+    			i--;
+
+    		// check for the known strings
+    		int matchlen;
+
+    		if (i >= 4 && 
+					(a[i-4] == 'c' || a[i-4] == 'C') &&
+					(a[i-3] == 'l' || a[i-3] == 'L') &&
+					(a[i-2] == 'a' || a[i-2] == 'A') &&
+					(a[i-1] == 's' || a[i-1] == 'S') &&
+					  (a[i] == 's' ||   a[i] == 'S'))
+			{
+				matchlen = 5;
+				mask |= ACTION_CLASS;
+	
+    		} else if (i >= 6 && 
+					(a[i-6] == 'e' || a[i-6] == 'E') &&
+					(a[i-5] == 'x' || a[i-5] == 'X') &&
+					(a[i-4] == 'e' || a[i-4] == 'E') &&
+					(a[i-3] == 'c' || a[i-3] == 'C') &&
+					(a[i-2] == 'u' || a[i-2] == 'U') &&
+					(a[i-1] == 't' || a[i-1] == 'T') &&
+					  (a[i] == 'e' ||   a[i] == 'E'))
+			{
+				matchlen = 7;
+				mask |= ACTION_EXECUTE;
+				
+			} else if (i >= 17 && 
+					(a[i-17] == 'e' || a[i-17] == 'E') &&
+					(a[i-16] == 'x' || a[i-16] == 'X') &&
+					(a[i-15] == 't' || a[i-15] == 'T') &&
+					(a[i-14] == 'e' || a[i-14] == 'E') &&
+					(a[i-13] == 'n' || a[i-13] == 'N') &&
+					(a[i-12] == 's' || a[i-12] == 'S') &&
+					(a[i-11] == 'i' || a[i-11] == 'I') &&
+					(a[i-10] == 'o' || a[i-10] == 'O') &&
+					(a[i-9] == 'n' || a[i-9] == 'N') &&
+					(a[i-8] == 'l' || a[i-8] == 'L') &&
+					(a[i-7] == 'i' || a[i-7] == 'I') &&
+					(a[i-6] == 'f' || a[i-6] == 'F') &&
+					(a[i-5] == 'e' || a[i-5] == 'E') &&
+					(a[i-4] == 'c' || a[i-4] == 'C') &&
+					(a[i-3] == 'y' || a[i-3] == 'Y') &&
+					(a[i-2] == 'c' || a[i-2] == 'C') &&
+					(a[i-1] == 'l' || a[i-1] == 'L') &&
+					  (a[i] == 'e' ||   a[i] == 'E'))
+    		{
+    			matchlen = 18;
+    			mask |= ACTION_EXTENSIONLIFECYCLE;
+
+    		} else if (i >= 8 && 
+					(a[i-8] == 'l' || a[i-8] == 'L') &&
+					(a[i-7] == 'i' || a[i-7] == 'I') &&
+					(a[i-6] == 'f' || a[i-6] == 'F') &&
+					(a[i-5] == 'e' || a[i-5] == 'E') &&
+					(a[i-4] == 'c' || a[i-4] == 'C') &&
+					(a[i-3] == 'y' || a[i-3] == 'Y') &&
+					(a[i-2] == 'c' || a[i-2] == 'C') &&
+					(a[i-1] == 'l' || a[i-1] == 'L') &&
+					  (a[i] == 'e' ||   a[i] == 'E'))
+			{
+				matchlen = 9;
+				mask |= ACTION_LIFECYCLE;
+				
+			} else if (i >= 7 && 
+					(a[i-7] == 'l' || a[i-7] == 'L') &&
+					(a[i-6] == 'i' || a[i-6] == 'I') &&
+					(a[i-5] == 's' || a[i-5] == 'S') &&
+					(a[i-4] == 't' || a[i-4] == 'T') &&
+					(a[i-3] == 'e' || a[i-3] == 'E') &&
+					(a[i-2] == 'n' || a[i-2] == 'N') &&
+					(a[i-1] == 'e' || a[i-1] == 'E') &&
+					  (a[i] == 'r' ||   a[i] == 'R'))
+			{
+				matchlen = 8;
+				mask |= ACTION_LISTENER;
+			
+			} else if (i >= 7 && 
+    				(a[i-7] == 'm' || a[i-7] == 'M') &&
+    	            (a[i-6] == 'e' || a[i-6] == 'E') &&
+    	            (a[i-5] == 't' || a[i-5] == 'T') &&
+    	            (a[i-4] == 'a' || a[i-4] == 'A') &&
+    	            (a[i-3] == 'd' || a[i-3] == 'D') &&
+    	            (a[i-2] == 'a' || a[i-2] == 'A') &&
+					(a[i-1] == 't' || a[i-1] == 'T') &&
+					  (a[i] == 'a' ||   a[i] == 'A'))
+    		{
+    			matchlen = 8;
+    			mask |= ACTION_METADATA;
+
+    		} else if (i >= 9 && 
+					(a[i-9] == 'p' || a[i-9] == 'P') &&
+					(a[i-8] == 'e' || a[i-8] == 'E') &&
+					(a[i-7] == 'r' || a[i-7] == 'R') &&
+					(a[i-6] == 'm' || a[i-6] == 'M') &&
+					(a[i-5] == 'i' || a[i-5] == 'I') &&
+					(a[i-4] == 's' || a[i-4] == 'S') &&
+					(a[i-3] == 's' || a[i-3] == 'S') &&
+					(a[i-2] == 'i' || a[i-2] == 'I') &&
+					(a[i-1] == 'o' || a[i-1] == 'O') &&
+					  (a[i] == 'n' ||   a[i] == 'N'))
+    		{
+    			matchlen = 10;
+    			mask |= ACTION_PERMISSION;
+			
+    		} else if (i >= 6 && 
+					(a[i-6] == 'r' || a[i-6] == 'R') &&
+					(a[i-5] == 'e' || a[i-5] == 'E') &&
+					(a[i-4] == 's' || a[i-4] == 'S') &&
+					(a[i-3] == 'o' || a[i-3] == 'O') &&
+					(a[i-2] == 'l' || a[i-2] == 'L') &&
+					(a[i-1] == 'v' || a[i-1] == 'V') &&
+					  (a[i] == 'e' ||   a[i] == 'E'))
+    		{
+    			matchlen = 7;
+    			mask |= ACTION_RESOLVE;
+    			
+    		} else if (i >= 7 && 
+    					(a[i-7] == 'r' || a[i-7] == 'R') &&
+						(a[i-6] == 'e' || a[i-6] == 'E') &&
+						(a[i-5] == 's' || a[i-5] == 'S') &&
+						(a[i-4] == 'o' || a[i-4] == 'O') &&
+						(a[i-3] == 'u' || a[i-3] == 'U') &&
+						(a[i-2] == 'r' || a[i-2] == 'R') &&
+						(a[i-1] == 'c' || a[i-1] == 'C') &&
+						  (a[i] == 'e' ||   a[i] == 'E'))
+			{
+    			matchlen = 8;
+    			mask |= ACTION_RESOURCE;
+
+    		} else if (i >= 9 && 
+					(a[i-9] == 's' || a[i-9] == 'S') &&
+					(a[i-8] == 't' || a[i-8] == 'T') &&
+					(a[i-7] == 'a' || a[i-7] == 'A') &&
+					(a[i-6] == 'r' || a[i-6] == 'R') &&
+					(a[i-5] == 't' || a[i-5] == 'T') &&
+					(a[i-4] == 'l' || a[i-4] == 'L') &&
+					(a[i-3] == 'e' || a[i-3] == 'E') &&
+					(a[i-2] == 'v' || a[i-2] == 'V') &&
+					(a[i-1] == 'e' || a[i-1] == 'E') &&
+					  (a[i] == 'l' ||   a[i] == 'L'))
+    		{
+    			matchlen = 10;
+    			mask |= ACTION_STARTLEVEL;
+
+    		} else if (i >= 0 && 
+					(a[i] == '*'))
+    		{
+    			matchlen = 1;
+    			mask |= ACTION_ALL;
+
+			} else {
+				// parse error
+				throw new IllegalArgumentException(
+						"invalid permission: " + actions);
+        }
+
+        // make sure we didn't just match the tail of a word
+        // like "ackbarfstartlevel".  Also, skip to the comma.
+        seencomma = false;
+        while (i >= matchlen && !seencomma) {
+        	switch(a[i-matchlen]) {
+        		case ',':
+        			seencomma = true;
+        			/*FALLTHROUGH*/
+        		case ' ': case '\r': case '\n':
+        		case '\f': case '\t':
+        			break;
+        		default:
+        			throw new IllegalArgumentException(
+        					"invalid permission: " + actions);
+        	}
+        	i--;
+        }
+
+        // point i at the location of the comma minus one (or -1).
+        i -= matchlen;
+    }
+
+    if (seencomma) {
+        throw new IllegalArgumentException("invalid permission: " +
+                        actions);
+    }
+
+    return mask;
+    }
+     
+    /**
+     * Called by <code><@link AdminPermission#implies(Permission)></code> on an AdminPermission
+     * which was constructed with a Bundle.  This method loads a dictionary with the
+     * filter-matchable properties of this bundle.  The dictionary is cached so this lookup
+     * only happens once.
+     * 
+     * This method should only be called on an AdminPermission which was constructed with a 
+     * bundle
+     * 
+     * @return a dictionary of properties for this bundle
+     */
+    private Dictionary getProperties() {
+    	if (bundleProperties == null) {
+    		bundleProperties = new Hashtable();
+
+    		AccessController.doPrivileged(new PrivilegedAction() {
+				public Object run() {
+		    		//set Id
+		    		bundleProperties.put("id",new Long(bundle.getBundleId())); //$NON-NLS-1$
+		    		
+		    		//set location
+		    		bundleProperties.put("location",bundle.getLocation()); //$NON-NLS-1$
+		    		
+		    		//set name
+		    		if (bundle.getSymbolicName() != null)
+		    			bundleProperties.put("name",bundle.getSymbolicName()); //$NON-NLS-1$
+		    		
+		    		//set signers
+//		    		bundleProperties.put("signer",new SignerWrapper(bundle)); //$NON-NLS-1$
+		    		
+		    		return null;
+				}
+			});
+    	}     		
+    	return bundleProperties;
+    }
+/*
+    private static class SignerWrapper extends Object {
+    	private Bundle bundle;
+    	private String pattern;
+    	public SignerWrapper(String pattern) {
+    		this.pattern = pattern;    			
+    	}
+    	SignerWrapper(Bundle bundle) {
+    		this.bundle = bundle;
+    	}
+    	
+		public boolean equals(Object o) {
+			if (!(o instanceof SignerWrapper))
+				return false;
+			SignerWrapper other = (SignerWrapper) o;
+			AbstractBundle matchBundle = (AbstractBundle) (bundle != null ? bundle : other.bundle);
+			String matchPattern = bundle != null ? other.pattern : pattern;
+			return matchBundle.getBundleData().matchDNChain(matchPattern);
+		}
+    }
+*/    
+
+    /**
+     * Called by <tt><@link AdminPermission#implies(Permission)></tt> on an AdminPermission
+     * which was constructed with a filter.  This method loads a FilterImpl with the
+     * filter specification of this AdminPermission.  The filter is cached so this work
+     * only happens once.
+     * 
+     * This method should only be called on an AdminPermission which was constructed with a 
+     * filter
+     * 
+     * @return a filterImpl for this bundle
+     */
+    private Filter getFilterImpl() {
+        if (filterImpl == null) {
+            try {
+                int pos = filter.indexOf("signer"); //$NON-NLS-1$
+                if (pos != -1){ 
+                
+                    //there may be a signer attribute 
+                    StringBuffer filterBuf = new StringBuffer(filter);
+                    int numAsteriskFound = 0; //use as offset to replace in buffer
+                    
+                    int walkbackPos; //temp pos
+
+                    //find occurences of (signer= and escape out *'s
+                    while (pos != -1) {
+
+                        //walk back and look for '(' to see if this is an attr
+                        walkbackPos = pos-1; 
+                        
+                        //consume whitespace
+                        while(walkbackPos >= 0 && Character.isWhitespace(filter.charAt(walkbackPos))) {
+                            walkbackPos--;
+                        }
+                        if (walkbackPos <0) {
+                            //filter is invalid - FilterImpl will throw error
+                            break;
+                        }
+                        
+                        //check to see if we have unescaped '('
+                        if (filter.charAt(walkbackPos) != '(' || (walkbackPos > 0 && filter.charAt(walkbackPos-1) == '\\')) {
+                            //'(' was escaped or not there
+                            pos = filter.indexOf("signer",pos+6); //$NON-NLS-1$
+                            continue;
+                        }                   
+                        pos+=6; //skip over 'signer'
+
+                        //found signer - consume whitespace before '='
+                        while (Character.isWhitespace(filter.charAt(pos))) {
+                            pos++;
+                        }
+
+                        //look for '='
+                        if (filter.charAt(pos) != '=') {
+                            //attr was signerx - keep looking
+                            pos = filter.indexOf("signer",pos); //$NON-NLS-1$
+                            continue;
+                        }
+                        pos++; //skip over '='
+                        
+                        //found signer value - escape '*'s
+                        while (!(filter.charAt(pos) == ')' && filter.charAt(pos-1) != '\\')) {
+                            if (filter.charAt(pos) == '*') {
+                                filterBuf.insert(pos+numAsteriskFound,'\\');
+                                numAsteriskFound++;
+                            }
+                            pos++;
+                        }
+
+                        //end of signer value - look for more?
+                        pos = filter.indexOf("signer",pos); //$NON-NLS-1$
+                    } //end while (pos != -1)
+                    filter = filterBuf.toString();
+                } //end if (pos != -1)
+
+                filterImpl = new FilterImpl(filter);
+            } catch (InvalidSyntaxException e) {
+                //we will return null
+            }
+        }           
+        return filterImpl;
+    }
+
+    /**
+     * Determines if the specified permission is implied by this object.
+     * This method throws an exception if the specified permission was not
+     * constructed with a bundle.
+     * 
+     * <p>This method returns <code>true</code> if
+     * The specified permission is an AdminPermission AND
+     * <ul>
+     * 	<li>this object's filter is an X.500 Distinguished name suffix that 
+     * matches the specified permission's bundle OR
+     * 	<li>this object's filter is "*" OR
+     * 	<li>this object's bundle is a equal to the specified permission's
+     * bundle
+     * </ul>
+     * AND this object's actions include all of the specified permission's actions 	 
+     *
+     * Special case: if the specified permission was constructed with "*", then this method
+     * returns <code>true</code> if this object's filter is "*" and this object's actions include
+     * all of the specified permission's actions
+     * 
+     * @param p The permission to interrogate.
+     *
+     * @return <code>true</code> if the specified permission is implied by
+     * this object; <code>false</code> otherwise.
+     * @throws RuntimeException if specified permission was not constructed with
+     * a bundle or "*"
+     */
+    public boolean implies(Permission p)
+    {
+    	if (!(p instanceof AdminPermission))
+    		return false;
+    	AdminPermission target = (AdminPermission)p;
+    	//check actions first - much faster
+    	if ((action_mask & target.action_mask)!=target.action_mask)
+    		return false;
+    	//if passed in a filter, puke
+    	if (target.filter != null)
+    		throw new RuntimeException("Cannot imply a filter");
+    	//special case - only wildcard implies wildcard
+    	if (target.wildcard)
+    		return wildcard;
+
+    	//check our name 
+    	if (filter != null) {
+    		//it's a filter
+    		Filter filterImpl = getFilterImpl();
+			return filterImpl != null && filterImpl.match(target.getProperties());
+    	} else if (wildcard) {
+    		//it's "*"
+    		return true;
+    	} else {
+    		//it's a bundle id
+    		return bundle.equals(target.bundle);
+    	}
+    	    	
+    }
+    
+    /**
+     * Returns the canonical string representation of the <code>AdminPermission</code> actions.
+     *
+     * <p>Always returns present <code>AdminPermission</code> actions in the following order:
+     * <code>CLASS</code>, <code>EXECUTE</code>, <code>LIFECYCLE</code>, <code>LISTENER</code>, 
+     * <code>METADATA</code>, <code>PERMISSION</code>, <code>RESOLVE</code>, <code>RESOURCE</code>, 
+     * <code>STARTLEVEL</code>.
+     * @return Canonical string representation of the <code>AdminPermission</code> actions.
+     */
+	public String getActions() {
+		if (actions == null) {
+			if (action_mask == ACTION_ALL) {
+				actions = "*"; //$NON-NLS-1$
+			} else {
+				StringBuffer sb = new StringBuffer();
+				
+				if ((action_mask & ACTION_CLASS) == ACTION_CLASS) {
+					sb.append(CLASS);
+					sb.append(',');
+				}
+
+				if ((action_mask & ACTION_EXECUTE) == ACTION_EXECUTE) {
+					sb.append(EXECUTE);
+					sb.append(',');
+				}
+	
+				if ((action_mask & ACTION_LIFECYCLE) == ACTION_LIFECYCLE) {
+					sb.append(LIFECYCLE);
+					sb.append(',');
+				}
+	
+				if ((action_mask & ACTION_LISTENER) == ACTION_LISTENER) {
+					sb.append(LISTENER);
+					sb.append(',');
+				}
+				
+				if ((action_mask & ACTION_METADATA) == ACTION_METADATA) {
+					sb.append(METADATA);
+					sb.append(',');
+				}
+	
+				if ((action_mask & ACTION_PERMISSION) == ACTION_PERMISSION) {
+					sb.append(PERMISSION);
+					sb.append(',');
+				}
+	
+				if ((action_mask & ACTION_RESOLVE) == ACTION_RESOLVE) {
+					sb.append(RESOLVE);
+					sb.append(',');
+				}
+	
+				if ((action_mask & ACTION_RESOURCE) == ACTION_RESOURCE) {
+					sb.append(RESOURCE);
+					sb.append(',');
+				}
+	
+				if ((action_mask & ACTION_STARTLEVEL) == ACTION_STARTLEVEL) {
+					sb.append(STARTLEVEL);
+					sb.append(',');
+				}
+
+				if ((action_mask & ACTION_EXTENSIONLIFECYCLE) == ACTION_EXTENSIONLIFECYCLE) {
+					sb.append(EXTENSIONLIFECYCLE);
+					sb.append(',');
+				}
+
+				//remove trailing comma
+				if (sb.length() > 0) {
+					sb.deleteCharAt(sb.length()-1);
+				}
+				
+				actions = sb.toString();
+			}
+		}
+		return actions;
+	}
+	
+    /**
+     * Determines the equality of two <code>AdminPermission</code> objects. <p>Two 
+     * <code>AdminPermission</code> objects are equal.
+     *
+     * @param obj The object being compared for equality with this object.
+     * @return <code>true</code> if <code>obj</code> is equivalent to this 
+     * <code>AdminPermission</code>; <code>false</code> otherwise.
+     */
+    public boolean equals(Object obj)
+    {
+        if (obj == this) {
+        	return true;
+        }
+        
+        if (!(obj instanceof AdminPermission))
+        {
+            return false;
+        }
+        
+        AdminPermission a = (AdminPermission) obj;
+
+        return (action_mask == a.action_mask) &&
+        		(wildcard == a.wildcard) &&
+        		(bundle == null ? a.bundle == null : (a.bundle == null ? false : bundle.getBundleId() == a.bundle.getBundleId())) &&
+				(filter == null ? a.filter == null : filter.equals(a.filter));
+    }
+
+    /**
+     * Returns the hash code value for this object.
+     *
+     * @return Hash code value for this object.
+     */
+	public int hashCode() {
+		return getName().hashCode() ^ getActions().hashCode();
+	}
+
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		if (filter == null && !wildcard)
+			throw new UnsupportedOperationException("cannot serialize");
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		action_mask = getMask(actions);
+	}
+
+    /**
+     * Returns a new <code>PermissionCollection</code> object suitable for storing
+     * <code>AdminPermission</code>s.
+     * 
+     * @return A new <code>PermissionCollection</code> object.
+     */
+    public PermissionCollection newPermissionCollection()
+    {
+        return(new AdminPermissionCollection());
+    }
+
+	/**
+	 * Stores a collection of <code>AdminPermission</code>s.
+	 */
+	private final class AdminPermissionCollection extends PermissionCollection
+	{
+		private static final long serialVersionUID = 3906372644575328048L;
+		/**
+	     * Collection of permissions.
+	     *
+	     * @serial
+	     */
+		private Hashtable permissions;
+	
+	    /**
+	     * Create an empty AdminPermissions object.
+	     *
+	     */
+	
+	    public AdminPermissionCollection()
+	    {
+	        permissions = new Hashtable();        
+	    }
+
+	    /**
+	     * Adds a permission to the <code>AdminPermission</code> objects. The key for 
+	     * the hashtable is the name
+	     *
+	     * @param permission The <code>AdminPermission</code> object to add.
+	     *
+	     * @exception IllegalArgumentException If the permission is not an
+	     * <code>AdminPermission</code> instance.
+	     *
+	     * @exception SecurityException If this <code>AdminPermissionCollection</code>
+	     * object has been marked read-only.
+	     */
+	    public void add(Permission permission)
+	    {
+	        if (! (permission instanceof AdminPermission))
+	            throw new IllegalArgumentException("invalid permission: "+
+	                                               permission);
+	        if (isReadOnly())
+	            throw new SecurityException("attempt to add a Permission to a " +
+	                                        "readonly AdminCollection");
+	        AdminPermission ap = (AdminPermission) permission;
+	    	AdminPermission existing = (AdminPermission) permissions.get(ap.getName());
+	    	if (existing != null){
+	    		int oldMask = existing.action_mask;
+	    		int newMask = ap.action_mask;
+	        
+	    		if (oldMask != newMask) {
+	    			permissions.put(existing.getName(),
+	    					new AdminPermission(existing.getName(), oldMask | newMask));
+	    		}
+	    	} else {
+	    		permissions.put(ap.getName(), ap);
+	    	}
+	    }
+	
+	
+	    /**
+	     * Determines if the specified permissions implies the permissions
+	     * expressed in <code>permission</code>.
+	     *
+	     * @param permission The Permission object to compare with the <code>AdminPermission</code>
+	     *  objects in this collection.
+	     *
+	     * @return <code>true</code> if <code>permission</code> is implied by an 
+	     * <code>AdminPermission</code> in this collection, <code>false</code> otherwise.
+	     */
+	    public boolean implies(Permission permission)
+	    {
+	        if (!(permission instanceof AdminPermission))
+	            return(false);
+	
+	        AdminPermission target = (AdminPermission) permission;
+	        
+	        //just iterate one by one
+	        Iterator permItr = permissions.values().iterator();
+	        
+	        while(permItr.hasNext())
+	        	if (((AdminPermission)permItr.next()).implies(target))
+	        		return true;
+	        return false;
+	    }
+	 
+	
+	    /**
+	     * Returns an enumeration of all <code>AdminPermission</code> objects in the
+	     * container.
+	     *
+	     * @return Enumeration of all <code>AdminPermission</code> objects.
+	     */
+	
+	    public Enumeration elements()
+	    {
+	        return(Collections.enumeration(permissions.values()));
+	    }
+	}
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/osgi/framework/AllServiceListener.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/osgi/framework/AllServiceListener.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/osgi/framework/AllServiceListener.java (added)
+++ incubator/oscar/trunk/src/org/osgi/framework/AllServiceListener.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,48 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/AllServiceListener.java,v 1.5 2005/05/13 20:32:55 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2005). All Rights Reserved.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this 
+ * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A <code>ServiceEvent</code> listener.
+ *
+ * <p><code>AllServiceListener</code> is a listener interface that may be implemented by a bundle
+ * developer.
+ * <p>An <code>AllServiceListener</code> object is registered with the Framework using the
+ * <code>BundleContext.addServiceListener</code> method.
+ * <code>AllServiceListener</code> objects are called with a <code>ServiceEvent</code> object when
+ * a service is registered, modified, or is in the process of unregistering.
+ *
+ * <p><code>ServiceEvent</code> object delivery to <code>AllServiceListener</code> objects is filtered by the
+ * filter specified when the listener was registered. If the Java Runtime Environment
+ * supports permissions, then additional filtering is done.
+ * <code>ServiceEvent</code> objects are only delivered to the listener if the bundle which defines
+ * the listener object's class has the appropriate <code>ServicePermission</code> to get the service
+ * using at least one of the named classes the service was registered under.
+ * 
+ * <p>
+ * Unlike normal <code>ServiceListener</code> objects,
+ * <code>AllServiceListener</code> objects receive all ServiceEvent objects regardless of the
+ * whether the package source of the listening bundle is equal to the package source of
+ * the bundle that registered the service. This means that the listener may not be able to
+ * cast the service object to any of its corresponding service interfaces if the service
+ * object is retrieved.
+ * 
+ * @version $Revision: 1.5 $
+ * @see ServiceEvent
+ * @see ServicePermission
+ */
+
+public abstract interface AllServiceListener extends ServiceListener
+{
+	//This is a marker interface
+}
+
+