[FELIX-4712] Upgrade connect to OSGi r5
Upgrade to Java 6
Add support for FrameworkStartLevel, StartLevel and PackageAdmin
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1642172 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/connect/pom.xml b/connect/pom.xml
index 10be23c..c48d887 100644
--- a/connect/pom.xml
+++ b/connect/pom.xml
@@ -49,17 +49,22 @@
<name>Karl Pauls</name>
<email>karlpauls@gmail.com</email>
</developer>
+ <developer>
+ <id>gnodet</id>
+ <name>Guillaume Nodet</name>
+ <email>gnodet@gmail.com</email>
+ </developer>
</developers>
<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
- <version>4.3.1</version>
+ <version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
- <version>4.2.0</version>
+ <version>5.0.0</version>
</dependency>
</dependencies>
<repositories/>
@@ -91,8 +96,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <target>1.5</target>
- <source>1.5</source>
+ <target>1.6</target>
+ <source>1.6</source>
</configuration>
</plugin>
<plugin>
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Requirement.java b/connect/src/main/java/org/apache/felix/connect/BundleAware.java
similarity index 74%
rename from connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Requirement.java
rename to connect/src/main/java/org/apache/felix/connect/BundleAware.java
index 0995898..98c1ccb 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Requirement.java
+++ b/connect/src/main/java/org/apache/felix/connect/BundleAware.java
@@ -16,19 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.felix.connect.felix.framework.capabilityset;
+package org.apache.felix.connect;
-import java.util.List;
+import org.osgi.framework.Bundle;
-public interface Requirement
+public interface BundleAware
{
- String getNamespace();
- SimpleFilter getFilter();
+ void setBundle(Bundle bundle);
- boolean isOptional();
-
- Directive getDirective(String name);
-
- List<Directive> getDirectives();
-}
\ No newline at end of file
+}
diff --git a/connect/src/main/java/org/apache/felix/connect/DirRevision.java b/connect/src/main/java/org/apache/felix/connect/DirRevision.java
index 29a8328..5b49c7d 100644
--- a/connect/src/main/java/org/apache/felix/connect/DirRevision.java
+++ b/connect/src/main/java/org/apache/felix/connect/DirRevision.java
@@ -23,7 +23,7 @@
import java.net.URL;
import java.util.Enumeration;
-class DirRevision extends Revision
+class DirRevision implements Revision
{
private final File m_file;
@@ -38,7 +38,8 @@
return m_file.lastModified();
}
- public Enumeration getEntries()
+ @Override
+ public Enumeration<String> getEntries()
{
return new FileEntriesEnumeration(m_file);
}
@@ -48,18 +49,20 @@
{
try
{
- if (entryName != null) {
- File file = (new File(m_file, (entryName.startsWith("/")) ? entryName.substring(1) : entryName));
- if (file.exists()) {
- return file.toURL();
- }
- }
+ if (entryName != null)
+ {
+ File file = (new File(m_file, (entryName.startsWith("/")) ? entryName.substring(1) : entryName));
+ if (file.exists())
+ {
+ return file.toURI().toURL();
+ }
+ }
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
- return null;
+ return null;
}
diff --git a/connect/src/main/java/org/apache/felix/connect/EntriesEnumeration.java b/connect/src/main/java/org/apache/felix/connect/EntriesEnumeration.java
index c5c4990..d6b753a 100644
--- a/connect/src/main/java/org/apache/felix/connect/EntriesEnumeration.java
+++ b/connect/src/main/java/org/apache/felix/connect/EntriesEnumeration.java
@@ -19,50 +19,62 @@
package org.apache.felix.connect;
import java.util.Enumeration;
+import java.util.NoSuchElementException;
import java.util.zip.ZipEntry;
-class EntriesEnumeration implements Enumeration
+class EntriesEnumeration implements Enumeration<String>
{
- private final Enumeration m_enumeration;
- private final String m_prefix;
- private volatile Object current;
+ private final Enumeration<? extends ZipEntry> m_enumeration;
+ private final String m_prefix;
+ private volatile String current;
- public EntriesEnumeration(Enumeration enumeration)
+ public EntriesEnumeration(Enumeration<? extends ZipEntry> enumeration)
{
this(enumeration, null);
}
-
- public EntriesEnumeration(Enumeration enumeration, String prefix)
- {
- m_enumeration = enumeration;
- m_prefix = prefix;
- }
- public boolean hasMoreElements() {
- while ((current == null) && m_enumeration.hasMoreElements()) {
- String result = (String) ((ZipEntry) m_enumeration.nextElement()).getName();
- if (m_prefix != null){
- if (result.startsWith(m_prefix)) {
- current = result.substring(m_prefix.length());
- }
- }
- else {
- current = result;
- }
- }
- return (current != null);
- }
+ public EntriesEnumeration(Enumeration<? extends ZipEntry> enumeration, String prefix)
+ {
+ m_enumeration = enumeration;
+ m_prefix = prefix;
+ }
- public Object nextElement() {
- try {
- if (hasMoreElements()) {
- return current;
- }
- else {
- return m_enumeration.nextElement();
- }
- } finally {
- current = null;
- }
- }
+ public boolean hasMoreElements()
+ {
+ while ((current == null) && m_enumeration.hasMoreElements())
+ {
+ String result = m_enumeration.nextElement().getName();
+ if (m_prefix != null)
+ {
+ if (result.startsWith(m_prefix))
+ {
+ current = result.substring(m_prefix.length());
+ }
+ }
+ else
+ {
+ current = result;
+ }
+ }
+ return (current != null);
+ }
+
+ public String nextElement()
+ {
+ try
+ {
+ if (hasMoreElements())
+ {
+ return current;
+ }
+ else
+ {
+ throw new NoSuchElementException();
+ }
+ }
+ finally
+ {
+ current = null;
+ }
+ }
}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/EntryFilterEnumeration.java b/connect/src/main/java/org/apache/felix/connect/EntryFilterEnumeration.java
index 2e3de55..01c9d4d 100644
--- a/connect/src/main/java/org/apache/felix/connect/EntryFilterEnumeration.java
+++ b/connect/src/main/java/org/apache/felix/connect/EntryFilterEnumeration.java
@@ -40,8 +40,12 @@
private final Set<String> m_dirEntries = new HashSet<String>();
private final List<T> m_nextEntries = new ArrayList<T>(2);
- public EntryFilterEnumeration(Revision rev, boolean includeFragments,
- String path, String filePattern, boolean recurse,
+ public EntryFilterEnumeration(
+ Revision rev,
+ boolean includeFragments,
+ String path,
+ String filePattern,
+ boolean recurse,
boolean isURLValues)
{
m_revision = rev;
@@ -52,8 +56,7 @@
// Sanity check the parameters.
if (path == null)
{
- throw new IllegalArgumentException(
- "The path for findEntries() cannot be null.");
+ throw new IllegalArgumentException("The path for findEntries() cannot be null.");
}
// Strip leading '/' if present.
if ((path.length() > 0) && (path.charAt(0) == '/'))
@@ -170,8 +173,7 @@
: entryURL;
try
{
- m_nextEntries.add((T) new URL(
- entryURL, "/" + dir));
+ m_nextEntries.add((T) new URL(entryURL, "/" + dir));
}
catch (MalformedURLException ex)
{
@@ -199,8 +201,7 @@
// is a child (not a grandchild) of the initial path, then
// we need
// to check if it matches the file pattern.
- if (m_recurse || (dirSlashIdx < 0)
- || (dirSlashIdx == entryName.length() - 1))
+ if (m_recurse || (dirSlashIdx < 0) || (dirSlashIdx == entryName.length() - 1))
{
// See if the file pattern matches the last element of
// the path.
diff --git a/connect/src/main/java/org/apache/felix/connect/ExportedPackageImpl.java b/connect/src/main/java/org/apache/felix/connect/ExportedPackageImpl.java
new file mode 100644
index 0000000..f769849
--- /dev/null
+++ b/connect/src/main/java/org/apache/felix/connect/ExportedPackageImpl.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.connect;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.service.packageadmin.ExportedPackage;
+
+class ExportedPackageImpl implements ExportedPackage
+{
+ private final BundleCapability m_export;
+
+ public ExportedPackageImpl(BundleCapability export)
+ {
+ m_export = export;
+ }
+
+ public Bundle getExportingBundle()
+ {
+ return m_export.getRevision().getBundle();
+ }
+
+ public Bundle[] getImportingBundles()
+ {
+ // Create set for storing importing bundles.
+ Set<Bundle> result = new HashSet<Bundle>();
+ // Get all importers and requirers for all revisions of the bundle.
+ // The spec says that require-bundle should be returned with importers.
+ for (BundleWire wire : m_export.getRevision().getWiring().getProvidedWires(null))
+ {
+ if (wire.getCapability() == m_export
+ || BundleNamespace.BUNDLE_NAMESPACE.equals(wire.getCapability().getNamespace()))
+ {
+ result.add( wire.getRequirer().getBundle() );
+ }
+ }
+ // Return the results.
+ return result.toArray(new Bundle[result.size()]);
+ }
+
+ public String getName()
+ {
+ return (String) m_export.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+ }
+
+ public String getSpecificationVersion()
+ {
+ return getVersion().toString();
+ }
+
+ public Version getVersion()
+ {
+ return m_export.getAttributes().containsKey(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE)
+ ? (Version) m_export.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE)
+ : Version.emptyVersion;
+ }
+
+ public boolean isRemovalPending()
+ {
+ return false;
+ }
+
+ public String toString()
+ {
+ return getName() + "; version=" + getVersion();
+ }
+}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/FileEntriesEnumeration.java b/connect/src/main/java/org/apache/felix/connect/FileEntriesEnumeration.java
index ab9aa60..0208a37 100644
--- a/connect/src/main/java/org/apache/felix/connect/FileEntriesEnumeration.java
+++ b/connect/src/main/java/org/apache/felix/connect/FileEntriesEnumeration.java
@@ -22,7 +22,7 @@
import java.util.Enumeration;
import java.util.NoSuchElementException;
-class FileEntriesEnumeration implements Enumeration
+class FileEntriesEnumeration implements Enumeration<String>
{
private final File m_dir;
private final File[] m_children;
@@ -39,7 +39,7 @@
return (m_children != null) && (m_counter < m_children.length);
}
- public synchronized Object nextElement()
+ public synchronized String nextElement()
{
if ((m_children == null) || (m_counter >= m_children.length))
{
@@ -52,7 +52,7 @@
// Remove the leading path of the reference directory, since the
// entry paths are supposed to be relative to the root.
- StringBuffer sb = new StringBuffer(abs);
+ StringBuilder sb = new StringBuilder(abs);
sb.delete(0, m_dir.getAbsolutePath().length() + 1);
// Add a '/' to the end of directory entries.
if (m_children[m_counter].isDirectory())
@@ -67,15 +67,14 @@
{
File[] children = dir.listFiles();
File[] combined = children;
- for (int i = 0; i < children.length; i++)
+ for (File aChildren : children)
{
- if (children[i].isDirectory())
+ if (aChildren.isDirectory())
{
- File[] grandchildren = listFilesRecursive(children[i]);
+ File[] grandchildren = listFilesRecursive(aChildren);
if (grandchildren.length > 0)
{
- File[] tmp = new File[combined.length
- + grandchildren.length];
+ File[] tmp = new File[combined.length + grandchildren.length];
System.arraycopy(combined, 0, tmp, 0, combined.length);
System.arraycopy(grandchildren, 0, tmp, combined.length,
grandchildren.length);
diff --git a/connect/src/main/java/org/apache/felix/connect/JarRevision.java b/connect/src/main/java/org/apache/felix/connect/JarRevision.java
index aa8f442..61b6455 100644
--- a/connect/src/main/java/org/apache/felix/connect/JarRevision.java
+++ b/connect/src/main/java/org/apache/felix/connect/JarRevision.java
@@ -18,28 +18,29 @@
*/
package org.apache.felix.connect;
-import java.io.*;
-import java.net.URLStreamHandler;
-import java.net.URLConnection;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
import java.util.Enumeration;
-import java.util.jar.JarFile;
import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
-class JarRevision extends Revision
+class JarRevision implements Revision
{
private final long m_lastModified;
private final JarFile m_jar;
private final URL m_url;
- private final String m_urlString;
- private final String m_prefix;
+ private final String m_urlString;
+ private final String m_prefix;
public JarRevision(JarFile jar, URL url, String prefix, long lastModified)
{
m_jar = jar;
m_url = url;
- m_urlString = m_url.toExternalForm();
- m_prefix = prefix;
+ m_urlString = m_url.toExternalForm();
+ m_prefix = prefix;
if (lastModified > 0)
{
m_lastModified = lastModified;
@@ -56,7 +57,7 @@
return m_lastModified;
}
- public Enumeration getEntries()
+ public Enumeration<String> getEntries()
{
return new EntriesEnumeration(m_jar.entries(), m_prefix);
}
@@ -66,61 +67,69 @@
{
try
{
- if("/".equals(entryName) || "".equals(entryName) || " ".equals(entryName)) {
- return new URL("jar:" + m_urlString + "!/" + ((m_prefix == null) ? "" : m_prefix));
- }
+ if ("/".equals(entryName) || "".equals(entryName) || " ".equals(entryName))
+ {
+ return new URL("jar:" + m_urlString + "!/" + ((m_prefix == null) ? "" : m_prefix));
+ }
if (entryName != null)
- {
- final String target = ((entryName.startsWith("/")) ? entryName.substring(1) : entryName);
- final JarEntry entry = m_jar.getJarEntry(((m_prefix == null) ? "" : m_prefix) + target);
- if ( entry != null) {
- URL result = new URL(null, "jar:" + m_urlString + "!/" + ((m_prefix == null) ? "" : m_prefix) + target, new URLStreamHandler() {
-
-
- protected URLConnection openConnection(final URL u) throws IOException {
- return new java.net.JarURLConnection(u) {
-
- public JarFile getJarFile() {
- return m_jar;
- }
- public void connect() throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- public InputStream getInputStream()
- throws IOException {
-
- String extF = u.toExternalForm();
- JarEntry targetEntry = entry;
- if (!extF.endsWith(target)) {
- extF = extF.substring(extF.indexOf('!') + 2);
- if (m_prefix != null) {
- if (!extF.startsWith(m_prefix)) {
- extF = m_prefix + extF;
- }
- }
- targetEntry = m_jar.getJarEntry(extF);
- }
- return m_jar.getInputStream(targetEntry);
- }
- };
- }
- });
- return result;
- }
- else {
- if (entryName.endsWith("/")) {
- return new URL("jar:" + m_urlString + "!/" + ((m_prefix == null) ? "" : m_prefix) + target);
- }
- }
- }
+ {
+ final String target = ((entryName.startsWith("/")) ? entryName.substring(1) : entryName);
+ final JarEntry entry = m_jar.getJarEntry(((m_prefix == null) ? "" : m_prefix) + target);
+ if (entry != null)
+ {
+ URL result = new URL(null, "jar:" + m_urlString + "!/" + ((m_prefix == null) ? "" : m_prefix) + target, new URLStreamHandler()
+ {
+ protected URLConnection openConnection(final URL u) throws IOException
+ {
+ return new java.net.JarURLConnection(u)
+ {
+
+ public JarFile getJarFile()
+ {
+ return m_jar;
+ }
+
+ public void connect() throws IOException
+ {
+ }
+
+ public InputStream getInputStream() throws IOException
+ {
+ String extF = u.toExternalForm();
+ JarEntry targetEntry = entry;
+ if (!extF.endsWith(target))
+ {
+ extF = extF.substring(extF.indexOf('!') + 2);
+ if (m_prefix != null)
+ {
+ if (!extF.startsWith(m_prefix))
+ {
+ extF = m_prefix + extF;
+ }
+ }
+ targetEntry = m_jar.getJarEntry(extF);
+ }
+ return m_jar.getInputStream(targetEntry);
+ }
+ };
+ }
+ });
+ return result;
+ }
+ else
+ {
+ if (entryName.endsWith("/"))
+ {
+ return new URL("jar:" + m_urlString + "!/" + ((m_prefix == null) ? "" : m_prefix) + target);
+ }
+ }
+ }
}
catch (IOException e)
{
e.printStackTrace();
}
- return null;
+ return null;
}
diff --git a/connect/src/main/java/org/apache/felix/connect/PojoSR.java b/connect/src/main/java/org/apache/felix/connect/PojoSR.java
index 0fcc480..960261e 100644
--- a/connect/src/main/java/org/apache/felix/connect/PojoSR.java
+++ b/connect/src/main/java/org/apache/felix/connect/PojoSR.java
@@ -19,16 +19,21 @@
package org.apache.felix.connect;
import java.io.File;
+import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
+import java.util.Set;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -37,6 +42,7 @@
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
@@ -44,6 +50,11 @@
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;
@@ -59,45 +70,41 @@
public class PojoSR implements PojoServiceRegistry
{
private final BundleContext m_context;
- private final ServiceRegistry m_reg = new ServiceRegistry(
+ private final ServiceRegistry m_registry = new ServiceRegistry(
new ServiceRegistry.ServiceRegistryCallbacks()
{
-
- public void serviceChanged(ServiceEvent event,
- Dictionary oldProps)
+ public void serviceChanged(ServiceEvent event, Dictionary<String, ?> oldProps)
{
m_dispatcher.fireServiceEvent(event, oldProps, null);
}
});
- private final EventDispatcher m_dispatcher = new EventDispatcher(m_reg);
- private final Map<Long, Bundle> m_bundles =new HashMap<Long, Bundle>();
- private final Map<String, Bundle> m_symbolicNameToBundle = new HashMap<String, Bundle>();
- private final Map bundleConfig;
- public PojoSR(Map config) throws Exception
- {
+ private final EventDispatcher m_dispatcher = new EventDispatcher(m_registry);
+ private final Map<Long, Bundle> m_bundles = new HashMap<Long, Bundle>();
+ private final Map<String, Object> bundleConfig;
+
+ public static BundleDescriptor createSystemBundle() {
final Map<String, String> headers = new HashMap<String, String>();
- headers.put(Constants.BUNDLE_SYMBOLICNAME,
- "org.apache.felix.connect");
- headers.put(Constants.BUNDLE_VERSION, "0.1.0-SNAPSHOT");
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, "org.apache.felix.connect");
+ headers.put(Constants.BUNDLE_VERSION, "0.0.0");
headers.put(Constants.BUNDLE_NAME, "System Bundle");
headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
- headers.put(Constants.BUNDLE_VENDOR, "Apache Software Foundation");
- bundleConfig = new HashMap(config);
- final Bundle b = new PojoSRBundle(new Revision()
- {
+ headers.put(Constants.BUNDLE_VENDOR, "Apache Software Foundation");
+
+ Revision revision = new Revision()
+ {
+ final long lastModified = System.currentTimeMillis();
@Override
public long getLastModified()
{
- // TODO Auto-generated method stub
- return System.currentTimeMillis();
+ return lastModified;
}
@Override
- public Enumeration getEntries()
+ public Enumeration<String> getEntries()
{
- return new Properties().elements();
+ return Collections.emptyEnumeration();
}
@Override
@@ -105,26 +112,60 @@
{
return getClass().getClassLoader().getResource(entryName);
}
- }, headers, new Version(0, 0, 1), "file:pojosr", m_reg, m_dispatcher,
- null, 0, "org.apache.felix.connect", m_bundles, getClass()
- .getClassLoader(), bundleConfig)
- {
- @Override
- public synchronized void start() throws BundleException {
- if (m_state != Bundle.RESOLVED) {
- return;
- }
- m_dispatcher.startDispatching();
- m_state = Bundle.STARTING;
+ };
+ Map<Class, Object> services = new HashMap<Class, Object>();
+ services.put(FrameworkStartLevel.class, new FrameworkStartLevelImpl());
+ return new BundleDescriptor(
+ PojoSR.class.getClassLoader(),
+ "felix-connect",
+ headers,
+ revision,
+ services
+ );
+ }
- m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTING,
- this));
- m_context = new PojoSRBundleContext(this, m_reg, m_dispatcher,
- m_bundles, bundleConfig);
+ public PojoSR(Map<String, ?> config) throws Exception
+ {
+ this(config, null);
+ }
+
+ public PojoSR(Map<String, ?> config, BundleDescriptor systemBundle) throws Exception
+ {
+ if (systemBundle == null) {
+ systemBundle = createSystemBundle();
+ }
+ bundleConfig = new HashMap<String, Object>(config);
+ final Bundle b = new PojoSRBundle(
+ m_registry,
+ m_dispatcher,
+ m_bundles,
+ systemBundle.getUrl(),
+ 0,
+ "org.apache.felix.connect",
+ new Version(0, 0, 1),
+ systemBundle.getRevision(),
+ systemBundle.getClassLoader(),
+ systemBundle.getHeaders(),
+ systemBundle.getServices(),
+ bundleConfig)
+ {
+ @Override
+ public synchronized void start() throws BundleException
+ {
+ if (m_state != Bundle.RESOLVED)
+ {
+ return;
+ }
+ m_dispatcher.startDispatching();
+ m_state = Bundle.STARTING;
+
+ m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTING, this));
+ m_context = new PojoSRBundleContext(this, m_registry, m_dispatcher, m_bundles, bundleConfig);
int i = 0;
- for (Bundle b : m_bundles.values()) {
- i++;
- try
+ for (Bundle b : m_bundles.values())
+ {
+ i++;
+ try
{
if (b != this)
{
@@ -133,327 +174,223 @@
}
catch (Throwable t)
{
- System.out.println("Unable to start bundle: " + i );
- t.printStackTrace();
+ System.out.println("Unable to start bundle: " + i);
+ t.printStackTrace();
}
}
m_state = Bundle.ACTIVE;
- m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTED,
- this));
+ m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTED, this));
m_dispatcher.fireFrameworkEvent(new FrameworkEvent(FrameworkEvent.STARTED, this, null));
- super.start();
- };
+ super.start();
+ }
+
@Override
public synchronized void stop() throws BundleException
{
- if ((m_state == Bundle.STOPPING) || m_state == Bundle.RESOLVED) {
- return;
+ if ((m_state == Bundle.STOPPING) || m_state == Bundle.RESOLVED)
+ {
+ return;
- }
- else if (m_state != Bundle.ACTIVE) {
- throw new BundleException("Can't stop pojosr because it is not ACTIVE");
- }
- final Bundle systemBundle = this;
- Runnable r = new Runnable() {
+ }
+ else if (m_state != Bundle.ACTIVE)
+ {
+ throw new BundleException("Can't stop pojosr because it is not ACTIVE");
+ }
+ final Bundle systemBundle = this;
+ Runnable r = new Runnable()
+ {
- public void run() {
- m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPING,
- systemBundle));
- for (Bundle b : m_bundles.values())
- {
- try
- {
- if (b != systemBundle)
- {
- b.stop();
- }
- }
- catch (Throwable t)
- {
- t.printStackTrace();
- }
- }
- m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED,
- systemBundle));
- m_state = Bundle.RESOLVED;
- m_dispatcher.stopDispatching();
- }
- };
- m_state = Bundle.STOPPING;
- if ("true".equalsIgnoreCase(System.getProperty("org.apache.felix.connect.events.sync"))) {
- r.run();
- }
- else {
- new Thread(r).start();
- }
+ public void run()
+ {
+ m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPING, systemBundle));
+ for (Bundle b : m_bundles.values())
+ {
+ try
+ {
+ if (b != systemBundle)
+ {
+ b.stop();
+ }
+ }
+ catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
+ }
+ m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED, systemBundle));
+ m_state = Bundle.RESOLVED;
+ m_dispatcher.stopDispatching();
+ }
+ };
+ m_state = Bundle.STOPPING;
+ if ("true".equalsIgnoreCase(System.getProperty("org.apache.felix.connect.events.sync")))
+ {
+ r.run();
+ }
+ else
+ {
+ new Thread(r).start();
+ }
}
};
- m_symbolicNameToBundle.put(b.getSymbolicName(), b);
+ m_bundles.put(0l, b);
b.start();
- b.getBundleContext().registerService(StartLevel.class.getName(),
- new StartLevel()
- {
+ b.getBundleContext().registerService(StartLevel.class.getName(), new StartLevelImpl(), null);
- public void setStartLevel(int startlevel)
- {
- // TODO Auto-generated method stub
-
- }
-
- public void setInitialBundleStartLevel(int startlevel)
- {
- // TODO Auto-generated method stub
-
- }
-
- public void setBundleStartLevel(Bundle bundle,
- int startlevel)
- {
- // TODO Auto-generated method stub
-
- }
-
- public boolean isBundlePersistentlyStarted(Bundle bundle)
- {
- // TODO Auto-generated method stub
- return true;
- }
-
- public boolean isBundleActivationPolicyUsed(Bundle bundle)
- {
- // TODO Auto-generated method stub
- return false;
- }
-
- public int getStartLevel()
- {
- // TODO Auto-generated method stub
- return 1;
- }
-
- public int getInitialBundleStartLevel()
- {
- // TODO Auto-generated method stub
- return 1;
- }
-
- public int getBundleStartLevel(Bundle bundle)
- {
- // TODO Auto-generated method stub
- return 1;
- }
- }, null);
-
- b.getBundleContext().registerService(PackageAdmin.class.getName(),
- new PackageAdmin()
- {
-
- public boolean resolveBundles(Bundle[] bundles)
- {
- // TODO Auto-generated method stub
- return true;
- }
-
- public void refreshPackages(Bundle[] bundles)
- {
- m_dispatcher.fireFrameworkEvent(new FrameworkEvent(
- FrameworkEvent.PACKAGES_REFRESHED, b, null));
- }
-
- public RequiredBundle[] getRequiredBundles(
- String symbolicName)
- {
- return null;
- }
-
- public Bundle[] getHosts(Bundle bundle)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- public Bundle[] getFragments(Bundle bundle)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- public ExportedPackage[] getExportedPackages(String name)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- public ExportedPackage[] getExportedPackages(Bundle bundle)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- public ExportedPackage getExportedPackage(String name)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- public Bundle[] getBundles(String symbolicName,
- String versionRange)
- {
- Bundle result = m_symbolicNameToBundle.get((symbolicName != null) ? symbolicName.trim() : symbolicName);
- if (result != null) {
- return new Bundle[] {result};
- }
- return null;
- }
-
- public int getBundleType(Bundle bundle)
- {
- return 0;
- }
-
- public Bundle getBundle(Class clazz)
- {
- return m_context.getBundle();
- }
- }, null);
+ b.getBundleContext().registerService(PackageAdmin.class.getName(), new PackageAdminImpl(), null);
m_context = b.getBundleContext();
- List<BundleDescriptor> scan = (List<BundleDescriptor>) config
- .get(PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS);
+ Collection<BundleDescriptor> scan = (Collection<BundleDescriptor>) config.get(PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS);
if (scan != null)
{
startBundles(scan);
- }
+ }
}
- public void startBundles(List<BundleDescriptor> scan) throws Exception {
- for (BundleDescriptor desc : scan)
+ public void startBundles(Collection<BundleDescriptor> scan) throws Exception
+ {
+ for (BundleDescriptor desc : scan)
+ {
+ Revision revision = desc.getRevision();
+ if (revision == null)
{
- URL u = new URL(desc.getUrl().toExternalForm()
- + "META-INF/MANIFEST.MF");
- Revision r;
- if (u.toExternalForm().startsWith("file:"))
+ revision = buildRevision(desc);
+ }
+ Map<String, String> bundleHeaders = desc.getHeaders();
+ Version osgiVersion;
+ try
+ {
+ osgiVersion = Version.parseVersion(bundleHeaders.get(Constants.BUNDLE_VERSION));
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ osgiVersion = Version.emptyVersion;
+ }
+ String sym = bundleHeaders.get(Constants.BUNDLE_SYMBOLICNAME);
+ if (sym != null)
+ {
+ int idx = sym.indexOf(';');
+ if (idx > 0)
{
- File root = new File(URLDecoder.decode(desc.getUrl()
- .getFile(), "UTF-8"));
- u = root.toURL();
- r = new DirRevision(root);
+ sym = sym.substring(0, idx);
}
- else
- {
- URLConnection uc = u.openConnection();
- if (uc instanceof JarURLConnection)
- {
- String target = ((JarURLConnection) uc).getJarFileURL().toExternalForm();
- String prefix = null;
- if (!("jar:" + target + "!/").equals(desc.getUrl().toExternalForm())) {
- prefix = desc.getUrl().toExternalForm().substring(("jar:" + target + "!/").length());
- }
- r = new JarRevision(
- ((JarURLConnection) uc).getJarFile(),
- ((JarURLConnection) uc).getJarFileURL(),
- prefix,
- uc.getLastModified());
- }
- else
- {
- r = new URLRevision(desc.getUrl(), desc.getUrl()
- .openConnection().getLastModified());
- }
- }
- Map<String, String> bundleHeaders = desc.getHeaders();
- Version osgiVersion = null;
- try {
- osgiVersion = Version.parseVersion(bundleHeaders.get(Constants.BUNDLE_VERSION));
- } catch (Exception ex) {
- ex.printStackTrace();
- osgiVersion = Version.emptyVersion;
- }
- String sym = bundleHeaders.get(Constants.BUNDLE_SYMBOLICNAME);
- if (sym != null)
- {
- int idx = sym.indexOf(';');
- if (idx > 0)
- {
- sym = sym.substring(0, idx);
- }
- sym = sym.trim();
- }
-
- if ((sym == null)
- || !m_symbolicNameToBundle.containsKey( sym ))
- {
- // TODO: framework - support multiple versions
- Bundle bundle = new PojoSRBundle(r, bundleHeaders,
- osgiVersion, desc.getUrl().toExternalForm(), m_reg,
- m_dispatcher,
- bundleHeaders.get(Constants.BUNDLE_ACTIVATOR),
- m_bundles.size(),
- sym,
- m_bundles, desc.getClassLoader(), bundleConfig);
- if (sym != null)
- {
- m_symbolicNameToBundle.put(bundle.getSymbolicName(),
- bundle);
- }
- }
-
+ sym = sym.trim();
}
+ Bundle bundle = new PojoSRBundle(
+ m_registry,
+ m_dispatcher,
+ m_bundles,
+ desc.getUrl(),
+ m_bundles.size(),
+ sym,
+ osgiVersion,
+ revision,
+ desc.getClassLoader(),
+ bundleHeaders,
+ desc.getServices(),
+ bundleConfig);
+ m_bundles.put(bundle.getBundleId(), bundle);
+ }
- for (long i = 1; i < m_bundles.size(); i++)
+
+ for (Bundle bundle : m_bundles.values())
{
try
{
- m_bundles.get(i).start();
+ bundle.start();
}
catch (Throwable e)
{
- System.out.println("Unable to start bundle: " + i);
+ System.out.println("Unable to start bundle: " + bundle);
e.printStackTrace();
}
}
- }
+ }
+
+ private Revision buildRevision(BundleDescriptor desc) throws IOException
+ {
+ Revision r;
+ URL url = new URL(desc.getUrl());
+ URL u = new URL(desc.getUrl() + "META-INF/MANIFEST.MF");
+ if (u.toExternalForm().startsWith("file:"))
+ {
+ File root = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
+ r = new DirRevision(root);
+ }
+ else
+ {
+ URLConnection uc = u.openConnection();
+ if (uc instanceof JarURLConnection)
+ {
+ String target = ((JarURLConnection) uc).getJarFileURL().toExternalForm();
+ String prefix = null;
+ if (!("jar:" + target + "!/").equals(desc.getUrl()))
+ {
+ prefix = desc.getUrl().substring(("jar:" + target + "!/").length());
+ }
+ r = new JarRevision(
+ ((JarURLConnection) uc).getJarFile(),
+ ((JarURLConnection) uc).getJarFileURL(),
+ prefix,
+ uc.getLastModified());
+ }
+ else
+ {
+ r = new URLRevision(url, url.openConnection().getLastModified());
+ }
+ }
+ return r;
+ }
public static void main(String[] args) throws Exception
{
- Filter filter = null;
- Class main = null;
- for (int i = 0;(args != null) && (i < args.length) && (i < 2); i++) {
- try {
- filter = FrameworkUtil.createFilter(args[i]);
- } catch (InvalidSyntaxException ie) {
- try {
- main = PojoSR.class.getClassLoader().loadClass(args[i]);
- } catch (Exception ex) {
- throw new IllegalArgumentException("Argument is neither a filter nor a class: " + args[i]);
- }
- }
- }
- Map config = new HashMap();
+ Filter filter = null;
+ Class<?> main = null;
+ for (int i = 0; (args != null) && (i < args.length) && (i < 2); i++)
+ {
+ try
+ {
+ filter = FrameworkUtil.createFilter(args[i]);
+ }
+ catch (InvalidSyntaxException ie)
+ {
+ try
+ {
+ main = PojoSR.class.getClassLoader().loadClass(args[i]);
+ }
+ catch (Exception ex)
+ {
+ throw new IllegalArgumentException("Argument is neither a filter nor a class: " + args[i]);
+ }
+ }
+ }
+ Map<String, Object> config = new HashMap<String, Object>();
config.put(
PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS,
(filter != null) ? new ClasspathScanner()
.scanForBundles(filter.toString()) : new ClasspathScanner()
.scanForBundles());
new PojoServiceRegistryFactoryImpl().newPojoServiceRegistry(config);
- if (main != null) {
- int count = 0;
- if (filter != null) {
- count++;
- }
- if (main != null) {
- count++;
- }
- String[] newArgs = args;
- if (count > 0) {
- newArgs = new String[args.length - count];
- System.arraycopy(args, count, newArgs, 0, newArgs.length);
- }
- main.getMethod("main", String[].class).invoke(null, (Object) newArgs );
+ if (main != null)
+ {
+ int count = 0;
+ if (filter != null)
+ {
+ count++;
+ }
+ count++;
+ String[] newArgs = args;
+ if (count > 0)
+ {
+ newArgs = new String[args.length - count];
+ System.arraycopy(args, count, newArgs, 0, newArgs.length);
+ }
+ main.getMethod("main", String[].class).invoke(null, newArgs);
}
}
@@ -462,52 +399,281 @@
return m_context;
}
- public void addServiceListener(ServiceListener listener, String filter)
- throws InvalidSyntaxException
+ @Override
+ public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException
{
m_context.addServiceListener(listener, filter);
}
+ @Override
public void addServiceListener(ServiceListener listener)
{
m_context.addServiceListener(listener);
}
+ @Override
public void removeServiceListener(ServiceListener listener)
{
m_context.removeServiceListener(listener);
}
- public ServiceRegistration registerService(String[] clazzes,
- Object service, Dictionary properties)
+ @Override
+ public ServiceRegistration<?> registerService(String[] clazzes, Object service, Dictionary<String, ?> properties)
{
return m_context.registerService(clazzes, service, properties);
}
- public ServiceRegistration registerService(String clazz, Object service,
- Dictionary properties)
+ @Override
+ public ServiceRegistration<?> registerService(String clazz, Object service, Dictionary<String, ?> properties)
{
return m_context.registerService(clazz, service, properties);
}
- public ServiceReference[] getServiceReferences(String clazz, String filter)
- throws InvalidSyntaxException
+ @Override
+ public ServiceReference<?>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException
{
return m_context.getServiceReferences(clazz, filter);
}
- public ServiceReference getServiceReference(String clazz)
+ @Override
+ public ServiceReference<?> getServiceReference(String clazz)
{
return m_context.getServiceReference(clazz);
}
- public Object getService(ServiceReference reference)
+ @Override
+ public <S> S getService(ServiceReference<S> reference)
{
return m_context.getService(reference);
}
- public boolean ungetService(ServiceReference reference)
+ @Override
+ public boolean ungetService(ServiceReference<?> reference)
{
return m_context.ungetService(reference);
}
+
+ private static class FrameworkStartLevelImpl implements FrameworkStartLevel, BundleAware
+ {
+
+ private Bundle bundle;
+
+ @Override
+ public void setBundle(Bundle bundle)
+ {
+ this.bundle = bundle;
+ }
+
+ @Override
+ public int getStartLevel()
+ {
+ return 0;
+ }
+
+ @Override
+ public void setStartLevel(int startlevel, FrameworkListener... listeners)
+ {
+ }
+
+ @Override
+ public int getInitialBundleStartLevel()
+ {
+ return 0;
+ }
+
+ @Override
+ public void setInitialBundleStartLevel(int startlevel)
+ {
+ }
+
+ @Override
+ public Bundle getBundle()
+ {
+ return bundle;
+ }
+ }
+
+ private static class StartLevelImpl implements StartLevel
+ {
+ @Override
+ public void setStartLevel(int startlevel)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void setInitialBundleStartLevel(int startlevel)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void setBundleStartLevel(Bundle bundle, int startlevel)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public boolean isBundlePersistentlyStarted(Bundle bundle)
+ {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @Override
+ public boolean isBundleActivationPolicyUsed(Bundle bundle)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public int getStartLevel()
+ {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+
+ @Override
+ public int getInitialBundleStartLevel()
+ {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+
+ @Override
+ public int getBundleStartLevel(Bundle bundle)
+ {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+ }
+
+ private class PackageAdminImpl implements PackageAdmin
+ {
+
+ @Override
+ public boolean resolveBundles(Bundle[] bundles)
+ {
+ return true;
+ }
+
+ @Override
+ public void refreshPackages(Bundle[] bundles)
+ {
+ FrameworkEvent event = new FrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, m_bundles.get(0l), null);
+ m_dispatcher.fireFrameworkEvent(event);
+ }
+
+ @Override
+ public RequiredBundle[] getRequiredBundles(String symbolicName)
+ {
+ List list = new ArrayList();
+ for (Bundle bundle : PojoSR.this.m_bundles.values())
+ {
+ if ((symbolicName == null) || (symbolicName.equals(bundle.getSymbolicName())))
+ {
+ list.add(new RequiredBundleImpl(bundle));
+ }
+ }
+ return (list.isEmpty())
+ ? null
+ : (RequiredBundle[]) list.toArray(new RequiredBundle[list.size()]);
+ }
+
+ @Override
+ public Bundle[] getHosts(Bundle bundle)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Bundle[] getFragments(Bundle bundle)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ExportedPackage[] getExportedPackages(String name)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ExportedPackage[] getExportedPackages(Bundle bundle)
+ {
+ List<ExportedPackage> list = new ArrayList<ExportedPackage>();
+ // If a bundle is specified, then return its
+ // exported packages.
+ if (bundle != null)
+ {
+ getExportedPackages(bundle, list);
+ }
+ // Otherwise return all exported packages.
+ else
+ {
+ for (Bundle b : m_bundles.values())
+ {
+ getExportedPackages(b, list);
+ }
+ }
+ return list.isEmpty() ? null : list.toArray(new ExportedPackage[list.size()]);
+ }
+
+ private void getExportedPackages(Bundle bundle, List<ExportedPackage> list)
+ {
+ // Since a bundle may have many revisions associated with it,
+ // one for each revision in the cache, search each revision
+ // to get all exports.
+ for (BundleCapability cap : bundle.adapt(BundleWiring.class).getCapabilities(null))
+ {
+ if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
+ {
+ list.add(new ExportedPackageImpl(cap));
+ }
+ }
+ }
+
+ @Override
+ public ExportedPackage getExportedPackage(String name)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Bundle[] getBundles(String symbolicName, String versionRange)
+ {
+ Set<Bundle> result = new HashSet<Bundle>();
+ VersionRange range = versionRange != null ? new VersionRange(versionRange) : null;
+ for (Bundle bundle : m_bundles.values())
+ {
+ if (symbolicName != null && !bundle.getSymbolicName().equals(symbolicName))
+ {
+ continue;
+ }
+ if (range != null && !range.includes(bundle.getVersion()))
+ {
+ continue;
+ }
+ result.add(bundle);
+ }
+ return result.isEmpty() ? null : result.toArray(new Bundle[result.size()]);
+ }
+
+ @Override
+ public int getBundleType(Bundle bundle)
+ {
+ return bundle.adapt(BundleRevision.class).getTypes();
+ }
+
+ @Override
+ public Bundle getBundle(Class clazz)
+ {
+ return m_context.getBundle();
+ }
+ }
}
diff --git a/connect/src/main/java/org/apache/felix/connect/PojoSRBundle.java b/connect/src/main/java/org/apache/felix/connect/PojoSRBundle.java
index 9c7a570..df26329 100644
--- a/connect/src/main/java/org/apache/felix/connect/PojoSRBundle.java
+++ b/connect/src/main/java/org/apache/felix/connect/PojoSRBundle.java
@@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -29,7 +30,6 @@
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -51,21 +51,23 @@
import org.osgi.framework.wiring.BundleRevisions;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
-
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Wire;
import org.apache.felix.connect.felix.framework.ServiceRegistry;
import org.apache.felix.connect.felix.framework.util.EventDispatcher;
import org.apache.felix.connect.felix.framework.util.MapToDictionary;
import org.apache.felix.connect.felix.framework.util.StringMap;
-class PojoSRBundle implements Bundle, BundleRevisions, BundleRevision
+class PojoSRBundle implements Bundle, BundleRevisions
{
private final Revision m_revision;
- private final Map<String, String> m_manifest;
+ private final Map<String, String> m_headers;
private final Version m_version;
private final String m_location;
private final Map<Long, Bundle> m_bundles;
- private final ServiceRegistry m_reg;
+ private final ServiceRegistry m_registry;
private final String m_activatorClass;
private final long m_id;
private final String m_symbolicName;
@@ -73,45 +75,62 @@
volatile int m_state = Bundle.RESOLVED;
volatile BundleContext m_context = null;
private final EventDispatcher m_dispatcher;
- private final ClassLoader m_loader;
+ private final ClassLoader m_classLoader;
+ private final Map<Class, Object> m_services;
private final Map m_config;
- Revision getRevision()
- {
- return m_revision;
- }
-
- public PojoSRBundle(Revision revision, Map<String, String> manifest,
- Version version, String location, ServiceRegistry reg,
- EventDispatcher dispatcher, String activatorClass, long id,
- String symbolicName, Map<Long, Bundle> bundles, ClassLoader loader, Map config)
+ public PojoSRBundle(ServiceRegistry registry,
+ EventDispatcher dispatcher,
+ Map<Long, Bundle> bundles,
+ String location,
+ long id,
+ String symbolicName,
+ Version version,
+ Revision revision,
+ ClassLoader classLoader,
+ Map<String, String> headers,
+ Map<Class, Object> services,
+ Map<? extends Object, ? extends Object> config)
{
m_revision = revision;
- m_manifest = manifest;
+ m_headers = headers;
m_version = version;
m_location = location;
- m_reg = reg;
+ m_registry = registry;
m_dispatcher = dispatcher;
- m_activatorClass = activatorClass;
+ m_activatorClass = headers.get(Constants.BUNDLE_ACTIVATOR);
m_id = id;
m_symbolicName = symbolicName;
- bundles.put(m_id, this);
m_bundles = bundles;
- m_loader = loader;
+ m_classLoader = classLoader;
+ m_services = services;
m_config = config;
+ if (classLoader instanceof BundleAware) {
+ ((BundleAware) classLoader).setBundle(this);
+ }
+ if (services != null) {
+ for (Object o : services.values()) {
+ if (o instanceof BundleAware) {
+ ((BundleAware) o).setBundle(this);
+ }
+ }
+ }
}
+ @Override
public int getState()
{
return m_state;
}
+ @Override
public void start(int options) throws BundleException
{
// TODO: lifecycle - fix this
start();
}
+ @Override
public synchronized void start() throws BundleException
{
if (m_state != Bundle.RESOLVED)
@@ -126,36 +145,33 @@
{
m_state = Bundle.STARTING;
- m_context = new PojoSRBundleContext(this, m_reg, m_dispatcher,
- m_bundles, m_config);
- m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTING,
- this));
+ m_context = new PojoSRBundleContext(this, m_registry, m_dispatcher, m_bundles, m_config);
+ m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTING, this));
if (m_activatorClass != null)
{
- m_activator = (BundleActivator) m_loader.loadClass(
- m_activatorClass).newInstance();
+ m_activator = (BundleActivator) m_classLoader.loadClass(m_activatorClass).newInstance();
m_activator.start(m_context);
}
m_state = Bundle.ACTIVE;
- m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTED,
- this));
+ m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTED, this));
}
catch (Throwable ex)
{
m_state = Bundle.RESOLVED;
m_activator = null;
- m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED,
- this));
+ m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED, this));
throw new BundleException("Unable to start bundle", ex);
}
}
+ @Override
public void stop(int options) throws BundleException
{
// TODO: lifecycle - fix this
stop();
}
+ @Override
public synchronized void stop() throws BundleException
{
if (m_state != Bundle.ACTIVE)
@@ -182,7 +198,7 @@
}
finally
{
- m_reg.unregisterServices(this);
+ m_registry.unregisterServices(this);
m_dispatcher.removeListeners(m_context);
m_activator = null;
m_context = null;
@@ -192,72 +208,83 @@
}
}
+ @Override
public void update(InputStream input) throws BundleException
{
throw new BundleException("pojosr bundles can't be updated");
}
+ @Override
public void update() throws BundleException
{
throw new BundleException("pojosr bundles can't be updated");
}
+ @Override
public void uninstall() throws BundleException
{
throw new BundleException("pojosr bundles can't be uninstalled");
}
- public Dictionary getHeaders()
+ @Override
+ public Dictionary<String, String> getHeaders()
{
return getHeaders(Locale.getDefault().toString());
}
+ @Override
public long getBundleId()
{
return m_id;
}
+ @Override
public String getLocation()
{
return m_location;
}
- public ServiceReference[] getRegisteredServices()
+ @Override
+ public ServiceReference<?>[] getRegisteredServices()
{
- return m_reg.getRegisteredServices(this);
+ return m_registry.getRegisteredServices(this);
}
- public ServiceReference[] getServicesInUse()
+ @Override
+ public ServiceReference<?>[] getServicesInUse()
{
- return m_reg.getServicesInUse(this);
+ return m_registry.getServicesInUse(this);
}
+ @Override
public boolean hasPermission(Object permission)
{
// TODO: security - fix this
return true;
}
+ @Override
public URL getResource(String name)
{
// TODO: module - implement this based on the revision
- URL result = m_loader.getResource(name);
+ URL result = m_classLoader.getResource(name);
return result;
}
- public Dictionary getHeaders(String locale)
+ @Override
+ public Dictionary<String, String> getHeaders(String locale)
{
- return new MapToDictionary(getCurrentLocalizedHeader(locale));
+ return new MapToDictionary<String, String>(getCurrentLocalizedHeader(locale));
}
- Map getCurrentLocalizedHeader(String locale)
+ Map<String, String> getCurrentLocalizedHeader(String locale)
{
- Map result = null;
+ Map<String, String> result = null;
// Spec says empty local returns raw headers.
if ((locale == null) || (locale.length() == 0))
{
- result = new StringMap(m_manifest, false);
+ result = new StringMap<String>(m_headers, false);
}
// If we have no result, try to get it from the cached headers.
@@ -270,7 +297,7 @@
// the time of uninstall, so just return that.
if (getState() == Bundle.UNINSTALLED)
{
- result = (Map) m_cachedHeaders.values().iterator().next();
+ result = m_cachedHeaders.values().iterator().next();
}
// If the bundle has been updated, clear the cached headers.
else if (getLastModified() > m_cachedHeadersTimestamp)
@@ -280,12 +307,8 @@
// Otherwise, returned the cached headers if they exist.
else
{
- // Check if headers for this locale have already been
- // resolved
- if (m_cachedHeaders.containsKey(locale))
- {
- result = (Map) m_cachedHeaders.get(locale);
- }
+ // Check if headers for this locale have already been resolved
+ result = m_cachedHeaders.get(locale);
}
}
}
@@ -294,18 +317,18 @@
if (result == null)
{
// Get a modifiable copy of the raw headers.
- Map headers = new StringMap(m_manifest, false);
+ Map<String, String> headers = new StringMap<String>(m_headers, false);
// Assume for now that this will be the result.
result = headers;
// Check to see if we actually need to localize anything
boolean localize = false;
- for (Iterator it = headers.values().iterator(); !localize
- && it.hasNext();)
+ for (String s : headers.values())
{
- if (((String) it.next()).startsWith("%"))
+ if ((s).startsWith("%"))
{
localize = true;
+ break;
}
}
@@ -319,31 +342,28 @@
else
{
// Do localization here and return the localized headers
- String basename = (String) headers
- .get(Constants.BUNDLE_LOCALIZATION);
+ String basename = headers.get(Constants.BUNDLE_LOCALIZATION);
if (basename == null)
{
basename = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
}
// Create ordered list of files to load properties from
- List resourceList = createLocalizationResourceList(basename,
- locale);
+ List<String> resourceList = createLocalizationResourceList(basename, locale);
// Create a merged props file with all available props for this
// locale
boolean found = false;
Properties mergedProperties = new Properties();
- for (Iterator it = resourceList.iterator(); it.hasNext();)
+ for (String aResourceList : resourceList)
{
- URL temp = m_revision.getEntry(it.next() + ".properties");
+ URL temp = m_revision.getEntry(aResourceList + ".properties");
if (temp != null)
{
found = true;
try
{
- mergedProperties.load(temp.openConnection()
- .getInputStream());
+ mergedProperties.load(temp.openConnection().getInputStream());
}
catch (IOException ex)
{
@@ -357,24 +377,20 @@
// return the default localization.
if (!found && !locale.equals(Locale.getDefault().toString()))
{
- result = getCurrentLocalizedHeader(Locale.getDefault()
- .toString());
+ result = getCurrentLocalizedHeader(Locale.getDefault().toString());
}
// Otherwise, perform the localization based on the discovered
// properties and cache the result.
else
{
// Resolve all localized header entries
- for (Iterator it = headers.entrySet().iterator(); it
- .hasNext();)
+ for (Map.Entry<String, String> entry : headers.entrySet())
{
- Map.Entry entry = (Map.Entry) it.next();
- String value = (String) entry.getValue();
+ String value = entry.getValue();
if (value.startsWith("%"))
{
String newvalue;
- String key = value
- .substring(value.indexOf("%") + 1);
+ String key = value.substring(value.indexOf("%") + 1);
newvalue = mergedProperties.getProperty(key);
if (newvalue == null)
{
@@ -392,7 +408,7 @@
return result;
}
- private void updateHeaderCache(String locale, Map localizedHeaders)
+ private void updateHeaderCache(String locale, Map<String, String> localizedHeaders)
{
synchronized (m_cachedHeaders)
{
@@ -401,16 +417,15 @@
}
}
- private final Map m_cachedHeaders = new HashMap();
+ private final Map<String, Map<String, String>> m_cachedHeaders = new HashMap<String, Map<String, String>>();
private long m_cachedHeadersTimestamp;
- private static List createLocalizationResourceList(String basename,
- String locale)
+ private static List<String> createLocalizationResourceList(String basename, String locale)
{
- List result = new ArrayList(4);
+ List<String> result = new ArrayList<String>(4);
StringTokenizer tokens;
- StringBuffer tempLocale = new StringBuffer(basename);
+ StringBuilder tempLocale = new StringBuilder(basename);
result.add(tempLocale.toString());
@@ -433,64 +448,73 @@
public Class<?> loadClass(String name) throws ClassNotFoundException
{
- return m_loader.loadClass(name);
+ return m_classLoader.loadClass(name);
}
+ @Override
public Enumeration<URL> getResources(String name) throws IOException
{
// TODO: module - implement this based on the revision
- return m_loader.getResources(name);
+ return m_classLoader.getResources(name);
}
+ @Override
public Enumeration<String> getEntryPaths(String path)
{
return new EntryFilterEnumeration<String>(m_revision, false, path, null, false,
false);
}
+ @Override
public URL getEntry(String path)
{
URL result = m_revision.getEntry(path);
return result;
}
+ @Override
public long getLastModified()
{
return m_revision.getLastModified();
}
- public Enumeration<URL> findEntries(String path, String filePattern,
- boolean recurse)
+ @Override
+ public Enumeration<URL> findEntries(String path, String filePattern, boolean recurse)
{
// TODO: module - implement this based on the revision
- return new EntryFilterEnumeration<URL>(m_revision, false, path, filePattern,
- recurse, true);
+ return new EntryFilterEnumeration<URL>(m_revision, true, path, filePattern, recurse, true);
}
+ @Override
public BundleContext getBundleContext()
{
return m_context;
}
- public Map getSignerCertificates(int signersType)
+ @Override
+ public Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType)
{
// TODO: security - fix this
- return new HashMap();
+ return new HashMap<X509Certificate, List<X509Certificate>>();
}
+ @Override
public Version getVersion()
{
return m_version;
}
- public boolean equals(Object o)
- {
- if (o instanceof PojoSRBundle) {
- return ((PojoSRBundle) o).m_id == m_id;
- }
- return false;
- }
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o instanceof PojoSRBundle)
+ {
+ return ((PojoSRBundle) o).m_id == m_id;
+ }
+ return false;
+ }
+ @Override
public int compareTo(Bundle o)
{
long thisBundleId = this.getBundleId();
@@ -498,45 +522,28 @@
return (thisBundleId < thatBundleId ? -1 : (thisBundleId == thatBundleId ? 0 : 1));
}
+ @SuppressWarnings("unchecked")
public <A> A adapt(Class<A> type)
{
- if (type == BundleStartLevel.class)
+ if (m_services != null && m_services.containsKey(type))
{
- return (A) new BundleStartLevel() {
-
- public Bundle getBundle()
- {
- return PojoSRBundle.this;
- }
-
- public int getStartLevel()
- {
- // TODO Implement this?
- return 1;
- }
-
- public void setStartLevel(int startlevel)
- {
- // TODO Implement this?
- }
-
- public boolean isPersistentlyStarted()
- {
- return true;
- }
-
- public boolean isActivationPolicyUsed()
- {
- return false;
- }};
+ return (A) m_services.get(type);
}
- else if (type == BundleRevisions.class)
+ if (type.isInstance(this))
{
return (A) this;
}
- else if (type == BundleWiring.class)
+ if (type == BundleWiring.class)
{
- return (A) this.getWiring();
+ return (A) new BundleWiringImpl(this, m_classLoader);
+ }
+ if (type == BundleRevision.class)
+ {
+ return (A) new BundleRevisionImpl(this);
+ }
+ if (type == BundleStartLevel.class)
+ {
+ return (A) new BundleStartLevelImpl(this);
}
return null;
}
@@ -551,109 +558,248 @@
String sym = getSymbolicName();
if (sym != null)
{
- return sym + " [" + getBundleId() +"]";
+ return sym + " [" + getBundleId() + "]";
}
- return "[" + getBundleId() +"]";
+ return "[" + getBundleId() + "]";
}
+ @Override
+ public List<BundleRevision> getRevisions()
+ {
+ return Arrays.asList(adapt(BundleRevision.class));
+ }
+
+ @Override
public Bundle getBundle()
{
return this;
}
- public List<BundleRevision> getRevisions()
- {
- return Arrays.asList((BundleRevision) this);
- }
- public List<BundleCapability> getDeclaredCapabilities(String namespace)
+ public static class BundleStartLevelImpl implements BundleStartLevel
{
- return Collections.emptyList();
- }
+ private final Bundle bundle;
- public List<BundleRequirement> getDeclaredRequirements(String namespace)
- {
- return Collections.emptyList();
- }
-
- public int getTypes()
- {
- if (getHeaders().get(Constants.FRAGMENT_HOST) != null) {
- return BundleRevision.TYPE_FRAGMENT;
- }
- return 0;
- }
-
- public BundleWiring getWiring()
- {
- return new BundleWiring()
+ public BundleStartLevelImpl(Bundle bundle)
{
+ this.bundle = bundle;
+ }
- public Bundle getBundle()
- {
- return PojoSRBundle.this;
- }
+ public int getStartLevel()
+ {
+ // TODO Implement this?
+ return 1;
+ }
- public Collection<String> listResources(String path, String filePattern, int options)
- {
- Collection<String> result = new ArrayList<String>();
- for (URL u : findEntries(path, filePattern, options))
- {
- result.add(u.toString());
- }
- // TODO: implement this
- return result;
- }
+ public void setStartLevel(int startlevel)
+ {
+ // TODO Implement this?
+ }
- public boolean isInUse()
- {
- return true;
- }
+ public boolean isPersistentlyStarted()
+ {
+ return true;
+ }
- public boolean isCurrent()
- {
- return true;
- }
+ public boolean isActivationPolicyUsed()
+ {
+ return false;
+ }
- public BundleRevision getRevision()
- {
- return PojoSRBundle.this;
- }
-
- public List<BundleRequirement> getRequirements(String namespace)
- {
- return getDeclaredRequirements(namespace);
- }
-
- public List<BundleWire> getRequiredWires(String namespace)
- {
- return Collections.emptyList();
- }
-
- public List<BundleWire> getProvidedWires(String namespace)
- {
- return Collections.emptyList();
- }
-
- public ClassLoader getClassLoader()
- {
- return getClass().getClassLoader();
- }
-
- public List<BundleCapability> getCapabilities(String namespace)
- {
- return Collections.emptyList();
- }
-
- public List<URL> findEntries(String path, String filePattern, int options)
- {
- List<URL> result = new ArrayList<URL>();
- for (Enumeration<URL> e = PojoSRBundle.this.findEntries(path, filePattern, options == BundleWiring.FINDENTRIES_RECURSE); e.hasMoreElements();)
- {
- result.add(e.nextElement());
- }
- return result;
- }
- };
+ @Override
+ public Bundle getBundle()
+ {
+ return bundle;
+ }
}
+
+ public static class BundleRevisionImpl implements BundleRevision
+ {
+ private final Bundle bundle;
+
+ public BundleRevisionImpl(Bundle bundle)
+ {
+ this.bundle = bundle;
+ }
+
+ @Override
+ public String getSymbolicName()
+ {
+ return bundle.getSymbolicName();
+ }
+
+ @Override
+ public Version getVersion()
+ {
+ return bundle.getVersion();
+ }
+
+ @Override
+ public List<BundleCapability> getDeclaredCapabilities(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<BundleRequirement> getDeclaredRequirements(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public int getTypes()
+ {
+ if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null)
+ {
+ return BundleRevision.TYPE_FRAGMENT;
+ }
+ return 0;
+ }
+
+ @Override
+ public BundleWiring getWiring()
+ {
+ return bundle.adapt(BundleWiring.class);
+ }
+
+ @Override
+ public List<Capability> getCapabilities(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<Requirement> getRequirements(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Bundle getBundle()
+ {
+ return bundle;
+ }
+ }
+
+ public static class BundleWiringImpl implements BundleWiring
+ {
+
+ private final Bundle bundle;
+ private final ClassLoader classLoader;
+
+ public BundleWiringImpl(Bundle bundle, ClassLoader classLoader)
+ {
+ this.bundle = bundle;
+ this.classLoader = classLoader;
+ }
+
+ @Override
+ public boolean isInUse()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isCurrent()
+ {
+ return true;
+ }
+
+ @Override
+ public BundleRevision getRevision()
+ {
+ return bundle.adapt(BundleRevision.class);
+ }
+
+ @Override
+ public List<BundleRequirement> getRequirements(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<BundleWire> getRequiredWires(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<BundleWire> getProvidedWires(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public ClassLoader getClassLoader()
+ {
+ return classLoader;
+ }
+
+ @Override
+ public List<BundleCapability> getCapabilities(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<Capability> getResourceCapabilities(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<Requirement> getResourceRequirements(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<Wire> getProvidedResourceWires(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<Wire> getRequiredResourceWires(String namespace)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public BundleRevision getResource()
+ {
+ return getRevision();
+ }
+
+ @Override
+ public Bundle getBundle()
+ {
+ return bundle;
+ }
+
+ @Override
+ public List<URL> findEntries(String path, String filePattern, int options)
+ {
+ List<URL> result = new ArrayList<URL>();
+ for (Enumeration<URL> e = bundle.findEntries(path, filePattern, options == BundleWiring.FINDENTRIES_RECURSE); e.hasMoreElements(); )
+ {
+ result.add(e.nextElement());
+ }
+ return result;
+ }
+
+ @Override
+ public Collection<String> listResources(String path, String filePattern, int options)
+ {
+ // TODO: this is wrong, we should return the resource names
+ Collection<String> result = new ArrayList<String>();
+ for (URL u : findEntries(path, filePattern, options))
+ {
+ result.add(u.toString());
+ }
+ return result;
+ }
+
+ }
+
}
diff --git a/connect/src/main/java/org/apache/felix/connect/PojoSRBundleContext.java b/connect/src/main/java/org/apache/felix/connect/PojoSRBundleContext.java
index e4e3b3c..864a818 100644
--- a/connect/src/main/java/org/apache/felix/connect/PojoSRBundleContext.java
+++ b/connect/src/main/java/org/apache/felix/connect/PojoSRBundleContext.java
@@ -25,8 +25,9 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.Dictionary;
-import java.util.List;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -39,10 +40,13 @@
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.hooks.service.FindHook;
import org.apache.felix.connect.felix.framework.ServiceRegistry;
import org.apache.felix.connect.felix.framework.capabilityset.SimpleFilter;
import org.apache.felix.connect.felix.framework.util.EventDispatcher;
+import org.apache.felix.connect.felix.framework.util.ShrinkableCollection;
+import org.apache.felix.connect.felix.framework.util.Util;
class PojoSRBundleContext implements BundleContext
{
@@ -50,10 +54,10 @@
private final ServiceRegistry m_reg;
private final EventDispatcher m_dispatcher;
private final Map<Long, Bundle> m_bundles;
- private final Map m_config;
+ private final Map<String, Object> m_config;
public PojoSRBundleContext(Bundle bundle, ServiceRegistry reg,
- EventDispatcher dispatcher, Map<Long, Bundle> bundles, Map config)
+ EventDispatcher dispatcher, Map<Long, Bundle> bundles, Map<String, Object> config)
{
m_bundle = bundle;
m_reg = reg;
@@ -70,7 +74,7 @@
public void removeServiceListener(ServiceListener listener)
{
m_dispatcher.removeListener(this, ServiceListener.class,
- listener);
+ listener);
}
public void removeFrameworkListener(FrameworkListener listener)
@@ -85,14 +89,14 @@
}
public ServiceRegistration registerService(String clazz, Object service,
- Dictionary properties)
+ Dictionary properties)
{
- return m_reg.registerService(m_bundle, new String[] { clazz }, service,
+ return m_reg.registerService(m_bundle, new String[]{clazz}, service,
properties);
}
public ServiceRegistration registerService(String[] clazzes,
- Object service, Dictionary properties)
+ Object service, Dictionary properties)
{
return m_reg.registerService(m_bundle, clazzes, service, properties);
}
@@ -109,17 +113,17 @@
throw new BundleException("pojosr can't do that");
}
- public ServiceReference[] getServiceReferences(String clazz, String filter)
+ public ServiceReference<?>[] getServiceReferences(String clazz, String filter)
throws InvalidSyntaxException
{
- return getAllServiceReferences(clazz, filter);
+ return getServiceReferences(clazz, filter, true);
}
- public ServiceReference getServiceReference(String clazz)
+ public ServiceReference<?> getServiceReference(String clazz)
{
try
{
- return getBestServiceReference(getAllServiceReferences(clazz, null));
+ return getBestServiceReference(getServiceReferences(clazz, null));
}
catch (InvalidSyntaxException e)
{
@@ -127,7 +131,7 @@
}
}
- private ServiceReference getBestServiceReference(ServiceReference[] refs)
+ private ServiceReference<?> getBestServiceReference(ServiceReference<?>[] refs)
{
if (refs == null)
{
@@ -153,7 +157,7 @@
return bestRef;
}
- public Object getService(ServiceReference reference)
+ public <S> S getService(ServiceReference<S> reference)
{
return m_reg.getService(m_bundle, reference);
}
@@ -202,24 +206,90 @@
}
public ServiceReference[] getAllServiceReferences(String clazz,
- String filter) throws InvalidSyntaxException
+ String filter) throws InvalidSyntaxException
{
- SimpleFilter simple = null;
- if (filter != null)
+ return getServiceReferences(clazz, filter, false);
+ }
+
+ /**
+ * Retrieves an array of {@link ServiceReference} objects based on calling bundle,
+ * service class name, and filter expression. Optionally checks for isAssignable to
+ * make sure that the service can be cast to the
+ * @param className Service Classname or <code>null</code> for all
+ * @param expr Filter Criteria or <code>null</code>
+ * @return Array of ServiceReference objects that meet the criteria
+ * @throws InvalidSyntaxException
+ */
+ ServiceReference[] getServiceReferences(
+ final String className,
+ final String expr, final boolean checkAssignable)
+ throws InvalidSyntaxException
+ {
+ // Define filter if expression is not null.
+ SimpleFilter filter = null;
+ if (expr != null)
{
try
{
- simple = SimpleFilter.parse(filter);
+ filter = SimpleFilter.parse(expr);
}
catch (Exception ex)
{
- throw new InvalidSyntaxException(ex.getMessage(), filter);
+ throw new InvalidSyntaxException(ex.getMessage(), expr);
}
}
- List<ServiceReference> result = m_reg.getServiceReferences(clazz,
- simple);
- return result.isEmpty() ? null : result
- .toArray(new ServiceReference[result.size()]);
+
+ // Ask the service registry for all matching service references.
+ final Collection<ServiceReference<?>> refList = m_reg.getServiceReferences(className, filter);
+
+ // Filter on assignable references
+ if (checkAssignable)
+ {
+ for (Iterator<ServiceReference<?>> it = refList.iterator(); it.hasNext();)
+ {
+ // Get the current service reference.
+ ServiceReference ref = it.next();
+ // Now check for castability.
+ if (!Util.isServiceAssignable(m_bundle, ref))
+ {
+ it.remove();
+ }
+ }
+ }
+
+ // activate findhooks
+ Set<ServiceReference<FindHook>> findHooks = m_reg.getHooks(org.osgi.framework.hooks.service.FindHook.class);
+ for (ServiceReference<org.osgi.framework.hooks.service.FindHook> sr : findHooks)
+ {
+ org.osgi.framework.hooks.service.FindHook fh = m_reg.getService(getBundle(0), sr);
+ if (fh != null)
+ {
+ try
+ {
+ fh.find(this,
+ className,
+ expr,
+ !checkAssignable,
+ new ShrinkableCollection<ServiceReference<?>>(refList));
+ }
+ catch (Throwable th)
+ {
+ System.err.println("Problem invoking service registry hook");
+ th.printStackTrace();
+ }
+ finally
+ {
+ m_reg.ungetService(getBundle(0), sr);
+ }
+ }
+ }
+
+ if (refList.size() > 0)
+ {
+ return refList.toArray(new ServiceReference[refList.size()]);
+ }
+
+ return null;
}
public Filter createFilter(String filter) throws InvalidSyntaxException
@@ -240,10 +310,10 @@
}
}
- public void addServiceListener(final ServiceListener listener, String filter)
+ public void addServiceListener(final ServiceListener listener, String filter)
throws InvalidSyntaxException
{
- m_dispatcher.addListener(this, ServiceListener.class, listener,
+ m_dispatcher.addListener(this, ServiceListener.class, listener,
filter == null ? null : FrameworkUtil.createFilter(filter));
}
@@ -259,18 +329,21 @@
.addListener(this, BundleListener.class, listener, null);
}
+ @SuppressWarnings("unchecked")
public <S> ServiceRegistration<S> registerService(Class<S> clazz, S service, Dictionary<String, ?> properties)
{
return (ServiceRegistration<S>) registerService(clazz.getName(), service, properties);
}
+ @SuppressWarnings("unchecked")
public <S> ServiceReference<S> getServiceReference(Class<S> clazz)
{
return (ServiceReference<S>) getServiceReference(clazz.getName());
}
+ @SuppressWarnings("unchecked")
public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter)
- throws InvalidSyntaxException
+ throws InvalidSyntaxException
{
ServiceReference<S>[] refs = (ServiceReference<S>[]) getServiceReferences(clazz.getName(), filter);
if (refs == null)
diff --git a/connect/src/main/java/org/apache/felix/connect/PojoServiceRegistryFactoryImpl.java b/connect/src/main/java/org/apache/felix/connect/PojoServiceRegistryFactoryImpl.java
index 5fdab63..6a05c40 100644
--- a/connect/src/main/java/org/apache/felix/connect/PojoServiceRegistryFactoryImpl.java
+++ b/connect/src/main/java/org/apache/felix/connect/PojoServiceRegistryFactoryImpl.java
@@ -22,9 +22,11 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.security.cert.X509Certificate;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.osgi.framework.Bundle;
@@ -42,183 +44,227 @@
import org.apache.felix.connect.launch.PojoServiceRegistry;
import org.apache.felix.connect.launch.PojoServiceRegistryFactory;
-public class PojoServiceRegistryFactoryImpl implements
- PojoServiceRegistryFactory, FrameworkFactory {
+public class PojoServiceRegistryFactoryImpl implements PojoServiceRegistryFactory, FrameworkFactory
+{
- public PojoServiceRegistry newPojoServiceRegistry(Map configuration)
- throws Exception {
- return new PojoSR(configuration);
- }
+ public PojoServiceRegistry newPojoServiceRegistry(Map<String, Object> configuration) throws Exception
+ {
+ return new PojoSR(configuration);
+ }
- public Framework newFramework(Map configuration) {
- return new FrameworkImpl((String) configuration.get("pojosr.filter"));
- }
+ public Framework newFramework(Map<String, String> configuration)
+ {
+ return new FrameworkImpl(configuration.get("pojosr.filter"));
+ }
- private static final class FrameworkImpl implements Framework {
- private final String m_filter;
- private volatile Bundle m_bundle = null;
- private volatile PojoServiceRegistry m_reg = null;
+ private static final class FrameworkImpl implements Framework
+ {
+ private final String m_filter;
+ private volatile Bundle m_bundle = null;
+ private volatile PojoServiceRegistry m_reg = null;
- public FrameworkImpl(String filter) {
- m_filter = filter;
- }
+ public FrameworkImpl(String filter)
+ {
+ m_filter = filter;
+ }
- public void init() throws BundleException {
- try {
- m_reg = new PojoServiceRegistryFactoryImpl()
- .newPojoServiceRegistry(new HashMap());
- m_bundle = m_reg.getBundleContext()
- .getBundle();
- } catch (Exception ex) {
- throw new BundleException("Unable to scan classpath", ex);
- }
- }
+ public void init() throws BundleException
+ {
+ try
+ {
+ m_reg = new PojoServiceRegistryFactoryImpl()
+ .newPojoServiceRegistry(new HashMap<String, Object>());
+ m_bundle = m_reg.getBundleContext().getBundle();
+ }
+ catch (Exception ex)
+ {
+ throw new BundleException("Unable to scan classpath", ex);
+ }
+ }
- public int getState() {
- return (m_bundle == null) ? Bundle.INSTALLED : m_bundle.getState();
- }
+ public int getState()
+ {
+ return (m_bundle == null) ? Bundle.INSTALLED : m_bundle.getState();
+ }
- public void start(int options) throws BundleException {
- start();
- }
+ public void start(int options) throws BundleException
+ {
+ start();
+ }
- public void start() throws BundleException {
- try {
- m_reg.startBundles((m_filter != null) ? new ClasspathScanner()
- .scanForBundles(m_filter)
- : new ClasspathScanner().scanForBundles());
- } catch (Exception e) {
- throw new BundleException("Error starting framework", e);
- }
- }
+ public void start() throws BundleException
+ {
+ try
+ {
+ m_reg.startBundles((m_filter != null) ? new ClasspathScanner()
+ .scanForBundles(m_filter)
+ : new ClasspathScanner().scanForBundles());
+ }
+ catch (Exception e)
+ {
+ throw new BundleException("Error starting framework", e);
+ }
+ }
- public void stop(int options) throws BundleException {
- m_bundle.stop(options);
- }
+ public void stop(int options) throws BundleException
+ {
+ m_bundle.stop(options);
+ }
- public void stop() throws BundleException {
- m_bundle.stop();
- }
+ public void stop() throws BundleException
+ {
+ m_bundle.stop();
+ }
- public void update(InputStream input) throws BundleException {
- m_bundle.update(input);
- }
+ public void update(InputStream input) throws BundleException
+ {
+ m_bundle.update(input);
+ }
- public void update() throws BundleException {
- m_bundle.update();
- }
+ public void update() throws BundleException
+ {
+ m_bundle.update();
+ }
- public void uninstall() throws BundleException {
- m_bundle.uninstall();
- }
+ public void uninstall() throws BundleException
+ {
+ m_bundle.uninstall();
+ }
- public Dictionary getHeaders() {
- return m_bundle.getHeaders();
- }
+ public Dictionary<String, String> getHeaders()
+ {
+ return m_bundle.getHeaders();
+ }
- public long getBundleId() {
- return m_bundle.getBundleId();
- }
+ public long getBundleId()
+ {
+ return m_bundle.getBundleId();
+ }
- public String getLocation() {
- return m_bundle.getLocation();
- }
+ public String getLocation()
+ {
+ return m_bundle.getLocation();
+ }
- public ServiceReference[] getRegisteredServices() {
- return m_bundle.getRegisteredServices();
- }
+ public ServiceReference[] getRegisteredServices()
+ {
+ return m_bundle.getRegisteredServices();
+ }
- public ServiceReference[] getServicesInUse() {
- return m_bundle.getServicesInUse();
- }
+ public ServiceReference[] getServicesInUse()
+ {
+ return m_bundle.getServicesInUse();
+ }
- public boolean hasPermission(Object permission) {
- return m_bundle.hasPermission(permission);
- }
+ public boolean hasPermission(Object permission)
+ {
+ return m_bundle.hasPermission(permission);
+ }
- public URL getResource(String name) {
- return m_bundle.getResource(name);
- }
+ public URL getResource(String name)
+ {
+ return m_bundle.getResource(name);
+ }
- public Dictionary getHeaders(String locale) {
- return m_bundle.getHeaders(locale);
- }
+ public Dictionary<String, String> getHeaders(String locale)
+ {
+ return m_bundle.getHeaders(locale);
+ }
- public String getSymbolicName() {
- return m_bundle.getSymbolicName();
- }
+ public String getSymbolicName()
+ {
+ return m_bundle.getSymbolicName();
+ }
- public Class loadClass(String name) throws ClassNotFoundException {
- return m_bundle.loadClass(name);
- }
+ public Class loadClass(String name) throws ClassNotFoundException
+ {
+ return m_bundle.loadClass(name);
+ }
- public Enumeration getResources(String name) throws IOException {
- return m_bundle.getResources(name);
- }
+ public Enumeration<URL> getResources(String name) throws IOException
+ {
+ return m_bundle.getResources(name);
+ }
- public Enumeration getEntryPaths(String path) {
- return m_bundle.getEntryPaths(path);
- }
+ public Enumeration<String> getEntryPaths(String path)
+ {
+ return m_bundle.getEntryPaths(path);
+ }
- public URL getEntry(String path) {
- return m_bundle.getEntry(path);
- }
+ public URL getEntry(String path)
+ {
+ return m_bundle.getEntry(path);
+ }
- public long getLastModified() {
- return m_bundle.getLastModified();
- }
+ public long getLastModified()
+ {
+ return m_bundle.getLastModified();
+ }
- public Enumeration findEntries(String path, String filePattern,
- boolean recurse) {
- return m_bundle.findEntries(path, filePattern, recurse);
- }
+ public Enumeration<URL> findEntries(String path, String filePattern, boolean recurse)
+ {
+ return m_bundle.findEntries(path, filePattern, recurse);
+ }
- public BundleContext getBundleContext() {
- return m_bundle.getBundleContext();
- }
+ public BundleContext getBundleContext()
+ {
+ return m_bundle.getBundleContext();
+ }
- public Map getSignerCertificates(int signersType) {
- return m_bundle.getSignerCertificates(signersType);
- }
+ public Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType)
+ {
+ return m_bundle.getSignerCertificates(signersType);
+ }
- public Version getVersion() {
- return m_bundle.getVersion();
- }
+ public Version getVersion()
+ {
+ return m_bundle.getVersion();
+ }
- public FrameworkEvent waitForStop(long timeout)
- throws InterruptedException {
- final Object lock = new Object();
-
- m_bundle.getBundleContext().addBundleListener(new SynchronousBundleListener() {
-
- public void bundleChanged(BundleEvent event) {
- if ((event.getBundle() == m_bundle) && (event.getType() == BundleEvent.STOPPED)) {
- synchronized (lock) {
- lock.notifyAll();
- }
- }
- }
- });
- synchronized (lock) {
- while (m_bundle.getState() != Bundle.RESOLVED) {
- if (m_bundle.getState() == Bundle.STOPPING ) {
- lock.wait(100);
- }
- else {
- lock.wait();
- }
- }
- }
- return new FrameworkEvent(FrameworkEvent.STOPPED, m_bundle, null);
- }
-
- public File getDataFile(String filename) {
- return m_bundle.getDataFile(filename);
- }
+ public FrameworkEvent waitForStop(long timeout)
+ throws InterruptedException
+ {
+ final Object lock = new Object();
+
+ m_bundle.getBundleContext().addBundleListener(new SynchronousBundleListener()
+ {
+
+ public void bundleChanged(BundleEvent event)
+ {
+ if ((event.getBundle() == m_bundle) && (event.getType() == BundleEvent.STOPPED))
+ {
+ synchronized (lock)
+ {
+ lock.notifyAll();
+ }
+ }
+ }
+ });
+ synchronized (lock)
+ {
+ while (m_bundle.getState() != Bundle.RESOLVED)
+ {
+ if (m_bundle.getState() == Bundle.STOPPING)
+ {
+ lock.wait(100);
+ }
+ else
+ {
+ lock.wait();
+ }
+ }
+ }
+ return new FrameworkEvent(FrameworkEvent.STOPPED, m_bundle, null);
+ }
+
+ public File getDataFile(String filename)
+ {
+ return m_bundle.getDataFile(filename);
+ }
public int compareTo(Bundle o)
{
- if (o == this)
+ if (o == this)
{
return 0;
}
@@ -230,5 +276,5 @@
return m_bundle.adapt(type);
}
- }
+ }
}
diff --git a/connect/src/main/java/org/apache/felix/connect/RequiredBundleImpl.java b/connect/src/main/java/org/apache/felix/connect/RequiredBundleImpl.java
new file mode 100644
index 0000000..50993b7
--- /dev/null
+++ b/connect/src/main/java/org/apache/felix/connect/RequiredBundleImpl.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.connect;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.packageadmin.RequiredBundle;
+
+public class RequiredBundleImpl implements RequiredBundle
+{
+
+ private final Bundle m_bundle;
+
+ public RequiredBundleImpl(Bundle bundle)
+ {
+ m_bundle = bundle;
+ }
+
+ public String getSymbolicName()
+ {
+ return m_bundle.getSymbolicName();
+ }
+
+ public Bundle getBundle()
+ {
+ return m_bundle;
+ }
+
+ public Bundle[] getRequiringBundles()
+ {
+ Set<Bundle> set = new HashSet<Bundle>();
+ for (BundleWire wire : m_bundle.adapt(BundleWiring.class).getProvidedWires(null))
+ {
+ if (BundleNamespace.BUNDLE_NAMESPACE.equals(wire.getCapability().getNamespace()))
+ {
+ set.add(wire.getRequirer().getBundle());
+ }
+ }
+ return set.toArray(new Bundle[set.size()]);
+ }
+
+ public Version getVersion()
+ {
+ return m_bundle.getVersion();
+ }
+
+ public boolean isRemovalPending()
+ {
+ return false;
+ }
+
+ public String toString()
+ {
+ return m_bundle.getSymbolicName() + "; version=" + m_bundle.getVersion();
+ }
+
+}
diff --git a/connect/src/main/java/org/apache/felix/connect/Revision.java b/connect/src/main/java/org/apache/felix/connect/Revision.java
index cf4fd36..77b23bd 100644
--- a/connect/src/main/java/org/apache/felix/connect/Revision.java
+++ b/connect/src/main/java/org/apache/felix/connect/Revision.java
@@ -21,11 +21,11 @@
import java.net.URL;
import java.util.Enumeration;
-abstract class Revision
+public interface Revision
{
- public abstract long getLastModified();
+ public long getLastModified();
- public abstract URL getEntry(String entryName);
+ public URL getEntry(String entryName);
- public abstract Enumeration<String> getEntries();
+ public Enumeration<String> getEntries();
}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/URLRevision.java b/connect/src/main/java/org/apache/felix/connect/URLRevision.java
index efbe650..4cf45cb 100644
--- a/connect/src/main/java/org/apache/felix/connect/URLRevision.java
+++ b/connect/src/main/java/org/apache/felix/connect/URLRevision.java
@@ -20,10 +20,10 @@
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Collections;
import java.util.Enumeration;
-import java.util.Properties;
-class URLRevision extends Revision
+class URLRevision implements Revision
{
private final URL m_url;
private final long m_lastModified;
@@ -47,9 +47,10 @@
return m_lastModified;
}
- public Enumeration getEntries()
+ @Override
+ public Enumeration<String> getEntries()
{
- return new Properties().elements();
+ return Collections.emptyEnumeration();
}
@Override
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/ServiceRegistrationImpl.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/ServiceRegistrationImpl.java
index b29e587..2c401b0 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/ServiceRegistrationImpl.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/ServiceRegistrationImpl.java
@@ -18,17 +18,27 @@
*/
package org.apache.felix.connect.felix.framework;
-import java.util.*;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Set;
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceException;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
import org.apache.felix.connect.felix.framework.util.MapToDictionary;
import org.apache.felix.connect.felix.framework.util.StringMap;
import org.apache.felix.connect.felix.framework.util.Util;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-class ServiceRegistrationImpl implements ServiceRegistration
+class ServiceRegistrationImpl<T> implements ServiceRegistration<T>
{
// Service registry.
private final ServiceRegistry m_registry;
@@ -41,16 +51,16 @@
// Service object.
private volatile Object m_svcObj;
// Service factory interface.
- private volatile ServiceFactory m_factory;
+ private volatile ServiceFactory<T> m_factory;
// Associated property dictionary.
private volatile Map m_propMap = new StringMap(false);
// Re-usable service reference.
- private final ServiceReferenceImpl m_ref;
+ private final ServiceReferenceImpl<T> m_ref;
// Flag indicating that we are unregistering.
private volatile boolean m_isUnregistering = false;
public ServiceRegistrationImpl(ServiceRegistry registry, Bundle bundle,
- String[] classes, Long serviceId, Object svcObj, Dictionary dict)
+ String[] classes, Long serviceId, Object svcObj, Dictionary dict)
{
m_registry = registry;
m_bundle = bundle;
@@ -77,7 +87,7 @@
m_svcObj = null;
}
- public synchronized ServiceReference getReference()
+ public synchronized ServiceReferenceImpl<T> getReference()
{
// Make sure registration is valid.
if (!isValid())
@@ -152,7 +162,7 @@
* itself.
*
* @return The service object associated with the registration.
- **/
+ */
Object getService()
{
return m_svcObj;
@@ -175,7 +185,7 @@
}
}
- void ungetService(Bundle relBundle, Object svcObj)
+ void ungetService(Bundle relBundle, T svcObj)
{
// If the service object is a service factory, then
// let it release the service object.
@@ -238,19 +248,24 @@
}
if (svcObj != null)
{
- for (int i = 0; i < m_classes.length; i++)
+ for (String className : m_classes)
{
- try {
- if (!Class.forName(m_classes[i]).isAssignableFrom(svcObj.getClass()))
+ Class<?> clazz = Util.loadClassUsingClass(svcObj.getClass(), className);
+ if ((clazz == null) || !clazz.isAssignableFrom(svcObj.getClass()))
{
- throw new ServiceException(
- "Service cannot be cast: " + m_classes[i],
- ServiceException.FACTORY_ERROR);
+ if (clazz == null)
+ {
+ throw new ServiceException(
+ "Service cannot be cast due to missing class: " + className,
+ ServiceException.FACTORY_ERROR);
+ }
+ else
+ {
+ throw new ServiceException(
+ "Service cannot be cast: " + className,
+ ServiceException.FACTORY_ERROR);
+ }
}
- } catch (ClassNotFoundException ex) {
- throw new ServiceException("Service is missing class: " + m_classes[i], ServiceException.FACTORY_ERROR);
- }
-
}
}
else
@@ -261,18 +276,17 @@
return svcObj;
}
- private void ungetFactoryUnchecked(Bundle bundle, Object svcObj)
+ private void ungetFactoryUnchecked(Bundle bundle, T svcObj)
{
m_factory.ungetService(bundle, this, svcObj);
}
-
//
// ServiceReference implementation
//
- class ServiceReferenceImpl implements ServiceReference, BundleCapability
+ class ServiceReferenceImpl<T> implements ServiceReference<T>, BundleCapability
{
private final ServiceReferenceMap m_map;
@@ -290,6 +304,13 @@
// Capability methods.
//
+
+ @Override
+ public BundleRevision getResource()
+ {
+ return getRevision();
+ }
+
@Override
public BundleRevision getRevision()
{
@@ -305,30 +326,28 @@
@Override
public Map<String, String> getDirectives()
{
- return Collections.EMPTY_MAP;
+ return Collections.emptyMap();
}
@Override
- public Map<String,Object> getAttributes()
+ public Map<String, Object> getAttributes()
{
return m_map;
}
- public List<String> getUses()
- {
- return Collections.EMPTY_LIST;
- }
-
+ @Override
public Object getProperty(String s)
{
return ServiceRegistrationImpl.this.getProperty(s);
}
+ @Override
public String[] getPropertyKeys()
{
return ServiceRegistrationImpl.this.getPropertyKeys();
}
+ @Override
public Bundle getBundle()
{
// The spec says that this should return null if
@@ -336,6 +355,7 @@
return (isValid()) ? m_bundle : null;
}
+ @Override
public Bundle[] getUsingBundles()
{
return ServiceRegistrationImpl.this.getUsingBundles();
@@ -349,12 +369,15 @@
{
oc = oc + ocs[i];
if (i < ocs.length - 1)
+ {
oc = oc + ", ";
+ }
}
oc = oc + "]";
return oc;
}
+ @Override
public boolean isAssignableTo(Bundle requester, String className)
{
// Always return true if the requester is the same as the provider.
@@ -365,9 +388,8 @@
// Boolean flag.
boolean allow = true;
- // Get the package.
- String pkgName = Util.getClassPackage(className);
- /*
+ /* // Get the package.
+ * String pkgName = Util.getClassPackage(className);
* Module requesterModule = ((BundleImpl)
* requester).getCurrentModule(); // Get package wiring from service
* requester. Wire requesterWire = Util.getWire(requesterModule,
@@ -444,6 +466,7 @@
return allow;
}
+ @Override
public int compareTo(Object reference)
{
ServiceReference other = (ServiceReference) reference;
@@ -485,66 +508,78 @@
}
}
- private class ServiceReferenceMap implements Map
+ private class ServiceReferenceMap implements Map<String, Object>
{
+ @Override
public int size()
{
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
public boolean isEmpty()
{
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
public boolean containsKey(Object o)
{
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
public boolean containsValue(Object o)
{
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
public Object get(Object o)
{
return ServiceRegistrationImpl.this.getProperty((String) o);
}
- public Object put(Object k, Object v)
+ @Override
+ public Object put(String k, Object v)
{
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
public Object remove(Object o)
{
throw new UnsupportedOperationException("Not supported yet.");
}
- public void putAll(Map map)
+ @Override
+ public void putAll(Map<? extends String, ? extends Object> map)
{
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
public void clear()
{
throw new UnsupportedOperationException("Not supported yet.");
}
- public Set<Object> keySet()
+ @Override
+ public Set<String> keySet()
{
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
public Collection<Object> values()
{
throw new UnsupportedOperationException("Not supported yet.");
}
- public Set<Entry<Object, Object>> entrySet()
+ @Override
+ public Set<Entry<String, Object>> entrySet()
{
- return Collections.EMPTY_SET;
+ return Collections.emptySet();
}
}
}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/ServiceRegistry.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/ServiceRegistry.java
index d46f613..a076b7f 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/ServiceRegistry.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/ServiceRegistry.java
@@ -18,80 +18,94 @@
*/
package org.apache.felix.connect.felix.framework;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.WeakHashMap;
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceException;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.wiring.BundleCapability;
import org.apache.felix.connect.felix.framework.capabilityset.CapabilitySet;
import org.apache.felix.connect.felix.framework.capabilityset.SimpleFilter;
-import org.osgi.framework.wiring.BundleCapability;
public class ServiceRegistry
{
private long m_currentServiceId = 1L;
// Maps bundle to an array of service registrations.
- private final Map m_regsMap = Collections.synchronizedMap(new HashMap());
+ private final Map<Bundle, ServiceRegistration[]> m_regsMap = Collections.synchronizedMap(new HashMap<Bundle, ServiceRegistration[]>());
// Capability set for all service registrations.
- private final CapabilitySet m_regCapSet;
+ private final CapabilitySet<ServiceRegistrationImpl.ServiceReferenceImpl> m_regCapSet;
// Maps registration to thread to keep track when a
// registration is in use, which will cause other
// threads to wait.
- private final Map m_lockedRegsMap = new HashMap();
+ private final Map<ServiceRegistrationImpl, Thread> m_lockedRegsMap = new HashMap<ServiceRegistrationImpl, Thread>();
// Maps bundle to an array of usage counts.
- private final Map m_inUseMap = new HashMap();
+ private final Map<Bundle, UsageCount[]> m_inUseMap = new HashMap<Bundle, UsageCount[]>();
private final ServiceRegistryCallbacks m_callbacks;
private final WeakHashMap<ServiceReference, ServiceReference> m_blackList =
- new WeakHashMap<ServiceReference, ServiceReference>();
+ new WeakHashMap<ServiceReference, ServiceReference>();
private final static Class<?>[] m_hookClasses =
- {
- org.osgi.framework.hooks.bundle.FindHook.class,
- org.osgi.framework.hooks.bundle.EventHook.class,
- org.osgi.framework.hooks.service.EventHook.class,
- org.osgi.framework.hooks.service.EventListenerHook.class,
- org.osgi.framework.hooks.service.FindHook.class,
- org.osgi.framework.hooks.service.ListenerHook.class,
- org.osgi.framework.hooks.weaving.WeavingHook.class,
- org.osgi.framework.hooks.resolver.ResolverHookFactory.class,
- org.osgi.service.url.URLStreamHandlerService.class,
- java.net.ContentHandler.class
- };
+ {
+ org.osgi.framework.hooks.bundle.FindHook.class,
+ org.osgi.framework.hooks.bundle.EventHook.class,
+ org.osgi.framework.hooks.service.EventHook.class,
+ org.osgi.framework.hooks.service.EventListenerHook.class,
+ org.osgi.framework.hooks.service.FindHook.class,
+ org.osgi.framework.hooks.service.ListenerHook.class,
+ org.osgi.framework.hooks.weaving.WeavingHook.class,
+ org.osgi.framework.hooks.resolver.ResolverHookFactory.class,
+ org.osgi.service.url.URLStreamHandlerService.class,
+ java.net.ContentHandler.class
+ };
private final Map<Class<?>, Set<ServiceReference<?>>> m_allHooks =
- new HashMap<Class<?>, Set<ServiceReference<?>>>();
+ new HashMap<Class<?>, Set<ServiceReference<?>>>();
public ServiceRegistry(ServiceRegistryCallbacks callbacks)
{
m_callbacks = callbacks;
- List indices = new ArrayList();
- indices.add(Constants.OBJECTCLASS);
- m_regCapSet = new CapabilitySet(indices, false);
+ m_regCapSet = new CapabilitySet(Collections.singletonList(Constants.OBJECTCLASS), false);
}
public ServiceReference[] getRegisteredServices(Bundle bundle)
{
- ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
+ ServiceRegistration[] regs = m_regsMap.get(bundle);
if (regs != null)
{
- List refs = new ArrayList(regs.length);
- for (int i = 0; i < regs.length; i++)
+ List<ServiceReference> refs = new ArrayList<ServiceReference>(regs.length);
+ for (ServiceRegistration reg : regs)
{
try
{
- refs.add(regs[i].getReference());
+ refs.add(reg.getReference());
}
catch (IllegalStateException ex)
{
// Don't include the reference as it is not valid anymore
}
}
- return (ServiceReference[]) refs.toArray(new ServiceReference[refs.size()]);
+ return refs.toArray(new ServiceReference[refs.size()]);
}
return null;
}
// Caller is expected to fire REGISTERED event.
public ServiceRegistration registerService(
- Bundle bundle, String[] classNames, Object svcObj, Dictionary dict)
+ Bundle bundle, String[] classNames, Object svcObj, Dictionary dict)
{
ServiceRegistrationImpl reg = null;
@@ -99,7 +113,7 @@
{
// Create the service registration.
reg = new ServiceRegistrationImpl(
- this, bundle, classNames, new Long(m_currentServiceId++), svcObj, dict);
+ this, bundle, classNames, m_currentServiceId++, svcObj, dict);
// Keep track of registered hooks.
addHooks(classNames, svcObj, reg.getReference());
@@ -107,19 +121,19 @@
// Get the bundles current registered services.
ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
m_regsMap.put(bundle, addServiceRegistration(regs, reg));
- m_regCapSet.addCapability((BundleCapability) reg.getReference());
+ m_regCapSet.addCapability(reg.getReference());
}
// Notify callback objects about registered service.
if (m_callbacks != null)
{
m_callbacks.serviceChanged(new ServiceEvent(
- ServiceEvent.REGISTERED, reg.getReference()), null);
+ ServiceEvent.REGISTERED, reg.getReference()), null);
}
return reg;
}
- public void unregisterService(Bundle bundle, ServiceRegistration reg)
+ public void unregisterService(Bundle bundle, ServiceRegistrationImpl reg)
{
// If this is a hook, it should be removed.
removeHook(reg.getReference());
@@ -133,16 +147,16 @@
// new bundles will be able to look up the service.
// Now remove the registered service.
- ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
+ ServiceRegistration[] regs = m_regsMap.get(bundle);
m_regsMap.put(bundle, removeServiceRegistration(regs, reg));
- m_regCapSet.removeCapability((BundleCapability) reg.getReference());
+ m_regCapSet.removeCapability(reg.getReference());
}
// Notify callback objects about unregistering service.
if (m_callbacks != null)
{
m_callbacks.serviceChanged(
- new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()), null);
+ new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()), null);
}
// Now forcibly unget the service object for all stubborn clients.
@@ -152,7 +166,9 @@
for (int i = 0; (clients != null) && (i < clients.length); i++)
{
while (ungetService(clients[i], reg.getReference()))
+ {
; // Keep removing until it is no longer possible
+ }
}
((ServiceRegistrationImpl) reg).invalidate();
}
@@ -165,7 +181,6 @@
* bundle.
*
* @param bundle the bundle whose services should be unregistered.
- *
*/
public void unregisterServices(Bundle bundle)
{
@@ -173,7 +188,7 @@
ServiceRegistration[] regs = null;
synchronized (this)
{
- regs = (ServiceRegistration[]) m_regsMap.get(bundle);
+ regs = m_regsMap.get(bundle);
}
// Note, there is no race condition here with respect to the
@@ -197,7 +212,7 @@
}
}
- public synchronized List getServiceReferences(String className, SimpleFilter filter)
+ public synchronized Collection<ServiceReference<?>> getServiceReferences(String className, SimpleFilter filter)
{
if ((className == null) && (filter == null))
{
@@ -212,16 +227,16 @@
else if ((className != null) && (filter != null))
{
// Return services matching the class name and filter.
- List filters = new ArrayList(2);
+ List<Object> filters = new ArrayList<Object>(2);
filters.add(new SimpleFilter(Constants.OBJECTCLASS, className, SimpleFilter.EQ));
filters.add(filter);
filter = new SimpleFilter(null, filters, SimpleFilter.AND);
}
// else just use the specified filter.
- Set<BundleCapability> matches = m_regCapSet.match(filter, false);
+ Set<ServiceRegistrationImpl.ServiceReferenceImpl> matches = m_regCapSet.match(filter, false);
- return new ArrayList(matches);
+ return (Collection) matches;
}
public synchronized ServiceReference[] getServicesInUse(Bundle bundle)
@@ -246,7 +261,7 @@
// Get the service registration.
ServiceRegistrationImpl reg =
- ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getRegistration();
+ ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getRegistration();
synchronized (this)
{
@@ -258,9 +273,9 @@
if (o.equals(Thread.currentThread()))
{
throw new ServiceException(
- "ServiceFactory.getService() resulted in a cycle.",
- ServiceException.FACTORY_ERROR,
- null);
+ "ServiceFactory.getService() resulted in a cycle.",
+ ServiceException.FACTORY_ERROR,
+ null);
}
// Otherwise, wait for it to be freed.
@@ -339,7 +354,7 @@
{
UsageCount usage = null;
ServiceRegistrationImpl reg =
- ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getRegistration();
+ ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getRegistration();
synchronized (this)
{
@@ -351,7 +366,7 @@
if (o.equals(Thread.currentThread()))
{
throw new IllegalStateException(
- "ServiceFactory.ungetService() resulted in a cycle.");
+ "ServiceFactory.ungetService() resulted in a cycle.");
}
// Otherwise, wait for it to be freed.
@@ -385,7 +400,7 @@
{
// Remove reference from usages array.
((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
- .getRegistration().ungetService(bundle, usage.m_svcObj);
+ .getRegistration().ungetService(bundle, usage.m_svcObj);
}
}
finally
@@ -423,14 +438,13 @@
* specified bundle.
*
* @param bundle the bundle whose services are to be released.
- *
*/
public void ungetServices(Bundle bundle)
{
UsageCount[] usages;
synchronized (this)
{
- usages = (UsageCount[]) m_inUseMap.get(bundle);
+ usages = m_inUseMap.get(bundle);
}
if (usages == null)
@@ -445,10 +459,10 @@
// Remove each service object from the
// service cache.
- for (int i = 0; i < usages.length; i++)
+ for (UsageCount usage : usages)
{
// Keep ungetting until all usage count is zero.
- while (ungetService(bundle, usages[i].m_ref))
+ while (ungetService(bundle, usage.m_ref))
{
// Empty loop body.
}
@@ -458,22 +472,18 @@
public synchronized Bundle[] getUsingBundles(ServiceReference ref)
{
Bundle[] bundles = null;
- for (Iterator iter = m_inUseMap.entrySet().iterator(); iter.hasNext();)
+ for (Map.Entry<Bundle, UsageCount[]> entry : m_inUseMap.entrySet())
{
- Map.Entry entry = (Map.Entry) iter.next();
- Bundle bundle = (Bundle) entry.getKey();
- UsageCount[] usages = (UsageCount[]) entry.getValue();
- for (int useIdx = 0; useIdx < usages.length; useIdx++)
+ Bundle bundle = entry.getKey();
+ UsageCount[] usages = entry.getValue();
+ for (UsageCount usage : usages)
{
- if (usages[useIdx].m_ref.equals(ref))
+ if (usage.m_ref.equals(ref))
{
// Add the bundle to the array to be returned.
if (bundles == null)
{
- bundles = new Bundle[]
- {
- bundle
- };
+ bundles = new Bundle[]{bundle};
}
else
{
@@ -494,19 +504,19 @@
if (m_callbacks != null)
{
m_callbacks.serviceChanged(
- new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()), oldProps);
+ new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()), oldProps);
}
}
private static ServiceRegistration[] addServiceRegistration(
- ServiceRegistration[] regs, ServiceRegistration reg)
+ ServiceRegistration[] regs, ServiceRegistration reg)
{
if (regs == null)
{
regs = new ServiceRegistration[]
- {
- reg
- };
+ {
+ reg
+ };
}
else
{
@@ -519,7 +529,7 @@
}
private static ServiceRegistration[] removeServiceRegistration(
- ServiceRegistration[] regs, ServiceRegistration reg)
+ ServiceRegistration[] regs, ServiceRegistration reg)
{
for (int i = 0; (regs != null) && (i < regs.length); i++)
{
@@ -538,7 +548,7 @@
if (i < newRegs.length)
{
System.arraycopy(
- regs, i + 1, newRegs, i, newRegs.length - i);
+ regs, i + 1, newRegs, i, newRegs.length - i);
}
regs = newRegs;
}
@@ -552,9 +562,8 @@
* specified service reference.
*
* @param bundle The bundle whose usage counts are being searched.
- * @param ref The service reference to find in the bundle's usage counts.
+ * @param ref The service reference to find in the bundle's usage counts.
* @return The associated usage count or null if not found.
- *
*/
private UsageCount getUsageCount(Bundle bundle, ServiceReference ref)
{
@@ -577,13 +586,11 @@
* be incremented.
*
* @param bundle The bundle acquiring the service.
- * @param ref The service reference of the acquired service.
- * @param svcObj The service object of the acquired service.
- *
+ * @param ref The service reference of the acquired service.
*/
private UsageCount addUsageCount(Bundle bundle, ServiceReference ref)
{
- UsageCount[] usages = (UsageCount[]) m_inUseMap.get(bundle);
+ UsageCount[] usages = m_inUseMap.get(bundle);
UsageCount usage = new UsageCount();
usage.m_ref = ref;
@@ -591,9 +598,9 @@
if (usages == null)
{
usages = new UsageCount[]
- {
- usage
- };
+ {
+ usage
+ };
}
else
{
@@ -618,8 +625,7 @@
* usage count for the specified service reference.
*
* @param bundle The bundle whose usage count should be removed.
- * @param ref The service reference whose usage count should be removed.
- *
+ * @param ref The service reference whose usage count should be removed.
*/
private void flushUsageCount(Bundle bundle, ServiceReference ref)
{
@@ -641,7 +647,7 @@
if (i < newUsages.length)
{
System.arraycopy(
- usages, i + 1, newUsages, i, newUsages.length - i);
+ usages, i + 1, newUsages, i, newUsages.length - i);
}
usages = newUsages;
}
@@ -726,7 +732,7 @@
// We maintain the hooks sorted, so if ranking has changed for example,
// we need to ensure the order remains correct by resorting the hooks.
Object svcObj = ((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
- .getRegistration().getService();
+ .getRegistration().getService();
String[] classNames = (String[]) ref.getProperty(Constants.OBJECTCLASS);
for (Class<?> hookClass : m_hookClasses)
@@ -750,7 +756,7 @@
private void removeHook(ServiceReference ref)
{
Object svcObj = ((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
- .getRegistration().getService();
+ .getRegistration().getService();
String[] classNames = (String[]) ref.getProperty(Constants.OBJECTCLASS);
for (Class<?> hookClass : m_hookClasses)
@@ -777,25 +783,18 @@
{
synchronized (m_allHooks)
{
- Set<ServiceReference<?>> hooks = m_allHooks.get(hookClass);
+ @SuppressWarnings("unchecked")
+ Set<ServiceReference<S>> hooks = (Set) m_allHooks.get(hookClass);
if (hooks != null)
{
- SortedSet sorted = new TreeSet<ServiceReference<?>>(Collections.reverseOrder());
+ SortedSet<ServiceReference<S>> sorted = new TreeSet<ServiceReference<S>>(Collections.reverseOrder());
sorted.addAll(hooks);
- return asTypedSortedSet(sorted);
+ return sorted;
}
- return Collections.EMPTY_SET;
+ return Collections.emptySet();
}
}
- private static <S> SortedSet<ServiceReference<S>> asTypedSortedSet(
- SortedSet<ServiceReference<?>> ss)
- {
- return (SortedSet<ServiceReference<S>>) (SortedSet) ss;
-
-
- }
-
private static class UsageCount
{
public int m_count = 0;
@@ -805,6 +804,6 @@
public interface ServiceRegistryCallbacks
{
- void serviceChanged(ServiceEvent event, Dictionary oldProps);
+ void serviceChanged(ServiceEvent event, Dictionary<String, ?> oldProps);
}
}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Attribute.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Attribute.java
deleted file mode 100644
index ea8b01f..0000000
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Attribute.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.connect.felix.framework.capabilityset;
-
-public class Attribute
-{
- private final String m_name;
- private final Object m_value;
- private final boolean m_isMandatory;
-
- public Attribute(String name, Object value, boolean isMandatory)
- {
- m_name = name;
- m_value = value;
- m_isMandatory = isMandatory;
- }
-
- public String getName()
- {
- return m_name;
- }
-
- public Object getValue()
- {
- return m_value;
- }
-
- public boolean isMandatory()
- {
- return m_isMandatory;
- }
-
- public String toString()
- {
- return m_name + "=" + m_value;
- }
-}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Capability.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Capability.java
deleted file mode 100644
index 7c4e0f5..0000000
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Capability.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.connect.felix.framework.capabilityset;
-
-import java.util.List;
-
-public interface Capability
-{
- static final String MODULE_NAMESPACE = "module";
- static final String HOST_NAMESPACE = "host";
- static final String PACKAGE_NAMESPACE = "package";
- static final String SINGLETON_NAMESPACE = "singleton";
-
- public static final String PACKAGE_ATTR = "package";
- public static final String VERSION_ATTR = "version";
-
- String getNamespace();
-
- Directive getDirective(String name);
-
- List<Directive> getDirectives();
-
- Attribute getAttribute(String name);
-
- List<Attribute> getAttributes();
-
- List<String> getUses();
-}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/CapabilitySet.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/CapabilitySet.java
index 895809b..cfeccef 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/CapabilitySet.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/CapabilitySet.java
@@ -31,33 +31,34 @@
import java.util.Set;
import java.util.TreeMap;
-import org.apache.felix.connect.felix.framework.util.StringComparator;
-import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.resource.Capability;
-public class CapabilitySet
+import org.apache.felix.connect.felix.framework.util.StringComparator;
+
+public class CapabilitySet<T extends Capability>
{
- private final Map<String, Map<Object, Set<BundleCapability>>> m_indices;
- private final Set<BundleCapability> m_capSet = new HashSet<BundleCapability>();
+ private final Map<String, Map<Object, Set<T>>> m_indices;
+ private final Set<T> m_capSet = new HashSet<T>();
public CapabilitySet(List<String> indexProps, boolean caseSensitive)
{
m_indices = (caseSensitive)
- ? new TreeMap<String, Map<Object, Set<BundleCapability>>>()
- : new TreeMap<String, Map<Object, Set<BundleCapability>>>(
- new StringComparator(false));
+ ? new TreeMap<String, Map<Object, Set<T>>>()
+ : new TreeMap<String, Map<Object, Set<T>>>(
+ new StringComparator(false));
for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
{
m_indices.put(
- indexProps.get(i), new HashMap<Object, Set<BundleCapability>>());
+ indexProps.get(i), new HashMap<Object, Set<T>>());
}
}
- public void addCapability(BundleCapability cap)
+ public void addCapability(T cap)
{
m_capSet.add(cap);
// Index capability.
- for (Entry<String, Map<Object, Set<BundleCapability>>> entry : m_indices.entrySet())
+ for (Entry<String, Map<Object, Set<T>>> entry : m_indices.entrySet())
{
Object value = cap.getAttributes().get(entry.getKey());
if (value != null)
@@ -67,7 +68,7 @@
value = convertArrayToList(value);
}
- Map<Object, Set<BundleCapability>> index = entry.getValue();
+ Map<Object, Set<T>> index = entry.getValue();
if (value instanceof Collection)
{
@@ -86,22 +87,22 @@
}
private void indexCapability(
- Map<Object, Set<BundleCapability>> index, BundleCapability cap, Object capValue)
+ Map<Object, Set<T>> index, T cap, Object capValue)
{
- Set<BundleCapability> caps = index.get(capValue);
+ Set<T> caps = index.get(capValue);
if (caps == null)
{
- caps = new HashSet<BundleCapability>();
+ caps = new HashSet<T>();
index.put(capValue, caps);
}
caps.add(cap);
}
- public void removeCapability(BundleCapability cap)
+ public void removeCapability(T cap)
{
if (m_capSet.remove(cap))
{
- for (Entry<String, Map<Object, Set<BundleCapability>>> entry : m_indices.entrySet())
+ for (Entry<String, Map<Object, Set<T>>> entry : m_indices.entrySet())
{
Object value = cap.getAttributes().get(entry.getKey());
if (value != null)
@@ -111,7 +112,7 @@
value = convertArrayToList(value);
}
- Map<Object, Set<BundleCapability>> index = entry.getValue();
+ Map<Object, Set<T>> index = entry.getValue();
if (value instanceof Collection)
{
@@ -131,9 +132,9 @@
}
private void deindexCapability(
- Map<Object, Set<BundleCapability>> index, BundleCapability cap, Object value)
+ Map<Object, Set<T>> index, T cap, Object value)
{
- Set<BundleCapability> caps = index.get(value);
+ Set<T> caps = index.get(value);
if (caps != null)
{
caps.remove(cap);
@@ -144,18 +145,18 @@
}
}
- public Set<BundleCapability> match(SimpleFilter sf, boolean obeyMandatory)
+ public Set<T> match(SimpleFilter sf, boolean obeyMandatory)
{
- Set<BundleCapability> matches = match(m_capSet, sf);
- return matches;
- /* return (obeyMandatory)
+ Set<T> matches = match(m_capSet, sf);
+ return /* (obeyMandatory)
? matchMandatory(matches, sf)
- : matches;*/
+ : */ matches;
}
- private Set<BundleCapability> match(Set<BundleCapability> caps, SimpleFilter sf)
+ @SuppressWarnings("unchecked")
+ private Set<T> match(Set<T> caps, SimpleFilter sf)
{
- Set<BundleCapability> matches = new HashSet<BundleCapability>();
+ Set<T> matches = new HashSet<T>();
if (sf.getOperation() == SimpleFilter.MATCH_ALL)
{
@@ -179,9 +180,9 @@
// Evaluate each subfilter against the remaining capabilities.
// For OR we calculate the union of each subfilter.
List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; i < sfs.size(); i++)
+ for (SimpleFilter sf1 : sfs)
{
- matches.addAll(match(caps, sfs.get(i)));
+ matches.addAll(match(caps, sf1));
}
}
else if (sf.getOperation() == SimpleFilter.NOT)
@@ -190,17 +191,17 @@
// For OR we calculate the union of each subfilter.
matches.addAll(caps);
List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; i < sfs.size(); i++)
+ for (SimpleFilter sf1 : sfs)
{
- matches.removeAll(match(caps, sfs.get(i)));
+ matches.removeAll(match(caps, sf1));
}
}
else
{
- Map<Object, Set<BundleCapability>> index = m_indices.get(sf.getName());
+ Map<Object, Set<T>> index = m_indices.get(sf.getName());
if ((sf.getOperation() == SimpleFilter.EQ) && (index != null))
{
- Set<BundleCapability> existingCaps = index.get(sf.getValue());
+ Set<T> existingCaps = index.get(sf.getValue());
if (existingCaps != null)
{
matches.addAll(existingCaps);
@@ -209,9 +210,8 @@
}
else
{
- for (Iterator<BundleCapability> it = caps.iterator(); it.hasNext(); )
+ for (T cap : caps)
{
- BundleCapability cap = it.next();
Object lhs = cap.getAttributes().get(sf.getName());
if (lhs != null)
{
@@ -227,12 +227,13 @@
return matches;
}
- /* public static boolean matches(BundleCapability cap, SimpleFilter sf)
- {
- return matchesInternal(cap, sf) && matchMandatory(cap, sf);
- }
-*/
- private static boolean matchesInternal(BundleCapability cap, SimpleFilter sf)
+ /* public static boolean matches(BundleCapability cap, SimpleFilter sf)
+ {
+ return matchesInternal(cap, sf) && matchMandatory(cap, sf);
+ }
+ */
+ @SuppressWarnings("unchecked")
+ private boolean matchesInternal(T cap, SimpleFilter sf)
{
boolean matched = true;
@@ -268,9 +269,9 @@
// Evaluate each subfilter against the remaining capabilities.
// For OR we calculate the union of each subfilter.
List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
- for (int i = 0; i < sfs.size(); i++)
+ for (SimpleFilter sf1 : sfs)
{
- matched = !(matchesInternal(cap, sfs.get(i)));
+ matched = !(matchesInternal(cap, sf1));
}
}
else
@@ -286,12 +287,13 @@
return matched;
}
- /* private static Set<BundleCapability> matchMandatory(
- Set<BundleCapability> caps, SimpleFilter sf)
+ /*
+ private Set<T> matchMandatory(
+ Set<T> caps, SimpleFilter sf)
{
- for (Iterator<BundleCapability> it = caps.iterator(); it.hasNext(); )
+ for (Iterator<T> it = caps.iterator(); it.hasNext(); )
{
- BundleCapability cap = it.next();
+ T cap = it.next();
if (!matchMandatory(cap, sf))
{
it.remove();
@@ -300,12 +302,12 @@
return caps;
}
- private static boolean matchMandatory(BundleCapability cap, SimpleFilter sf)
+ private boolean matchMandatory(T cap, SimpleFilter sf)
{
Map<String, Object> attrs = cap.getAttributes();
for (Entry<String, Object> entry : attrs.entrySet())
{
- if (((BundleCapability) cap).isAttributeMandatory(entry.getKey())
+ if (((T) cap).isAttributeMandatory(entry.getKey())
&& !matchMandatoryAttrbute(entry.getKey(), sf))
{
return false;
@@ -314,7 +316,7 @@
return true;
}
- private static boolean matchMandatoryAttrbute(String attrName, SimpleFilter sf)
+ private boolean matchMandatoryAttrbute(String attrName, SimpleFilter sf)
{
if ((sf.getName() != null) && sf.getName().equals(attrName))
{
@@ -336,8 +338,9 @@
return false;
}*/
- private static final Class<?>[] STRING_CLASS = new Class[] { String.class };
+ private static final Class<?>[] STRING_CLASS = new Class[]{String.class};
+ @SuppressWarnings("unchecked")
private static boolean compare(Object lhs, Object rhsUnknown, int op)
{
if (lhs == null)
@@ -382,66 +385,42 @@
switch (op)
{
case SimpleFilter.EQ:
- try
- {
- return (((Comparable) lhs).compareTo(rhs) == 0);
- }
- catch (Exception ex)
- {
- return false;
- }
+ try
+ {
+ return (((Comparable) lhs).compareTo(rhs) == 0);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
case SimpleFilter.GTE:
- try
- {
- return (((Comparable) lhs).compareTo(rhs) >= 0);
- }
- catch (Exception ex)
- {
- return false;
- }
+ try
+ {
+ return (((Comparable) lhs).compareTo(rhs) >= 0);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
case SimpleFilter.LTE:
- try
- {
- return (((Comparable) lhs).compareTo(rhs) <= 0);
- }
- catch (Exception ex)
- {
- return false;
- }
+ try
+ {
+ return (((Comparable) lhs).compareTo(rhs) <= 0);
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
case SimpleFilter.APPROX:
- return compareApproximate(((Comparable) lhs), rhs);
+ return compareApproximate(lhs, rhs);
case SimpleFilter.SUBSTRING:
- return SimpleFilter.compareSubstring((List<String>) rhs, (String) lhs);
+ return SimpleFilter.compareSubstring((List<String>) rhs, (String) lhs);
default:
- throw new RuntimeException(
+ throw new RuntimeException(
"Unknown comparison operator: " + op);
}
}
- // Booleans do not implement comparable, so special case them.
- else if (lhs instanceof Boolean)
- {
- Object rhs;
- try
- {
- rhs = coerceType(lhs, (String) rhsUnknown);
- }
- catch (Exception ex)
- {
- return false;
- }
- switch (op)
- {
- case SimpleFilter.EQ:
- case SimpleFilter.GTE:
- case SimpleFilter.LTE:
- case SimpleFilter.APPROX:
- return (lhs.equals(rhs));
- default:
- throw new RuntimeException(
- "Unknown comparison operator: " + op);
- }
- }
// If the LHS is not a comparable or boolean, check if it is an
// array. If so, convert it to a list so we can treat it as a
@@ -455,9 +434,9 @@
// of the collection until a match is found.
if (lhs instanceof Collection)
{
- for (Iterator iter = ((Collection) lhs).iterator(); iter.hasNext();)
+ for (Object o : ((Collection) lhs))
{
- if (compare(iter.next(), rhsUnknown, op))
+ if (compare(o, rhsUnknown, op))
{
return true;
}
@@ -467,7 +446,7 @@
}
// Spec says SUBSTRING is false for all types other than string.
- if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
+ if (op == SimpleFilter.SUBSTRING)
{
return false;
}
@@ -489,19 +468,19 @@
if (rhs instanceof String)
{
return removeWhitespace((String) lhs)
- .equalsIgnoreCase(removeWhitespace((String) rhs));
+ .equalsIgnoreCase(removeWhitespace((String) rhs));
}
else if (rhs instanceof Character)
{
return Character.toLowerCase(((Character) lhs))
- == Character.toLowerCase(((Character) rhs));
+ == Character.toLowerCase(((Character) rhs));
}
return lhs.equals(rhs);
}
private static String removeWhitespace(String s)
{
- StringBuffer sb = new StringBuffer(s.length());
+ StringBuilder sb = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++)
{
if (!Character.isWhitespace(s.charAt(i)))
@@ -523,14 +502,14 @@
// Try to convert the RHS type to the LHS type by using
// the string constructor of the LHS class, if it has one.
- Object rhs = null;
+ Object rhs;
try
{
// The Character class is a special case, since its constructor
// does not take a string, so handle it separately.
if (lhs instanceof Character)
{
- rhs = new Character(rhsString.charAt(0));
+ rhs = rhsString.charAt(0);
}
else
{
@@ -541,16 +520,16 @@
}
Constructor ctor = lhs.getClass().getConstructor(STRING_CLASS);
ctor.setAccessible(true);
- rhs = ctor.newInstance(new Object[] { rhsString });
+ rhs = ctor.newInstance(rhsString);
}
}
catch (Exception ex)
{
throw new Exception(
- "Could not instantiate class "
- + lhs.getClass().getName()
- + " from string constructor with argument '"
- + rhsString + "' because " + ex);
+ "Could not instantiate class "
+ + lhs.getClass().getName()
+ + " from string constructor with argument '"
+ + rhsString + "' because " + ex);
}
return rhs;
@@ -561,14 +540,13 @@
* array of primitive wrapper objects. This method simplifies processing
* LDAP filters since the special case of primitive arrays can be ignored.
*
- * @param array
- * An array of primitive types.
+ * @param array An array of primitive types.
* @return An corresponding array using pritive wrapper objects.
- **/
- private static List convertArrayToList(Object array)
+ */
+ private static List<Object> convertArrayToList(Object array)
{
int len = Array.getLength(array);
- List list = new ArrayList(len);
+ List<Object> list = new ArrayList<Object>(len);
for (int i = 0; i < len; i++)
{
list.add(Array.get(array, i));
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Directive.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Directive.java
deleted file mode 100644
index 9c6963d..0000000
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/Directive.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.connect.felix.framework.capabilityset;
-
-public class Directive
-{
- private final String m_name;
- private final Object m_value;
-
- public Directive(String name, Object value)
- {
- m_name = name;
- m_value = value;
- }
-
- public String getName()
- {
- return m_name;
- }
-
- public Object getValue()
- {
- return m_value;
- }
-
- public String toString()
- {
- return m_name + "=" + m_value;
- }
-}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/SimpleFilter.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/SimpleFilter.java
index 22f57cf..c8f0310 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/SimpleFilter.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/capabilityset/SimpleFilter.java
@@ -60,6 +60,7 @@
return m_op;
}
+ @SuppressWarnings("unchecked")
public String toString()
{
String s = null;
@@ -84,8 +85,7 @@
s = "(" + m_name + ">=" + toEncodedString(m_value) + ")";
break;
case SUBSTRING:
- s = "(" + m_name + "=" + unparseSubstring((List<String>) m_value)
- + ")";
+ s = "(" + m_name + "=" + unparseSubstring((List<String>) m_value) + ")";
break;
case PRESENT:
s = "(" + m_name + "=*)";
@@ -97,19 +97,19 @@
return s;
}
- private static String toString(List list)
+ private static String toString(List<?> list)
{
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < list.size(); i++)
+ StringBuilder sb = new StringBuilder();
+ for (Object aList : list)
{
- sb.append(list.get(i).toString());
+ sb.append(aList.toString());
}
return sb.toString();
}
private static String toDecodedString(String s, int startIdx, int endIdx)
{
- StringBuffer sb = new StringBuffer(endIdx - startIdx);
+ StringBuilder sb = new StringBuilder(endIdx - startIdx);
boolean escaped = false;
for (int i = 0; i < (endIdx - startIdx); i++)
{
@@ -133,7 +133,7 @@
if (o instanceof String)
{
String s = (String) o;
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
@@ -150,6 +150,7 @@
return o.toString();
}
+ @SuppressWarnings("unchecked")
public static SimpleFilter parse(String filter)
{
int idx = skipWhitespace(filter, 0);
@@ -166,7 +167,7 @@
}
SimpleFilter sf = null;
- List stack = new ArrayList();
+ List<Object> stack = new ArrayList<Object>();
boolean isEscaped = false;
while (idx < filter.length())
{
@@ -192,7 +193,7 @@
}
else
{
- stack.add(0, new Integer(idx));
+ stack.add(0, idx);
}
}
else if (filter.charAt(idx) == '|')
@@ -206,7 +207,7 @@
}
else
{
- stack.add(0, new Integer(idx));
+ stack.add(0, idx);
}
}
else if (filter.charAt(idx) == '!')
@@ -220,12 +221,12 @@
}
else
{
- stack.add(0, new Integer(idx));
+ stack.add(0, idx);
}
}
else
{
- stack.add(0, new Integer(idx));
+ stack.add(0, idx);
}
}
else if (!isEscaped && (filter.charAt(idx) == ')'))
@@ -233,36 +234,28 @@
Object top = stack.remove(0);
if (top instanceof SimpleFilter)
{
- if (!stack.isEmpty()
- && (stack.get(0) instanceof SimpleFilter))
+ if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
{
- ((List) ((SimpleFilter) stack.get(0)).m_value).add(top);
+ ((List<Object>) ((SimpleFilter) stack.get(0)).m_value).add(top);
}
else
{
sf = (SimpleFilter) top;
}
}
- else if (!stack.isEmpty()
- && (stack.get(0) instanceof SimpleFilter))
+ else if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
{
- ((List) ((SimpleFilter) stack.get(0)).m_value)
- .add(SimpleFilter.subfilter(filter,
- ((Integer) top).intValue(), idx));
+ ((List<Object>) ((SimpleFilter) stack.get(0)).m_value)
+ .add(SimpleFilter.subfilter(filter, (Integer) top, idx));
}
else
{
- sf = SimpleFilter.subfilter(filter,
- ((Integer) top).intValue(), idx);
+ sf = SimpleFilter.subfilter(filter, (Integer) top, idx);
}
}
- else if (!isEscaped && (filter.charAt(idx) == '\\'))
- {
- isEscaped = true;
- }
else
{
- isEscaped = false;
+ isEscaped = !isEscaped && (filter.charAt(idx) == '\\');
}
idx = skipWhitespace(filter, idx + 1);
@@ -270,15 +263,14 @@
if (sf == null)
{
- throw new IllegalArgumentException("Missing closing parenthesis: "
- + filter);
+ throw new IllegalArgumentException("Missing closing parenthesis: " + filter);
}
return sf;
}
private static SimpleFilter subfilter(String filter, int startIdx,
- int endIdx)
+ int endIdx)
{
final String opChars = "=<>~";
@@ -307,7 +299,7 @@
startIdx = skipWhitespace(filter, attrEndIdx);
// Determine the operator type.
- int op = -1;
+ int op;
switch (filter.charAt(startIdx))
{
case '=':
@@ -372,8 +364,8 @@
public static List<String> parseSubstring(String value)
{
- List<String> pieces = new ArrayList();
- StringBuffer ss = new StringBuffer();
+ List<String> pieces = new ArrayList<String>();
+ StringBuilder ss = new StringBuilder();
// int kind = SIMPLE; // assume until proven otherwise
boolean wasStar = false; // indicates last piece was a star
boolean leftstar = false; // track if the initial piece is a star
@@ -383,7 +375,7 @@
// We assume (sub)strings can contain leading and trailing blanks
boolean escaped = false;
- loop: for (;;)
+ for (; ; )
{
if (idx >= value.length())
{
@@ -401,7 +393,7 @@
// the string "" (!=null)
}
ss.setLength(0);
- break loop;
+ break;
}
// Read the next character and account for escapes.
@@ -460,7 +452,7 @@
public static String unparseSubstring(List<String> pieces)
{
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int i = 0; i < pieces.size(); i++)
{
if (i > 0)
@@ -495,7 +487,7 @@
int index = 0;
- loop: for (int i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
{
String piece = pieces.get(i);
@@ -506,7 +498,7 @@
if (!s.startsWith(piece))
{
result = false;
- break loop;
+ break;
}
}
@@ -514,15 +506,8 @@
// string ends with it.
if (i == len - 1)
{
- if (s.endsWith(piece))
- {
- result = true;
- }
- else
- {
- result = false;
- }
- break loop;
+ result = s.endsWith(piece);
+ break;
}
// If this is neither the first or last piece, then
@@ -533,7 +518,7 @@
if (index < 0)
{
result = false;
- break loop;
+ break;
}
}
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/EventDispatcher.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/EventDispatcher.java
index ffd59b5..e2002ac 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/EventDispatcher.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/EventDispatcher.java
@@ -20,10 +20,16 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.EventListener;
import java.util.EventObject;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -36,27 +42,23 @@
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.framework.hooks.bundle.EventHook;
+import org.osgi.framework.hooks.service.EventListenerHook;
import org.osgi.framework.hooks.service.ListenerHook;
import org.osgi.framework.launch.Framework;
import org.apache.felix.connect.felix.framework.ServiceRegistry;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
public class EventDispatcher
{
private final ServiceRegistry m_registry;
- private Map<BundleContext, List<ListenerInfo>> m_fwkListeners = Collections.EMPTY_MAP;
- private Map<BundleContext, List<ListenerInfo>> m_bndlListeners = Collections.EMPTY_MAP;
- private Map<BundleContext, List<ListenerInfo>> m_syncBndlListeners = Collections.EMPTY_MAP;
- private Map<BundleContext, List<ListenerInfo>> m_svcListeners = Collections.EMPTY_MAP;
+ private Map<BundleContext, List<ListenerInfo>> m_fwkListeners = Collections.emptyMap();
+ private Map<BundleContext, List<ListenerInfo>> m_bndlListeners = Collections.emptyMap();
+ private Map<BundleContext, List<ListenerInfo>> m_syncBndlListeners = Collections.emptyMap();
+ private Map<BundleContext, List<ListenerInfo>> m_svcListeners = Collections.emptyMap();
// A single thread is used to deliver events for all dispatchers.
private static Thread m_thread = null;
- private final static String m_threadLock = new String("thread lock");
+ private final static String m_threadLock = "thread lock";
private static int m_references = 0;
private static volatile boolean m_stopping = false;
// List of requests.
@@ -66,7 +68,7 @@
private static final boolean m_sync = "true".equalsIgnoreCase(System
.getProperty("org.apache.felix.connect.events.sync"));
-
+
public EventDispatcher(ServiceRegistry registry)
{
m_registry = registry;
@@ -153,6 +155,7 @@
}
catch (InterruptedException ex)
{
+ // Ignore
}
}
}
@@ -167,8 +170,7 @@
}
else if (!clazz.isInstance(l))
{
- throw new IllegalArgumentException(
- "Listener not of type " + clazz.getName());
+ throw new IllegalArgumentException("Listener not of type " + clazz.getName());
}
// See if we can simply update the listener, if so then
@@ -192,7 +194,7 @@
// Bundle context is no longer valid, so just return.
}
- Map<BundleContext, List<ListenerInfo>> listeners = null;
+ Map<BundleContext, List<ListenerInfo>> listeners;
Object acc = null;
if (clazz == FrameworkListener.class)
@@ -231,7 +233,7 @@
// Add listener.
ListenerInfo info =
- new ListenerInfo(bc.getBundle(), bc, clazz, l, filter, acc, false);
+ new ListenerInfo(bc.getBundle(), bc, clazz, l, filter, acc, false);
listeners = addListenerInfo(listeners, info);
if (clazz == FrameworkListener.class)
@@ -258,7 +260,7 @@
}
public ListenerHook.ListenerInfo removeListener(
- BundleContext bc, Class clazz, EventListener l)
+ BundleContext bc, Class clazz, EventListener l)
{
ListenerHook.ListenerInfo returnInfo = null;
@@ -270,13 +272,13 @@
else if (!clazz.isInstance(l))
{
throw new IllegalArgumentException(
- "Listener not of type " + clazz.getName());
+ "Listener not of type " + clazz.getName());
}
// Lock the object to remove the listener.
synchronized (this)
{
- Map<BundleContext, List<ListenerInfo>> listeners = null;
+ Map<BundleContext, List<ListenerInfo>> listeners;
if (clazz == FrameworkListener.class)
{
@@ -311,8 +313,8 @@
{
ListenerInfo info = infos.get(i);
if (info.getBundleContext().equals(bc)
- && (info.getListenerClass() == clazz)
- && (info.getListener() == l))
+ && (info.getListenerClass() == clazz)
+ && (info.getListener() == l))
{
// For service listeners, we must return some info about
// the listener for the ListenerHook callback.
@@ -405,19 +407,19 @@
{
ListenerInfo info = infos.get(i);
if (info.getBundleContext().equals(bc)
- && (info.getListenerClass() == clazz)
- && (info.getListener() == l))
+ && (info.getListenerClass() == clazz)
+ && (info.getListener() == l))
{
// The spec says to update the filter in this case.
Filter oldFilter = info.getParsedFilter();
ListenerInfo newInfo = new ListenerInfo(
- info.getBundle(),
- info.getBundleContext(),
- info.getListenerClass(),
- info.getListener(),
- filter,
- info.getSecurityContext(),
- info.isRemoved());
+ info.getBundle(),
+ info.getBundleContext(),
+ info.getListenerClass(),
+ info.getListener(),
+ filter,
+ info.getSecurityContext(),
+ info.isRemoved());
m_svcListeners = updateListenerInfo(m_svcListeners, i, newInfo);
return oldFilter;
}
@@ -429,15 +431,14 @@
}
/**
- * Returns all existing service listener information into a collection of
+ * Returns all existing service listener information into a List of
* ListenerHook.ListenerInfo objects. This is used the first time a listener
* hook is registered to synchronize it with the existing set of listeners.
*
* @return Returns all existing service listener information into a
- * collection of ListenerHook.ListenerInfo objects
- *
+ * List of ListenerHook.ListenerInfo objects
*/
- public Collection<ListenerHook.ListenerInfo> getAllServiceListeners()
+ public List<ListenerHook.ListenerInfo> getAllServiceListeners()
{
List<ListenerHook.ListenerInfo> listeners = new ArrayList<ListenerHook.ListenerInfo>();
synchronized (this)
@@ -453,7 +454,7 @@
public void fireFrameworkEvent(FrameworkEvent event)
{
// Take a snapshot of the listener array.
- Map<BundleContext, List<ListenerInfo>> listeners = null;
+ Map<BundleContext, List<ListenerInfo>> listeners;
synchronized (this)
{
listeners = m_fwkListeners;
@@ -466,8 +467,8 @@
public void fireBundleEvent(BundleEvent event)
{
// Take a snapshot of the listener array.
- Map<BundleContext, List<ListenerInfo>> listeners = null;
- Map<BundleContext, List<ListenerInfo>> syncListeners = null;
+ Map<BundleContext, List<ListenerInfo>> listeners;
+ Map<BundleContext, List<ListenerInfo>> syncListeners;
synchronized (this)
{
listeners = m_bndlListeners;
@@ -477,14 +478,13 @@
// Create a whitelist of bundle context for bundle listeners,
// if we have hooks.
Set<BundleContext> whitelist = createWhitelistFromHooks(event, event.getBundle(),
- listeners, syncListeners, org.osgi.framework.hooks.bundle.EventHook.class);
+ listeners.keySet(), syncListeners.keySet());
// If we have a whitelist, then create copies of only the whitelisted
// listeners.
if (whitelist != null)
{
- Map<BundleContext, List<ListenerInfo>> copy =
- new HashMap<BundleContext, List<ListenerInfo>>();
+ Map<BundleContext, List<ListenerInfo>> copy = new HashMap<BundleContext, List<ListenerInfo>>();
for (BundleContext bc : whitelist)
{
List<ListenerInfo> infos = listeners.get(bc);
@@ -507,188 +507,54 @@
}
// Fire synchronous bundle listeners immediately on the calling thread.
- fireEventImmediately(
- this, Request.BUNDLE_EVENT, syncListeners, event, null);
+ fireEventImmediately(this, Request.BUNDLE_EVENT, syncListeners, event, null);
// The spec says that asynchronous bundle listeners do not get events
// of types STARTING, STOPPING, or LAZY_ACTIVATION.
if ((event.getType() != BundleEvent.STARTING)
- && (event.getType() != BundleEvent.STOPPING)
- && (event.getType() != BundleEvent.LAZY_ACTIVATION))
+ && (event.getType() != BundleEvent.STOPPING)
+ && (event.getType() != BundleEvent.LAZY_ACTIVATION))
{
// Fire asynchronous bundle listeners on a separate thread.
- fireEventAsynchronously(
- this, Request.BUNDLE_EVENT, listeners, event);
+ fireEventAsynchronously(this, Request.BUNDLE_EVENT, listeners, event);
}
}
- public void fireServiceEvent(
- final ServiceEvent event, final Dictionary oldProps, final Framework felix)
- {
- // Take a snapshot of the listener array.
- Map<BundleContext, List<ListenerInfo>> listeners = null;
- synchronized (this)
- {
- listeners = m_svcListeners;
- }
-
- // Use service registry hooks to filter target listeners.
- listeners = filterListenersUsingHooks(event, felix, listeners);
-
- // Fire all service events immediately on the calling thread.
- fireEventImmediately(
- this, Request.SERVICE_EVENT, listeners, event, oldProps);
- }
-
-// TODO: OSGi R4.3 - This is ugly and inefficient.
- private Map<BundleContext, List<ListenerInfo>> filterListenersUsingHooks(
- ServiceEvent event, Framework felix, Map<BundleContext, List<ListenerInfo>> listeners)
- {
- Set<ServiceReference<org.osgi.framework.hooks.service.EventHook>> ehs =
- m_registry.getHooks(org.osgi.framework.hooks.service.EventHook.class);
- if ((ehs != null) && !ehs.isEmpty())
- {
- // Create a whitelist of bundle context for bundle listeners,
- // if we have hooks.
- Set<BundleContext> whitelist = createWhitelistFromHooks(event, felix,
- listeners, null, org.osgi.framework.hooks.service.EventHook.class);
-
- // If we have a whitelist, then create copies of only the whitelisted
- // listeners.
- if (whitelist != null)
- {
- Map<BundleContext, List<ListenerInfo>> copy =
- new HashMap<BundleContext, List<ListenerInfo>>();
- for (BundleContext bc : whitelist)
- {
- copy.put(bc, listeners.get(bc));
- }
- listeners = copy;
- }
- }
-
- Set<ServiceReference<org.osgi.framework.hooks.service.EventListenerHook>> elhs =
- m_registry.getHooks(org.osgi.framework.hooks.service.EventListenerHook.class);
- if ((elhs != null) && !elhs.isEmpty())
- {
- // Create shrinkable map with shrinkable collections.
- Map<BundleContext, Collection<ListenerHook.ListenerInfo>> shrinkableMap =
- new HashMap<BundleContext, Collection<ListenerHook.ListenerInfo>>();
- for (Entry<BundleContext, List<ListenerInfo>> entry : listeners.entrySet())
- {
- Collection shrinkableCollection =
- new ShrinkableCollection(new ArrayList(entry.getValue()));
- shrinkableMap.put(
- entry.getKey(),
- (Collection<ListenerHook.ListenerInfo>) shrinkableCollection);
- }
- shrinkableMap =
- new ShrinkableMap<BundleContext, Collection<ListenerHook.ListenerInfo>>(shrinkableMap);
- for (ServiceReference<org.osgi.framework.hooks.service.EventListenerHook> sr : elhs)
- {
- if (felix != null)
- {
- org.osgi.framework.hooks.service.EventListenerHook elh = null;
- try
- {
- elh = m_registry.getService(felix, sr);
- }
- catch (Exception ex)
- {
- // If we can't get the hook, then ignore it.
- }
- if (elh != null)
- {
- try
- {
- elh.event(event, shrinkableMap);
- }
- catch (Throwable th)
- {
- System.out.println("Problem invoking event hook");
- th.printStackTrace();
- }
- finally
- {
- m_registry.ungetService(felix, sr);
- }
- }
- }
- }
-// TODO: OSGi R4.3 - Should check and only do this if there was a change.
-// Also, it is inefficient to have to create new lists for the values.
- Map<BundleContext, List<ListenerInfo>> newMap =
- new HashMap<BundleContext, List<ListenerInfo>>();
- for (Entry entry : shrinkableMap.entrySet())
- {
- if (!((Collection) entry.getValue()).isEmpty())
- {
- newMap.put((BundleContext) entry.getKey(),
- new ArrayList<ListenerInfo>((Collection) entry.getValue()));
- }
- }
- listeners = newMap;
- }
-
- return listeners;
- }
-
private <T> Set<BundleContext> createWhitelistFromHooks(
- EventObject event, Bundle bundle,
- Map<BundleContext, List<ListenerInfo>> listeners1,
- Map<BundleContext, List<ListenerInfo>> listeners2,
- Class<T> hookClass)
+ BundleEvent event,
+ Bundle bundle,
+ Set<BundleContext> listeners1,
+ Set<BundleContext> listeners2)
{
+ if (bundle == null)
+ {
+ return null;
+ }
// Create a whitelist of bundle context, if we have hooks.
Set<BundleContext> whitelist = null;
- Set<ServiceReference<T>> hooks = m_registry.getHooks(hookClass);
+ Set<ServiceReference<EventHook>> hooks = m_registry.getHooks(EventHook.class);
if ((hooks != null) && !hooks.isEmpty())
{
whitelist = new HashSet<BundleContext>();
- for (Entry<BundleContext, List<ListenerInfo>> entry : listeners1.entrySet())
- {
- whitelist.add(entry.getKey());
- }
- if (listeners2 != null)
- {
- for (Entry<BundleContext, List<ListenerInfo>> entry : listeners2.entrySet())
- {
- whitelist.add(entry.getKey());
- }
- }
+ whitelist.addAll(listeners1);
+ whitelist.addAll(listeners2);
int originalSize = whitelist.size();
- ShrinkableCollection<BundleContext> shrinkable =
- new ShrinkableCollection<BundleContext>(whitelist);
- for (ServiceReference<T> sr : hooks)
+ ShrinkableCollection<BundleContext> shrinkable = new ShrinkableCollection<BundleContext>(whitelist);
+ for (ServiceReference<EventHook> sr : hooks)
{
- if (bundle != null)
+ try
{
- T eh = null;
- try
- {
- eh = m_registry.getService(bundle, sr);
- }
- catch (Exception ex)
- {
- // If we can't get the hook, then ignore it.
- }
+ EventHook eh = m_registry.getService(bundle, sr);
if (eh != null)
{
try
{
- if (eh instanceof org.osgi.framework.hooks.service.EventHook)
- {
- ((org.osgi.framework.hooks.service.EventHook) eh).event((ServiceEvent) event, shrinkable);
- }
- else if (eh instanceof org.osgi.framework.hooks.bundle.EventHook)
- {
- ((org.osgi.framework.hooks.bundle.EventHook) eh).event((BundleEvent) event, shrinkable);
- }
+ eh.event(event, shrinkable);
}
catch (Throwable th)
{
- System.out.println("Problem invoking event hook");
+ System.out.println("Problem invoking bundle hook");
th.printStackTrace();
}
finally
@@ -697,6 +563,10 @@
}
}
}
+ catch (Throwable th)
+ {
+ // If we can't get the hook, then ignore it.
+ }
}
// If the whitelist hasn't changed, then null it to avoid having
// to do whitelist lookups during event delivery.
@@ -708,16 +578,130 @@
return whitelist;
}
+ public void fireServiceEvent(final ServiceEvent event, final Dictionary<String, ?> oldProps, final Framework felix)
+ {
+ // Take a snapshot of the listener array.
+ Map<BundleContext, List<ListenerInfo>> listeners;
+ synchronized (this)
+ {
+ listeners = m_svcListeners;
+ }
+
+ // Use service registry hooks to filter target listeners.
+ listeners = filterListenersUsingHooks(event, felix, listeners);
+
+ // Fire all service events immediately on the calling thread.
+ fireEventImmediately(this, Request.SERVICE_EVENT, listeners, event, oldProps);
+ }
+
+ private Map<BundleContext, List<ListenerInfo>> filterListenersUsingHooks(
+ ServiceEvent event, Framework felix, Map<BundleContext, List<ListenerInfo>> listeners)
+ {
+ if (felix == null)
+ {
+ return listeners;
+ }
+
+ Set<ServiceReference<org.osgi.framework.hooks.service.EventHook>> ehs =
+ m_registry.getHooks(org.osgi.framework.hooks.service.EventHook.class);
+ Set<ServiceReference<EventListenerHook>> elhs =
+ m_registry.getHooks(EventListenerHook.class);
+
+ if ((ehs == null || ehs.isEmpty()) && (elhs == null || elhs.isEmpty()))
+ {
+ return listeners;
+ }
+
+ // Create a shrinkable copy of the map
+ Map<BundleContext, List<ListenerInfo>> shrinkableMap = new HashMap<BundleContext, List<ListenerInfo>>();
+ for (Entry<BundleContext, List<ListenerInfo>> entry : listeners.entrySet())
+ {
+ List<ListenerInfo> shrinkableList =
+ new ShrinkableList<ListenerInfo>(
+ new ArrayList<ListenerInfo>(entry.getValue()));
+ shrinkableMap.put(entry.getKey(), shrinkableList);
+ }
+ shrinkableMap = new ShrinkableMap<BundleContext, List<ListenerInfo>>(shrinkableMap);
+
+ // Go through service EventHook
+ if (ehs != null && !ehs.isEmpty())
+ {
+ Set<BundleContext> shrink = shrinkableMap.keySet();
+ for (ServiceReference<org.osgi.framework.hooks.service.EventHook> sr : ehs)
+ {
+ try
+ {
+ org.osgi.framework.hooks.service.EventHook eh = m_registry.getService(felix, sr);
+ if (eh != null)
+ {
+ try
+ {
+ eh.event(event, shrink);
+ }
+ catch (Throwable th)
+ {
+ System.out.println("Problem invoking event hook");
+ th.printStackTrace();
+ }
+ finally
+ {
+ m_registry.ungetService(felix, sr);
+ }
+ }
+ }
+ catch (Throwable th)
+ {
+ // Ignore
+ }
+ }
+ }
+
+ // Go through EventListenerHook
+ if (elhs != null && !elhs.isEmpty())
+ {
+ @SuppressWarnings("unchecked")
+ Map<BundleContext, Collection<ListenerHook.ListenerInfo>> shrink =
+ (Map<BundleContext, Collection<ListenerHook.ListenerInfo>>) (Map) shrinkableMap;
+ for (ServiceReference<EventListenerHook> sr : elhs)
+ {
+ try
+ {
+ EventListenerHook elh = m_registry.getService(felix, sr);
+ if (elh != null)
+ {
+ try
+ {
+ elh.event(event, shrink);
+ }
+ catch (Throwable th)
+ {
+ System.out.println("Problem invoking event hook");
+ th.printStackTrace();
+ }
+ finally
+ {
+ m_registry.ungetService(felix, sr);
+ }
+ }
+ }
+ catch (Throwable th)
+ {
+ // Ignore
+ }
+ }
+ }
+
+ return shrinkableMap;
+ }
+
private static void fireEventAsynchronously(
- EventDispatcher dispatcher, int type,
- Map<BundleContext, List<ListenerInfo>> listeners,
- EventObject event)
+ EventDispatcher dispatcher, int type,
+ Map<BundleContext, List<ListenerInfo>> listeners,
+ EventObject event)
{
if (!m_sync)
{
- // TODO: should possibly check this within thread lock, seems to be
- // ok
- // though without
+ // TODO: should possibly check this within thread lock, seems to be ok though without
// If dispatch thread is stopped, then ignore dispatch request.
if (m_stopping || m_thread == null)
{
@@ -725,7 +709,7 @@
}
// First get a request from the pool or create one if necessary.
- Request req = null;
+ Request req;
synchronized (m_requestPool)
{
if (m_requestPool.size() > 0)
@@ -760,9 +744,9 @@
}
private static void fireEventImmediately(
- EventDispatcher dispatcher, int type,
- Map<BundleContext, List<ListenerInfo>> listeners,
- EventObject event, Dictionary oldProps)
+ EventDispatcher dispatcher, int type,
+ Map<BundleContext, List<ListenerInfo>> listeners,
+ EventObject event, Dictionary<String, ?> oldProps)
{
if (!listeners.isEmpty())
{
@@ -788,19 +772,17 @@
}
else if (type == Request.SERVICE_EVENT)
{
- invokeServiceListenerCallback(
- bundle, l, filter, acc, event, oldProps);
+ invokeServiceListenerCallback(bundle, l, filter, acc, event, oldProps);
}
}
catch (Throwable th)
{
if ((type != Request.FRAMEWORK_EVENT)
- || (((FrameworkEvent) event).getType() != FrameworkEvent.ERROR))
+ || (((FrameworkEvent) event).getType() != FrameworkEvent.ERROR))
{
System.out.println("EventDispatcher: Error during dispatch.");
th.printStackTrace();
- dispatcher.fireFrameworkEvent(
- new FrameworkEvent(FrameworkEvent.ERROR, bundle, th));
+ dispatcher.fireFrameworkEvent(new FrameworkEvent(FrameworkEvent.ERROR, bundle, th));
}
}
}
@@ -809,13 +791,12 @@
}
private static void invokeFrameworkListenerCallback(
- Bundle bundle, final EventListener l, final EventObject event)
+ Bundle bundle, final EventListener l, final EventObject event)
{
// The spec says only active bundles receive asynchronous events,
// but we will include starting bundles too otherwise
// it is impossible to see everything.
- if ((bundle.getState() == Bundle.STARTING)
- || (bundle.getState() == Bundle.ACTIVE))
+ if ((bundle.getState() == Bundle.STARTING) || (bundle.getState() == Bundle.ACTIVE))
{
((FrameworkListener) l).frameworkEvent((FrameworkEvent) event);
@@ -823,7 +804,7 @@
}
private static void invokeBundleListenerCallback(
- Bundle bundle, final EventListener l, final EventObject event)
+ Bundle bundle, final EventListener l, final EventObject event)
{
// A bundle listener is either synchronous or asynchronous.
// If the bundle listener is synchronous, then deliver the
@@ -831,25 +812,25 @@
// ACTIVE. If the listener is asynchronous, then deliver the
// event only to bundles that are STARTING or ACTIVE.
if (((SynchronousBundleListener.class.isAssignableFrom(l.getClass()))
- && ((bundle.getState() == Bundle.STARTING)
- || (bundle.getState() == Bundle.STOPPING)
- || (bundle.getState() == Bundle.ACTIVE)))
- || ((bundle.getState() == Bundle.STARTING)
- || (bundle.getState() == Bundle.ACTIVE)))
+ && ((bundle.getState() == Bundle.STARTING)
+ || (bundle.getState() == Bundle.STOPPING)
+ || (bundle.getState() == Bundle.ACTIVE)))
+ || ((bundle.getState() == Bundle.STARTING)
+ || (bundle.getState() == Bundle.ACTIVE)))
{
((BundleListener) l).bundleChanged((BundleEvent) event);
}
}
private static void invokeServiceListenerCallback(Bundle bundle,
- final EventListener l, Filter filter, Object acc,
- final EventObject event, final Dictionary oldProps)
+ final EventListener l, Filter filter, Object acc,
+ final EventObject event, final Dictionary<String, ?> oldProps)
{
// Service events should be delivered to STARTING,
// STOPPING, and ACTIVE bundles.
if ((bundle.getState() != Bundle.STARTING)
- && (bundle.getState() != Bundle.STOPPING)
- && (bundle.getState() != Bundle.ACTIVE))
+ && (bundle.getState() != Bundle.STOPPING)
+ && (bundle.getState() != Bundle.ACTIVE))
{
return;
}
@@ -864,12 +845,11 @@
{
// Dispatch according to the filter.
boolean matched = (filter == null)
- || filter.match(((ServiceEvent) event).getServiceReference());
+ || filter.match(((ServiceEvent) event).getServiceReference());
if (matched)
{
- ((ServiceListener) l)
- .serviceChanged((ServiceEvent) event);
+ ((ServiceListener) l).serviceChanged((ServiceEvent) event);
}
// We need to send an MODIFIED_ENDMATCH event if the listener
// matched previously.
@@ -878,8 +858,8 @@
if (filter.match(oldProps))
{
final ServiceEvent se = new ServiceEvent(
- ServiceEvent.MODIFIED_ENDMATCH,
- ((ServiceEvent) event).getServiceReference());
+ ServiceEvent.MODIFIED_ENDMATCH,
+ ((ServiceEvent) event).getServiceReference());
((ServiceListener) l).serviceChanged(se);
}
@@ -888,11 +868,11 @@
}
private static Map<BundleContext, List<ListenerInfo>> addListenerInfo(
- Map<BundleContext, List<ListenerInfo>> listeners, ListenerInfo info)
+ Map<BundleContext, List<ListenerInfo>> listeners, ListenerInfo info)
{
// Make a copy of the map, since we will be mutating it.
Map<BundleContext, List<ListenerInfo>> copy =
- new HashMap<BundleContext, List<ListenerInfo>>(listeners);
+ new HashMap<BundleContext, List<ListenerInfo>>(listeners);
// Remove the affected entry and make a copy so we can modify it.
List<ListenerInfo> infos = copy.remove(info.getBundleContext());
if (infos == null)
@@ -911,32 +891,32 @@
}
private static Map<BundleContext, List<ListenerInfo>> updateListenerInfo(
- Map<BundleContext, List<ListenerInfo>> listeners, int idx,
- ListenerInfo info)
+ Map<BundleContext, List<ListenerInfo>> listeners, int idx,
+ ListenerInfo info)
{
// Make a copy of the map, since we will be mutating it.
Map<BundleContext, List<ListenerInfo>> copy =
- new HashMap<BundleContext, List<ListenerInfo>>(listeners);
+ new HashMap<BundleContext, List<ListenerInfo>>(listeners);
// Remove the affected entry and make a copy so we can modify it.
List<ListenerInfo> infos = copy.remove(info.getBundleContext());
if (infos != null)
{
- infos = new ArrayList<ListenerInfo>(infos);
+ List<ListenerInfo> copylist = new ArrayList<ListenerInfo>(infos);
// Update the new listener info.
- infos.set(idx, info);
+ copylist.set(idx, info);
// Put the listeners back into the copy of the map and return it.
- copy.put(info.getBundleContext(), infos);
+ copy.put(info.getBundleContext(), copylist);
return copy;
}
return listeners;
}
private static Map<BundleContext, List<ListenerInfo>> removeListenerInfo(
- Map<BundleContext, List<ListenerInfo>> listeners, BundleContext bc, int idx)
+ Map<BundleContext, List<ListenerInfo>> listeners, BundleContext bc, int idx)
{
// Make a copy of the map, since we will be mutating it.
Map<BundleContext, List<ListenerInfo>> copy =
- new HashMap<BundleContext, List<ListenerInfo>>(listeners);
+ new HashMap<BundleContext, List<ListenerInfo>>(listeners);
// Remove the affected entry and make a copy so we can modify it.
List<ListenerInfo> infos = copy.remove(bc);
if (infos != null)
@@ -955,11 +935,11 @@
}
private static Map<BundleContext, List<ListenerInfo>> removeListenerInfos(
- Map<BundleContext, List<ListenerInfo>> listeners, BundleContext bc)
+ Map<BundleContext, List<ListenerInfo>> listeners, BundleContext bc)
{
// Make a copy of the map, since we will be mutating it.
Map<BundleContext, List<ListenerInfo>> copy =
- new HashMap<BundleContext, List<ListenerInfo>>(listeners);
+ new HashMap<BundleContext, List<ListenerInfo>>(listeners);
// Remove the affected entry and return the copy.
copy.remove(bc);
return copy;
@@ -967,11 +947,10 @@
/**
* This is the dispatching thread's main loop.
- *
*/
private static void run()
{
- Request req = null;
+ Request req;
while (true)
{
// Lock the request list so we can try to get a
@@ -1012,8 +991,8 @@
// the invoked method shields us from exceptions by
// catching Throwables when it invokes callbacks.
fireEventImmediately(
- req.m_dispatcher, req.m_type, req.m_listeners,
- req.m_event, null);
+ req.m_dispatcher, req.m_type, req.m_listeners,
+ req.m_event, null);
// Put dispatch request in cache.
synchronized (m_requestPool)
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ListenerHookInfoImpl.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ListenerHookInfoImpl.java
deleted file mode 100644
index 86dbffd..0000000
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ListenerHookInfoImpl.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.connect.felix.framework.util;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.hooks.service.ListenerHook;
-
-public class ListenerHookInfoImpl implements ListenerHook.ListenerInfo
-{
- private final BundleContext m_context;
- private final ServiceListener m_listener;
- private final String m_filter;
- private boolean m_removed;
-
- public ListenerHookInfoImpl(BundleContext context,
- ServiceListener listener, String filter, boolean removed)
- {
- m_context = context;
- m_listener = listener;
- m_filter = filter;
- m_removed = removed;
- }
-
- public BundleContext getBundleContext()
- {
- return m_context;
- }
-
- public String getFilter()
- {
- return m_filter;
- }
-
- public boolean isRemoved()
- {
- return m_removed;
- }
-
- public boolean equals(Object obj)
- {
- if (obj == this)
- {
- return true;
- }
-
- if (!(obj instanceof ListenerHookInfoImpl))
- {
- return false;
- }
-
- ListenerHookInfoImpl other = (ListenerHookInfoImpl) obj;
- return other.m_listener == m_listener
- && (m_filter == null ? other.m_filter == null : m_filter
- .equals(other.m_filter));
- }
-
- public int hashCode()
- {
- int rc = 17;
-
- rc = 37 * rc + m_listener.hashCode();
- if (m_filter != null)
- {
- rc = 37 * rc + m_filter.hashCode();
- }
- return rc;
- }
-}
\ No newline at end of file
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ListenerInfo.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ListenerInfo.java
index 3e5bb59..e0aa933 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ListenerInfo.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ListenerInfo.java
@@ -19,6 +19,7 @@
package org.apache.felix.connect.felix.framework.util;
import java.util.EventListener;
+
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
@@ -36,8 +37,8 @@
private final boolean m_removed;
public ListenerInfo(
- Bundle bundle, BundleContext context, Class listenerClass, EventListener listener,
- Filter filter, Object acc, boolean removed)
+ Bundle bundle, BundleContext context, Class listenerClass, EventListener listener,
+ Filter filter, Object acc, boolean removed)
{
// Technically, we could get the bundle from the bundle context, but
// there are some corner cases where the bundle context might become
@@ -121,10 +122,10 @@
ListenerInfo other = (ListenerInfo) obj;
return (other.m_bundle == m_bundle)
- && (other.m_context == m_context)
- && (other.m_listenerClass == m_listenerClass)
- && (other.m_listener == m_listener)
- && (m_filter == null ? other.m_filter == null : m_filter.equals(other.m_filter));
+ && (other.m_context == m_context)
+ && (other.m_listenerClass == m_listenerClass)
+ && (other.m_listener == m_listener)
+ && (m_filter == null ? other.m_filter == null : m_filter.equals(other.m_filter));
}
@Override
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/MapToDictionary.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/MapToDictionary.java
index a882def..bd33969 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/MapToDictionary.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/MapToDictionary.java
@@ -18,20 +18,23 @@
*/
package org.apache.felix.connect.felix.framework.util;
-import java.util.*;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Map;
/**
* This is a simple class that implements a <tt>Dictionary</tt> from a
* <tt>Map</tt>. The resulting dictionary is immutable.
- **/
-public class MapToDictionary extends Dictionary
+ */
+public class MapToDictionary<K, V> extends Dictionary<K, V>
{
/**
* Map source.
- **/
- private Map m_map = null;
+ */
+ private Map<K, V> m_map = null;
- public MapToDictionary(Map map)
+ public MapToDictionary(Map<K, V> map)
{
if (map == null)
{
@@ -40,12 +43,12 @@
m_map = map;
}
- public Enumeration elements()
+ public Enumeration<V> elements()
{
return Collections.enumeration(m_map.values());
}
- public Object get(Object key)
+ public V get(Object key)
{
return m_map.get(key);
}
@@ -55,17 +58,17 @@
return m_map.isEmpty();
}
- public Enumeration keys()
+ public Enumeration<K> keys()
{
return Collections.enumeration(m_map.keySet());
}
- public Object put(Object key, Object value)
+ public V put(K key, V value)
{
throw new UnsupportedOperationException();
}
- public Object remove(Object key)
+ public V remove(Object key)
{
throw new UnsupportedOperationException();
}
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableCollection.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableCollection.java
index cc62168..04ae94c 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableCollection.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableCollection.java
@@ -18,13 +18,14 @@
*/
package org.apache.felix.connect.felix.framework.util;
+import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Iterator;
/**
* A collection wrapper that only permits clients to shrink the collection.
-**/
-public class ShrinkableCollection<T> implements Collection<T>
+ */
+public class ShrinkableCollection<T> extends AbstractCollection<T>
{
private final Collection<T> m_delegate;
@@ -33,80 +34,16 @@
m_delegate = delegate;
}
- public boolean add(T o)
- {
- throw new UnsupportedOperationException();
- }
-
- public boolean addAll(Collection<? extends T> c)
- {
- throw new UnsupportedOperationException();
- }
-
- public void clear()
- {
- m_delegate.clear();
- }
-
- public boolean contains(Object o)
- {
- return m_delegate.contains(o);
- }
-
- public boolean containsAll(Collection<?> c)
- {
- return m_delegate.containsAll(c);
- }
-
@Override
- public boolean equals(Object o)
- {
- return m_delegate.equals(o);
- }
-
- @Override
- public int hashCode()
- {
- return m_delegate.hashCode();
- }
-
- public boolean isEmpty()
- {
- return m_delegate.isEmpty();
- }
-
- public Iterator iterator()
+ public Iterator<T> iterator()
{
return m_delegate.iterator();
}
- public boolean remove(Object o)
- {
- return m_delegate.remove(o);
- }
-
- public boolean removeAll(Collection<?> c)
- {
- return m_delegate.removeAll(c);
- }
-
- public boolean retainAll(Collection<?> c)
- {
- return m_delegate.retainAll(c);
- }
-
+ @Override
public int size()
{
return m_delegate.size();
}
- public Object[] toArray()
- {
- return m_delegate.toArray();
- }
-
- public <A> A[] toArray(A[] a)
- {
- return m_delegate.toArray(a);
- }
}
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableList.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableList.java
new file mode 100644
index 0000000..6f4aed7
--- /dev/null
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableList.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.connect.felix.framework.util;
+
+import java.util.AbstractList;
+import java.util.List;
+
+/**
+ * A collection wrapper that only permits clients to shrink the collection.
+ */
+public class ShrinkableList<T> extends AbstractList<T>
+{
+ private final List<T> m_delegate;
+
+ public ShrinkableList(List<T> delegate)
+ {
+ m_delegate = delegate;
+ }
+
+ @Override
+ public T get(int index)
+ {
+ return m_delegate.get(index);
+ }
+
+ @Override
+ public int size()
+ {
+ return m_delegate.size();
+ }
+
+ @Override
+ public T remove(int index)
+ {
+ return m_delegate.remove(index);
+ }
+
+}
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableMap.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableMap.java
index 7235bde..dbaac0b 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableMap.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/ShrinkableMap.java
@@ -18,11 +18,11 @@
*/
package org.apache.felix.connect.felix.framework.util;
-import java.util.Collection;
+import java.util.AbstractMap;
import java.util.Map;
import java.util.Set;
-public class ShrinkableMap<K, V> implements Map<K, V>
+public class ShrinkableMap<K, V> extends AbstractMap<K, V>
{
private final Map<K, V> m_delegate;
@@ -31,63 +31,10 @@
m_delegate = delegate;
}
- public int size()
- {
- return m_delegate.size();
- }
-
- public boolean isEmpty()
- {
- return m_delegate.isEmpty();
- }
-
- public boolean containsKey(Object o)
- {
- return m_delegate.containsKey(o);
- }
-
- public boolean containsValue(Object o)
- {
- return m_delegate.containsValue(o);
- }
-
- public V get(Object o)
- {
- return m_delegate.get(o);
- }
-
- public V put(K k, V v)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public V remove(Object o)
- {
- return m_delegate.remove(o);
- }
-
- public void putAll(Map<? extends K, ? extends V> map)
- {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void clear()
- {
- m_delegate.clear();
- }
-
- public Set<K> keySet()
- {
- return m_delegate.keySet();
- }
-
- public Collection<V> values()
- {
- return m_delegate.values();
- }
-
+ @Override
public Set<Entry<K, V>> entrySet()
{
return m_delegate.entrySet();
}
+
}
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/StringComparator.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/StringComparator.java
index 25030b7..2a34eda 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/StringComparator.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/StringComparator.java
@@ -20,7 +20,7 @@
import java.util.Comparator;
-public class StringComparator implements Comparator
+public class StringComparator implements Comparator<String>
{
private final boolean m_isCaseSensitive;
@@ -29,15 +29,16 @@
m_isCaseSensitive = b;
}
- public int compare(Object o1, Object o2)
+ @Override
+ public int compare(String o1, String o2)
{
if (m_isCaseSensitive)
{
- return o1.toString().compareTo(o2.toString());
+ return o1.compareTo(o2);
}
else
{
- return o1.toString().compareToIgnoreCase(o2.toString());
+ return o1.compareToIgnoreCase(o2);
}
}
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/StringMap.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/StringMap.java
index 09709ea..f472782 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/StringMap.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/StringMap.java
@@ -18,7 +18,10 @@
*/
package org.apache.felix.connect.felix.framework.util;
-import java.util.*;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
/**
* Simple utility class that creates a map for string-based keys. This map can
@@ -26,10 +29,10 @@
* for the key. Any keys put into this map will be converted to a
* <tt>String</tt> using the <tt>toString()</tt> method, since it is only
* intended to compare strings.
- **/
-public class StringMap implements Map
+ */
+public class StringMap<T> implements Map<String, T>
{
- private TreeMap m_map;
+ private TreeMap<String, T> m_map;
public StringMap()
{
@@ -38,10 +41,10 @@
public StringMap(boolean caseSensitive)
{
- m_map = new TreeMap(new StringComparator(caseSensitive));
+ m_map = new TreeMap<String, T>(new StringComparator(caseSensitive));
}
- public StringMap(Map map, boolean caseSensitive)
+ public StringMap(Map<? extends String, ? extends T> map, boolean caseSensitive)
{
this(caseSensitive);
putAll(map);
@@ -56,72 +59,83 @@
{
if (isCaseSensitive() != b)
{
- TreeMap map = new TreeMap(new StringComparator(b));
+ TreeMap<String, T> map = new TreeMap<String, T>(new StringComparator(b));
map.putAll(m_map);
m_map = map;
}
}
+ @Override
public int size()
{
return m_map.size();
}
+ @Override
public boolean isEmpty()
{
return m_map.isEmpty();
}
+ @Override
public boolean containsKey(Object arg0)
{
return m_map.containsKey(arg0);
}
+ @Override
public boolean containsValue(Object arg0)
{
return m_map.containsValue(arg0);
}
- public Object get(Object arg0)
+ @Override
+ public T get(Object arg0)
{
return m_map.get(arg0);
}
- public Object put(Object key, Object value)
+ @Override
+ public T put(String key, T value)
{
- return m_map.put(key.toString(), value);
+ return m_map.put(key, value);
}
- public void putAll(Map map)
+ @Override
+ public void putAll(Map<? extends String, ? extends T> map)
{
- for (Iterator it = map.entrySet().iterator(); it.hasNext();)
+ for (Entry<? extends String, ? extends T> entry : map.entrySet())
{
- Map.Entry entry = (Map.Entry) it.next();
put(entry.getKey(), entry.getValue());
}
}
- public Object remove(Object arg0)
+ @Override
+ public T remove(Object arg0)
{
return m_map.remove(arg0);
}
+ @Override
public void clear()
{
m_map.clear();
}
- public Set keySet()
+ @Override
+ public Set<String> keySet()
{
return m_map.keySet();
}
- public Collection values()
+ @Override
+ public Collection<T> values()
{
return m_map.values();
}
- public Set entrySet()
+ @Override
+ public Set<Entry<String, T>> entrySet()
{
return m_map.entrySet();
}
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/Util.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/Util.java
index 1bebffa..565287e 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/Util.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/Util.java
@@ -36,7 +36,7 @@
{
/**
* The default name used for the default configuration properties file.
- **/
+ */
private static final String DEFAULT_PROPERTIES_FILE = "default.properties";
public static String getDefaultProperty(String name)
@@ -66,7 +66,9 @@
try
{
if (is != null)
+ {
is.close();
+ }
}
catch (IOException ex2)
{
@@ -83,7 +85,7 @@
* Converts a module identifier to a bundle identifier. Module IDs are
* typically <tt><bundle-id>.<revision></tt>; this method
* returns only the portion corresponding to the bundle ID.
- **/
+ */
public static long getBundleIdFromModuleId(String id)
{
try
@@ -102,7 +104,7 @@
* Converts a module identifier to a bundle identifier. Module IDs are
* typically <tt><bundle-id>.<revision></tt>; this method
* returns only the portion corresponding to the revision.
- **/
+ */
public static int getModuleRevisionFromModuleId(String id)
{
try
@@ -196,13 +198,11 @@
* from the service object's class loader, but from the class loaders of any
* interfaces it implements and the class loaders of all super classes.
* </p>
- *
- * @param svcObj
- * the class that is the root of the search.
- * @param name
- * the name of the class to load.
+ *
+ * @param svcObj the class that is the root of the search.
+ * @param name the name of the class to load.
* @return the loaded class or <tt>null</tt> if it could not be loaded.
- **/
+ */
public static Class loadClassUsingClass(Class clazz, String name)
{
Class loadedClass = null;
@@ -248,16 +248,14 @@
* This method determines if the requesting bundle is able to cast the
* specified service reference based on class visibility rules of the
* underlying modules.
- *
- * @param requester
- * The bundle requesting the service.
- * @param ref
- * The service in question.
+ *
+ * @param requester The bundle requesting the service.
+ * @param ref The service in question.
* @return <tt>true</tt> if the requesting bundle is able to case the
- * service object to a known type.
- **/
+ * service object to a known type.
+ */
public static boolean isServiceAssignable(Bundle requester,
- ServiceReference ref)
+ ServiceReference ref)
{
// Boolean flag.
boolean allow = true;
@@ -280,22 +278,22 @@
return allow;
}
- private static final byte encTab[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
+ private static final byte encTab[] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x2b, 0x2f };
+ 0x39, 0x2b, 0x2f};
- private static final byte decTab[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ private static final byte decTab[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 };
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1};
public static String base64Encode(String s) throws IOException
{
@@ -304,12 +302,10 @@
/**
* Encode a raw byte array to a Base64 String.
- *
- * @param in
- * Byte array to encode.
- * @param len
- * Length of Base64 lines. 0 means no line breaks.
- **/
+ *
+ * @param in Byte array to encode.
+ * @param len Length of Base64 lines. 0 means no line breaks.
+ */
public static String encode(byte[] in, int len) throws IOException
{
ByteArrayOutputStream baos = null;
@@ -409,23 +405,18 @@
* as nested variable placeholders, which are substituted from inner most to
* outer most. Configuration properties override system properties.
* </p>
- *
- * @param val
- * The string on which to perform property substitution.
- * @param currentKey
- * The key of the property being evaluated used to detect cycles.
- * @param cycleMap
- * Map of variable references used to detect nested cycles.
- * @param configProps
- * Set of configuration properties.
+ *
+ * @param val The string on which to perform property substitution.
+ * @param currentKey The key of the property being evaluated used to detect cycles.
+ * @param cycleMap Map of variable references used to detect nested cycles.
+ * @param configProps Set of configuration properties.
* @return The value of the specified string after system property
- * substitution.
- * @throws IllegalArgumentException
- * If there was a syntax error in the property placeholder
- * syntax or a recursive variable reference.
- **/
+ * substitution.
+ * @throws IllegalArgumentException If there was a syntax error in the property placeholder
+ * syntax or a recursive variable reference.
+ */
public static String substVars(String val, String currentKey, Map cycleMap,
- Properties configProps) throws IllegalArgumentException
+ Properties configProps) throws IllegalArgumentException
{
// If there is currently no cycle map, then create
// one for detecting cycles for this invocation.
diff --git a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/VersionRange.java b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/VersionRange.java
index a13b0a7..7971840 100644
--- a/connect/src/main/java/org/apache/felix/connect/felix/framework/util/VersionRange.java
+++ b/connect/src/main/java/org/apache/felix/connect/felix/framework/util/VersionRange.java
@@ -30,7 +30,7 @@
Version.emptyVersion, true, null, true);
public VersionRange(Version low, boolean isLowInclusive, Version high,
- boolean isHighInclusive)
+ boolean isHighInclusive)
{
m_floor = low;
m_isFloorInclusive = isLowInclusive;
diff --git a/connect/src/main/java/org/apache/felix/connect/launch/BundleDescriptor.java b/connect/src/main/java/org/apache/felix/connect/launch/BundleDescriptor.java
index 68b849e..0a2b1cc 100644
--- a/connect/src/main/java/org/apache/felix/connect/launch/BundleDescriptor.java
+++ b/connect/src/main/java/org/apache/felix/connect/launch/BundleDescriptor.java
@@ -18,21 +18,34 @@
*/
package org.apache.felix.connect.launch;
-import java.net.URL;
import java.util.Map;
+import org.apache.felix.connect.Revision;
+
public class BundleDescriptor
{
private final ClassLoader m_loader;
- private final URL m_url;
+ private final String m_url;
private final Map<String, String> m_headers;
+ private final Revision m_revision;
+ private final Map<Class, Object> m_services;
- public BundleDescriptor(ClassLoader loader, URL url,
- Map<String, String> headers)
+ public BundleDescriptor(ClassLoader loader, String url,
+ Map<String, String> headers)
+ {
+ this(loader, url, headers, null, null);
+ }
+
+ public BundleDescriptor(ClassLoader loader, String url,
+ Map<String, String> headers,
+ Revision revision,
+ Map<Class, Object> services)
{
m_loader = loader;
m_url = url;
m_headers = headers;
+ m_revision = revision;
+ m_services = services;
}
public ClassLoader getClassLoader()
@@ -40,18 +53,28 @@
return m_loader;
}
- public URL getUrl()
+ public String getUrl()
{
return m_url;
}
public String toString()
{
- return m_url.toExternalForm();
+ return m_url;
}
public Map<String, String> getHeaders()
{
return m_headers;
}
+
+ public Revision getRevision()
+ {
+ return m_revision;
+ }
+
+ public Map<Class, Object> getServices()
+ {
+ return m_services;
+ }
}
diff --git a/connect/src/main/java/org/apache/felix/connect/launch/ClasspathScanner.java b/connect/src/main/java/org/apache/felix/connect/launch/ClasspathScanner.java
index e1f794e..da19f9f 100644
--- a/connect/src/main/java/org/apache/felix/connect/launch/ClasspathScanner.java
+++ b/connect/src/main/java/org/apache/felix/connect/launch/ClasspathScanner.java
@@ -50,7 +50,7 @@
}
public List<BundleDescriptor> scanForBundles(String filterString, ClassLoader loader)
- throws Exception
+ throws Exception
{
Filter filter = (filterString != null) ? FrameworkUtil
.createFilter(filterString) : null;
@@ -58,105 +58,106 @@
loader = (loader != null) ? loader : getClass().getClassLoader();
List<BundleDescriptor> bundles = new ArrayList<BundleDescriptor>();
- byte[] bytes = new byte[1024 * 1024 * 2];
+ byte[] bytes = new byte[1024 * 1024 * 2];
for (Enumeration<URL> e = loader.getResources(
- "META-INF/MANIFEST.MF"); e.hasMoreElements();)
+ "META-INF/MANIFEST.MF"); e.hasMoreElements(); )
{
URL manifestURL = e.nextElement();
InputStream input = null;
try
{
input = manifestURL.openStream();
- int size = 0;
- for (int i = input.read(bytes); i != -1; i = input.read(bytes, size, bytes.length - size)) {
- size += i;
- if (size == bytes.length) {
- byte[] tmp = new byte[size * 2];
- System.arraycopy(bytes, 0, tmp, 0, bytes.length);
- bytes = tmp;
- }
- }
+ int size = 0;
+ for (int i = input.read(bytes); i != -1; i = input.read(bytes, size, bytes.length - size))
+ {
+ size += i;
+ if (size == bytes.length)
+ {
+ byte[] tmp = new byte[size * 2];
+ System.arraycopy(bytes, 0, tmp, 0, bytes.length);
+ bytes = tmp;
+ }
+ }
- // Now parse the main attributes. The idea is to do that
- // without creating new byte arrays. Therefore, we read through
- // the manifest bytes inside the bytes array and write them back into
- // the same array unless we don't need them (e.g., \r\n and \n are skipped).
- // That allows us to create the strings from the bytes array without the skipped
- // chars. We stopp as soon as we see a blankline as that denotes that the main
- //attributes part is finished.
- String key = null;
- int last = 0;
- int current = 0;
+ // Now parse the main attributes. The idea is to do that
+ // without creating new byte arrays. Therefore, we read through
+ // the manifest bytes inside the bytes array and write them back into
+ // the same array unless we don't need them (e.g., \r\n and \n are skipped).
+ // That allows us to create the strings from the bytes array without the skipped
+ // chars. We stopp as soon as we see a blankline as that denotes that the main
+ //attributes part is finished.
+ String key = null;
+ int last = 0;
+ int current = 0;
Map<String, String> headers = new HashMap<String, String>();
- for (int i = 0; i < size; i++)
- {
- // skip \r and \n if it is follows by another \n
- // (we catch the blank line case in the next iteration)
- if (bytes[i] == '\r')
- {
- if ((i + 1 < size) && (bytes[i + 1] == '\n'))
- {
- continue;
- }
- }
- if (bytes[i] == '\n')
- {
- if ((i + 1 < size) && (bytes[i + 1] == ' '))
- {
- i++;
- continue;
- }
- }
- // If we don't have a key yet and see the first : we parse it as the key
- // and skip the :<blank> that follows it.
- if ((key == null) && (bytes[i] == ':'))
- {
- key = new String(bytes, last, (current - last), "UTF-8");
- if ((i + 1 < size) && (bytes[i + 1] == ' '))
- {
- last = current + 1;
- continue;
- }
- else
- {
- throw new Exception(
- "Manifest error: Missing space separator - " + key);
- }
- }
- // if we are at the end of a line
- if (bytes[i] == '\n')
- {
- // and it is a blank line stop parsing (main attributes are done)
- if ((last == current) && (key == null))
- {
- break;
- }
- // Otherwise, parse the value and add it to the map (we throw an
- // exception if we don't have a key or the key already exist.
- String value = new String(bytes, last, (current - last), "UTF-8");
- if (key == null)
- {
- throw new Exception("Manifst error: Missing attribute name - " + value);
- }
- else if (headers.put(key, value) != null)
- {
- throw new Exception("Manifst error: Duplicate attribute name - " + key);
- }
- last = current;
- key = null;
- }
- else
- {
- // write back the byte if it needs to be included in the key or the value.
- bytes[current++] = bytes[i];
- }
- }
- if ((filter == null)
- || filter.match(new MapToDictionary(headers)))
+ for (int i = 0; i < size; i++)
{
- bundles.add(new BundleDescriptor(loader, getParentURL(manifestURL),
- headers));
+ // skip \r and \n if it is follows by another \n
+ // (we catch the blank line case in the next iteration)
+ if (bytes[i] == '\r')
+ {
+ if ((i + 1 < size) && (bytes[i + 1] == '\n'))
+ {
+ continue;
+ }
+ }
+ if (bytes[i] == '\n')
+ {
+ if ((i + 1 < size) && (bytes[i + 1] == ' '))
+ {
+ i++;
+ continue;
+ }
+ }
+ // If we don't have a key yet and see the first : we parse it as the key
+ // and skip the :<blank> that follows it.
+ if ((key == null) && (bytes[i] == ':'))
+ {
+ key = new String(bytes, last, (current - last), "UTF-8");
+ if ((i + 1 < size) && (bytes[i + 1] == ' '))
+ {
+ last = current + 1;
+ continue;
+ }
+ else
+ {
+ throw new Exception(
+ "Manifest error: Missing space separator - " + key);
+ }
+ }
+ // if we are at the end of a line
+ if (bytes[i] == '\n')
+ {
+ // and it is a blank line stop parsing (main attributes are done)
+ if ((last == current) && (key == null))
+ {
+ break;
+ }
+ // Otherwise, parse the value and add it to the map (we throw an
+ // exception if we don't have a key or the key already exist.
+ String value = new String(bytes, last, (current - last), "UTF-8");
+ if (key == null)
+ {
+ throw new Exception("Manifst error: Missing attribute name - " + value);
+ }
+ else if (headers.put(key, value) != null)
+ {
+ throw new Exception("Manifst error: Duplicate attribute name - " + key);
+ }
+ last = current;
+ key = null;
+ }
+ else
+ {
+ // write back the byte if it needs to be included in the key or the value.
+ bytes[current++] = bytes[i];
+ }
+ }
+ if ((filter == null)
+ || filter.match(new MapToDictionary<String, String>(headers)))
+ {
+ bundles.add(new BundleDescriptor(loader, getParentURL(manifestURL).toExternalForm(), headers));
}
}
finally
diff --git a/connect/src/main/java/org/apache/felix/connect/launch/PojoServiceRegistry.java b/connect/src/main/java/org/apache/felix/connect/launch/PojoServiceRegistry.java
index 2da7807..a63421b 100644
--- a/connect/src/main/java/org/apache/felix/connect/launch/PojoServiceRegistry.java
+++ b/connect/src/main/java/org/apache/felix/connect/launch/PojoServiceRegistry.java
@@ -18,8 +18,9 @@
*/
package org.apache.felix.connect.launch;
+import java.util.Collection;
import java.util.Dictionary;
-import java.util.List;
+
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceListener;
@@ -29,28 +30,24 @@
public interface PojoServiceRegistry
{
public BundleContext getBundleContext();
-
- public void startBundles(List<BundleDescriptor> bundles) throws Exception;
- public void addServiceListener(ServiceListener listener, String filter)
- throws InvalidSyntaxException;
+ public void startBundles(Collection<BundleDescriptor> bundles) throws Exception;
+
+ public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException;
public void addServiceListener(ServiceListener listener);
public void removeServiceListener(ServiceListener listener);
- public ServiceRegistration registerService(String[] clazzes,
- Object service, @SuppressWarnings("rawtypes") Dictionary properties);
+ public ServiceRegistration<?> registerService(String[] clazzes, Object service, Dictionary<String, ?> properties);
- public ServiceRegistration registerService(String clazz, Object service,
- @SuppressWarnings("rawtypes") Dictionary properties);
+ public ServiceRegistration<?> registerService(String clazz, Object service, Dictionary<String, ?> properties);
- public ServiceReference[] getServiceReferences(String clazz, String filter)
- throws InvalidSyntaxException;
+ public ServiceReference<?>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
- public ServiceReference getServiceReference(String clazz);
+ public ServiceReference<?> getServiceReference(String clazz);
- public Object getService(ServiceReference reference);
+ public <S> S getService(ServiceReference<S> reference);
- public boolean ungetService(ServiceReference reference);
+ public boolean ungetService(ServiceReference<?> reference);
}
diff --git a/connect/src/main/java/org/apache/felix/connect/launch/PojoServiceRegistryFactory.java b/connect/src/main/java/org/apache/felix/connect/launch/PojoServiceRegistryFactory.java
index 1084486..2ce9523 100644
--- a/connect/src/main/java/org/apache/felix/connect/launch/PojoServiceRegistryFactory.java
+++ b/connect/src/main/java/org/apache/felix/connect/launch/PojoServiceRegistryFactory.java
@@ -20,11 +20,10 @@
import java.util.Map;
-public interface PojoServiceRegistryFactory
+public interface PojoServiceRegistryFactory
{
- public static final String BUNDLE_DESCRIPTORS = PojoServiceRegistry.class
- .getName().toLowerCase() + ".bundles";
+ public static final String BUNDLE_DESCRIPTORS =
+ PojoServiceRegistry.class.getName().toLowerCase() + ".bundles";
- public PojoServiceRegistry newPojoServiceRegistry(Map configuration)
- throws Exception;
+ public PojoServiceRegistry newPojoServiceRegistry(Map<String, Object> configuration) throws Exception;
}