Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjfogell2005-12-15 19:59:24 +0000
committerjfogell2005-12-15 19:59:24 +0000
commitdc520ec816e6ef38fd464ae9de307c2e2f9e534d (patch)
tree413caa4c34d2d45f143a978a7fde14ba1cc71c9d
parent2dd01c470ad3807cada22a62d9b3362345946398 (diff)
downloadrt.equinox.bundles-dc520ec816e6ef38fd464ae9de307c2e2f9e534d.tar.gz
rt.equinox.bundles-dc520ec816e6ef38fd464ae9de307c2e2f9e534d.tar.xz
rt.equinox.bundles-dc520ec816e6ef38fd464ae9de307c2e2f9e534d.zip
initial checkin for OSGi Device Access service
-rw-r--r--bundles/org.eclipse.equinox.device/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.device/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.device/.project28
-rw-r--r--bundles/org.eclipse.equinox.device/META-INF/MANIFEST.MF15
-rw-r--r--bundles/org.eclipse.equinox.device/about.html22
-rw-r--r--bundles/org.eclipse.equinox.device/build.properties16
-rw-r--r--bundles/org.eclipse.equinox.device/plugin.properties13
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/Activator.java420
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DeviceMsg.java43
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DeviceTracker.java341
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverLocatorTracker.java344
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverSelectorTracker.java150
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverTracker.java485
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/ExternalMessages.properties37
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/LogTracker.java150
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/LogTrackerMsg.java27
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/Match.java36
-rw-r--r--bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/SecureAction.java53
18 files changed, 2188 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.device/.classpath b/bundles/org.eclipse.equinox.device/.classpath
new file mode 100644
index 000000000..065ac06e1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.device/.cvsignore b/bundles/org.eclipse.equinox.device/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.device/.project b/bundles/org.eclipse.equinox.device/.project
new file mode 100644
index 000000000..5d5c43191
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.device</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.device/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.device/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..4069367db
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Bundle-ManifestVersion: 2
+Bundle-Name: %bundleName
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.equinox.device.Activator
+Bundle-SymbolicName: org.eclipse.equinox.device
+Bundle-Vendor: %bundleVendor
+Bundle-Copyright: %bundleCopyright
+Bundle-Localization: plugin
+Import-Service: org.osgi.service.log.LogService
+Import-Package: org.osgi.framework;version="1.2",
+ org.osgi.service.device,
+ org.osgi.service.log;version="1.2",
+ org.osgi.util.tracker
+Export-Package: org.eclipse.equinox.device; x-internal:=true
+Eclipse-LazyStart: true
diff --git a/bundles/org.eclipse.equinox.device/about.html b/bundles/org.eclipse.equinox.device/about.html
new file mode 100644
index 000000000..b2f1e6bad
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/about.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
+<!-- saved from url=(0043)http://www.eclipse.org/legal/epl/about.html -->
+<HTML><HEAD><TITLE>About</TITLE>
+<META http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+<META content="MSHTML 6.00.2800.1498" name=GENERATOR></HEAD>
+<BODY lang=EN-US>
+<H2>About This Content</H2>
+<P>February 24, 2005</P>
+<H3>License</H3>
+<P>The Eclipse Foundation makes available all content in this plug-in
+("Content"). Unless otherwise indicated below, the Content is provided to you
+under the terms and conditions of the Eclipse Public License Version 1.0
+("EPL"). A copy of the EPL is available at <A
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</A>.
+For purposes of the EPL, "Program" will mean the Content.</P>
+<P>If you did not receive this Content directly from the Eclipse Foundation, the
+Content is being redistributed by another party ("Redistributor") and different
+terms and conditions may apply to your use of any object code in the Content.
+Check the Redistributor's license that was provided with the Content. If no such
+license exists, contact the Redistributor. Unless otherwise indicated below, the
+terms and conditions of the EPL still apply to any source code in the
+Content.</P></BODY></HTML>
diff --git a/bundles/org.eclipse.equinox.device/build.properties b/bundles/org.eclipse.equinox.device/build.properties
new file mode 100644
index 000000000..662d65185
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2005 IBM Corporation.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = META-INF/,\
+ plugin*.properties,\
+ about.html,\
+ .
+jars.compile.order = .
+source.. =
diff --git a/bundles/org.eclipse.equinox.device/plugin.properties b/bundles/org.eclipse.equinox.device/plugin.properties
new file mode 100644
index 000000000..86742fd77
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2005 IBM Corporation.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+bundleVendor = Eclipse.org
+bundleName = Device Access Service
+bundleCopyright = Copyright (c) IBM Corp. 1999, 2005
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/Activator.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/Activator.java
new file mode 100644
index 000000000..847408936
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/Activator.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * DeviceManager bundle. This bundle implements the OSGi Device Access 1.1
+ * specification.
+ *
+ * This implementation does not include the optimizations in section
+ * 8.7.4 of the OSGi SP R2 spec.
+ *
+ */
+public class Activator implements BundleActivator, ServiceTrackerCustomizer, FrameworkListener, Runnable {
+ protected final static boolean DEBUG = false;
+
+ /** DeviceManager BundleContext */
+ protected BundleContext context;
+
+ /** LogTracker object */
+ protected LogTracker log;
+
+ /** if false the thread must terminate */
+ protected volatile boolean running;
+
+ /** DeviceManager thread */
+ protected Thread thread;
+
+ /** DriverTracker for Driver services. */
+ protected DriverTracker drivers;
+
+ /** Tracker for DriverLocator services */
+ protected DriverLocatorTracker locators;
+
+ /** Tracker for DriverSelector services */
+ protected DriverSelectorTracker selectors;
+
+ /** ServiceTracker object for device services */
+ protected ServiceTracker devices;
+
+ /** filter for Device services */
+ protected Filter deviceFilter;
+
+ /** filter for Driver services */
+ protected Filter driverFilter;
+
+ /**
+ * Linked List item
+ */
+ static class DeviceService {
+ /** object for this item */
+ final DeviceTracker device;
+ /** next item in event queue */
+ DeviceService next;
+
+ /**
+ * Constructor for work queue item
+ *
+ * @param o Object for this event
+ */
+ DeviceService(DeviceTracker device) {
+ this.device = device;
+ next = null;
+ }
+ }
+
+ /** item at the head of the event queue */
+ private DeviceService head;
+ /** item at the tail of the event queue */
+ private DeviceService tail;
+
+ /** number of milliseconds to wait before refining idle Device services */
+ protected long updatewait;
+
+ /** set to true by DriverTracker when a Driver Service is registered */
+ protected volatile boolean driverServiceRegistered;
+
+ /**
+ * Create a DeviceManager object.
+ *
+ */
+
+ public Activator() {
+ super();
+ }
+
+ /**
+ * Start the Device Manager.
+ *
+ * @param context The device manager's bundle context
+ */
+
+ public void start(BundleContext context) throws Exception {
+ this.context = context;
+ running = false;
+
+ log = new LogTracker(context, System.err);
+
+ try {
+ deviceFilter = context.createFilter("(|(" + org.osgi.framework.Constants.OBJECTCLASS + "=" + DeviceTracker.clazz + ////-1$ ////-2$ //$NON-NLS-1$ //$NON-NLS-2$
+ ")(" + org.osgi.service.device.Constants.DEVICE_CATEGORY + "=*))"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ driverFilter = context.createFilter("(" + org.osgi.framework.Constants.OBJECTCLASS + "=" + DriverTracker.clazz + ")"); ////-1$ ////-2$ ////-3$ //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ } catch (InvalidSyntaxException e) {
+ log.log(log.LOG_ERROR, NLS.bind(DeviceMsg.Unable_to_create_Filter_for_DeviceManager, e)); ////-1$
+ throw e;
+ }
+
+ updatewait = 5 * 1000L;
+
+ String prop = context.getProperty("com.ibm.osg.service.device.updatewait"); //$NON-NLS-1$
+
+ if (prop != null) {
+ try {
+ updatewait = Long.parseLong(prop) * 1000L;
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ Bundle systemBundle = context.getBundle(0);
+
+ if ((systemBundle != null) && ((systemBundle.getState() & systemBundle.STARTING) != 0)) { /* if the system bundle is starting */
+ context.addFrameworkListener(this);
+ } else {
+ startDeviceManager();
+ }
+
+ log.log(log.LOG_INFO, DeviceMsg.DeviceManager_started);
+ }
+
+ /**
+ * Receive notification of a general framework event.
+ *
+ * @param event The FrameworkEvent.
+ */
+ public void frameworkEvent(FrameworkEvent event) {
+ switch (event.getType()) {
+ case FrameworkEvent.STARTED : {
+ context.removeFrameworkListener(this);
+
+ try {
+ startDeviceManager();
+ } catch (Throwable t) {
+ log.log(log.LOG_ERROR, NLS.bind(DeviceMsg.DeviceManager_has_thrown_an_error, t)); ////-1$
+ }
+
+ break;
+ }
+ }
+ }
+
+ /**
+ * Start the DeviceManager thread.
+ *
+ */
+ public void startDeviceManager() {
+ if (!running) {
+ head = null;
+ tail = null;
+
+ locators = new DriverLocatorTracker(this);
+
+ selectors = new DriverSelectorTracker(this);
+
+ drivers = new DriverTracker(this);
+
+ devices = new ServiceTracker(context, deviceFilter, this);
+ devices.open();
+
+ running = true;
+ driverServiceRegistered = false;
+
+ thread = (new SecureAction()).createThread(this, "DeviceManager"); //$NON-NLS-1$
+ thread.start(); /* Start DeviceManager thread */
+ }
+ }
+
+ /**
+ * Stop the Device Manager bundle.
+ *
+ * @param context The device manager's bundle context
+ */
+
+ public void stop(BundleContext context) throws Exception {
+ context.removeFrameworkListener(this);
+
+ if (running) {
+ Thread t = thread;
+
+ running = false; /* request thread to stop */
+
+ if (t != null) {
+ t.interrupt();
+
+ synchronized (t) {
+ while (t.isAlive()) /* wait for thread to complete */
+ {
+ try {
+ t.wait(0);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+ }
+
+ if (drivers != null) {
+ drivers.close();
+ drivers = null;
+ }
+
+ if (devices != null) {
+ devices.close();
+ devices = null;
+ }
+
+ if (locators != null) {
+ locators.close();
+ locators = null;
+ }
+
+ if (selectors != null) {
+ selectors.close();
+ selectors = null;
+ }
+
+ if (log != null) {
+ log.close();
+ log = null;
+ }
+
+ this.context = null;
+ }
+
+ /**
+ * A service is being added to the ServiceTracker.
+ *
+ * <p>This method is called before a service which matched
+ * the search parameters of the ServiceTracker is
+ * added to the ServiceTracker. This method should return the
+ * service object to be tracked for this ServiceReference.
+ * The returned service object is stored in the ServiceTracker
+ * and is available from the getService and getServices
+ * methods.
+ *
+ * @param reference Reference to service being added to the ServiceTracker.
+ * @return The service object to be tracked for the
+ * ServiceReference or <tt>null</tt> if the ServiceReference should not
+ * be tracked.
+ */
+ public Object addingService(ServiceReference reference) {
+ if (Activator.DEBUG) {
+ log.log(reference, log.LOG_DEBUG, "DeviceManager device service registered"); //$NON-NLS-1$
+ }
+
+ enqueue(new DeviceTracker(this, reference));
+
+ return (reference);
+ }
+
+ /**
+ * A service tracked by the ServiceTracker has been modified.
+ *
+ * <p>This method is called when a service being tracked
+ * by the ServiceTracker has had it properties modified.
+ *
+ * @param reference Reference to service that has been modified.
+ * @param service The service object for the modified service.
+ */
+ public void modifiedService(ServiceReference reference, Object service) {
+ }
+
+ /**
+ * A service tracked by the ServiceTracker is being removed.
+ *
+ * <p>This method is called after a service is no longer being tracked
+ * by the ServiceTracker.
+ *
+ * @param reference Reference to service that has been removed.
+ * @param service The service object for the removed service.
+ */
+ public void removedService(ServiceReference reference, Object object) {
+ if (Activator.DEBUG) {
+ log.log(reference, log.LOG_DEBUG, "DeviceManager device service unregistered"); //$NON-NLS-1$
+ }
+
+ /* We do not implement optional driver reclamation.
+ * Thus we take no specific action upon Device service unregistration .
+ */
+ }
+
+ public void refineIdleDevices() {
+ if (Activator.DEBUG) {
+ log.log(log.LOG_DEBUG, "DeviceManager refining idle device services"); //$NON-NLS-1$
+ }
+
+ ServiceReference[] references = devices.getServiceReferences();
+
+ if (references != null) {
+ int size = references.length;
+
+ for (int i = 0; i < size; i++) {
+ ServiceReference device = references[i];
+
+ enqueue(new DeviceTracker(this, device));
+ }
+ }
+ }
+
+ /**
+ * Main thread for DeviceManager.
+ *
+ * Attempt to refine all Device services that are not in use
+ * by a driver bundle.
+ */
+ public void run() {
+ while (running) {
+ DeviceTracker device;
+
+ try {
+ device = dequeue();
+ } catch (InterruptedException e) {
+ continue;
+ }
+
+ try {
+ device.refine();
+ } catch (Throwable t) {
+ log.log(log.LOG_ERROR, NLS.bind(DeviceMsg.DeviceManager_has_thrown_an_error, t)); ////-1$
+ }
+ }
+ }
+
+ /**
+ * Queue the object to be processed on the work thread.
+ * The thread is notified.
+ *
+ * @param device Work item.
+ */
+ public synchronized void enqueue(DeviceTracker device) {
+ if (device != null) {
+ if (Activator.DEBUG) {
+ log.log(log.LOG_DEBUG, "DeviceManager queuing DeviceTracker"); //$NON-NLS-1$
+ }
+
+ DeviceService item = new DeviceService(device);
+
+ if (head == null) /* if the queue was empty */
+ {
+ head = item;
+ tail = item;
+ } else /* else add to end of queue */
+ {
+ tail.next = item;
+ tail = item;
+ }
+ }
+
+ notify();
+ }
+
+ /**
+ * Dequeue an object from the work thread.
+ * If the queue is empty, this method blocks.
+ *
+ * @return Dequeue object from the work thread.
+ * @throws InterruptedException If the queue has been stopped.
+ */
+ private synchronized DeviceTracker dequeue() throws InterruptedException {
+ while (running && (head == null)) {
+ /* This should be included per Section 8.7.7 of the OSGi SP R2
+ * spec, but it causes the OSGi SP R2 Test Suite to fail.
+ * We should turn this on for R3.
+
+ if (driverServiceRegistered)
+ */
+ if (false) {
+ driverServiceRegistered = false;
+
+ refineIdleDevices();
+ } else {
+ locators.uninstallDriverBundles();
+
+ try {
+ if (Activator.DEBUG) {
+ log.log(log.LOG_DEBUG, "DeviceManager waiting on queue"); //$NON-NLS-1$
+ }
+
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ if (!running) /* if we are stopping */
+ {
+ throw new InterruptedException(); /* throw an exception */
+ }
+
+ DeviceService item = head;
+ head = item.next;
+ if (head == null) {
+ tail = null;
+ }
+
+ return (item.device);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DeviceMsg.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DeviceMsg.java
new file mode 100644
index 000000000..bbb83f35e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DeviceMsg.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import org.eclipse.osgi.util.NLS;
+
+public class DeviceMsg extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.device.ExternalMessages"; //$NON-NLS-1$
+
+ public static String DeviceManager_started;
+ public static String Device_service_unregistered;
+ public static String Device_noDriverFound_called;
+ public static String Multiple_Driver_services_with_the_same_DRIVER_ID;
+ public static String DeviceManager_Update_Wait;
+ public static String Driver_service_has_no_DRIVER_ID_property;
+ public static String Device_attached_by_DRIVER_ID;
+ public static String Device_referred_to;
+ public static String Unable_to_create_Filter_for_DeviceManager;
+ public static String DeviceManager_has_thrown_an_error;
+ public static String Device_noDriverFound_error;
+ public static String DriverLocator_unable_to_load_driver;
+ public static String DriverLocator_error_calling_findDrivers;
+ public static String Unable_to_install_or_start_driver_bundle;
+ public static String Unable_to_uninstall_driver_bundle;
+ public static String Unable_to_uninstall_driver_bundle_number;
+ public static String DriverSelector_error_during_match;
+ public static String Driver_service_has_no_DRIVER_ID;
+ public static String Driver_error_during_match;
+ public static String Driver_error_during_attach;
+
+ static {
+ // initialize resource bundles
+ NLS.initializeMessages(BUNDLE_NAME, DeviceMsg.class);
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DeviceTracker.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DeviceTracker.java
new file mode 100644
index 000000000..ee85a7f6d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DeviceTracker.java
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import java.util.*;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+import org.osgi.service.device.Device;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * DeviceTracker class. This class has the logic for refining a
+ * Device service.
+ *
+ */
+public class DeviceTracker extends ServiceTracker {
+ /** OSGi Device class name */
+ protected final static String clazz = "org.osgi.service.device.Device"; //$NON-NLS-1$
+
+ /** DeviceManager object. */
+ protected Activator manager;
+
+ /** reference to Device service we are attempting to refine */
+ protected ServiceReference device;
+
+ /** LogService object */
+ protected LogService log;
+
+ /** Device services properties */
+ protected Dictionary properties;
+
+ /** if false the algorithm must terminate */
+ protected volatile boolean running;
+
+ /**
+ * Create a DeviceTracker from a ServiceReference.
+ *
+ * @param manager DeviceManager object
+ * @param device ServiceReference to the Device service.
+ * @param id ID of DeviceTracker object
+ */
+ public DeviceTracker(Activator manager, ServiceReference device) {
+ super(manager.context, device, null);
+
+ this.manager = manager;
+ log = manager.log;
+
+ if (Activator.DEBUG) {
+ log.log(device, log.LOG_DEBUG, this + " constructor"); //$NON-NLS-1$
+ }
+
+ open();
+ }
+
+ /**
+ * Close the Device.
+ */
+
+ public void close() {
+ if (device != null) {
+ if (Activator.DEBUG) {
+ log.log(device, log.LOG_DEBUG, this + " closing"); //$NON-NLS-1$
+ }
+
+ running = false; /* request thread to stop */
+
+ super.close();
+
+ device = null;
+ }
+ }
+
+ /**
+ * A service is being added to the ServiceTracker.
+ *
+ * <p>This method is called before a service which matched
+ * the search parameters of the ServiceTracker is
+ * added to the ServiceTracker. This method should return the
+ * service object to be tracked for this ServiceReference.
+ * The returned service object is stored in the ServiceTracker
+ * and is available from the getService and getServices
+ * methods.
+ *
+ * @param reference Reference to service being added to the ServiceTracker.
+ * @return The service object to be tracked for the
+ * ServiceReference or <tt>null</tt> if the ServiceReference should not
+ * be tracked.
+ */
+ public Object addingService(ServiceReference reference) {
+ if (Activator.DEBUG) {
+ log.log(reference, log.LOG_DEBUG, this + " adding Device service"); //$NON-NLS-1$
+ }
+
+ device = reference;
+
+ running = true;
+
+ properties = new Properties(reference);
+
+ return (reference);
+ }
+
+ /**
+ * A service tracked by the ServiceTracker has been modified.
+ *
+ * <p>This method is called when a service being tracked
+ * by the ServiceTracker has had it properties modified.
+ *
+ * @param reference Reference to service that has been modified.
+ * @param service The service object for the modified service.
+ */
+ public void modifiedService(ServiceReference reference, Object service) {
+ properties = new Properties(reference);
+ }
+
+ /**
+ * A service tracked by the ServiceTracker is being removed.
+ *
+ * <p>This method is called after a service is no longer being tracked
+ * by the ServiceTracker.
+ *
+ * @param reference Reference to service that has been removed.
+ * @param service The service object for the removed service.
+ */
+ public void removedService(ServiceReference reference, Object service) {
+ if (running) {
+ log.log(reference, log.LOG_WARNING, DeviceMsg.Device_service_unregistered);
+ running = false; /* request algorithm to stop */
+ } else {
+ if (Activator.DEBUG) {
+ log.log(reference, log.LOG_DEBUG, this + " removing Device service"); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * Attempt to refine this Device service.
+ *
+ */
+ public void refine() {
+ if (Activator.DEBUG) {
+ log.log(device, log.LOG_DEBUG, this + " refining " + device); //$NON-NLS-1$
+ }
+
+ if (running && isIdle()) {
+ /* List of excluded drivers from this algorithm run */
+ DriverTracker drivers = manager.drivers;
+
+ manager.locators.loadDrivers(properties, drivers);
+
+ Vector exclude = new Vector(drivers.size());
+
+ while (running) {
+ ServiceReference driver = drivers.match(device, exclude);
+
+ if (driver == null) {
+ noDriverFound();
+ break;
+ }
+
+ if (drivers.attach(driver, device, exclude)) {
+ break;
+ }
+ }
+ }
+
+ close();
+ }
+
+ /**
+ * Determine if the device service tracked by this object is idle.
+ *
+ * OSGi SP R2 Section 8.2.2 defines in idle device service as:
+ * "A Device service is not used by any other bundle according to the Framework;
+ * it is called an idle Device service."
+ *
+ * This method defines it as:
+ * A Device service is not used by any DRIVER bundle according to the Framework;
+ * it is called an idle Device service.
+ *
+ * Thus if a non-driver bundle uses a device service, it is still considered
+ * idle by this method.
+ *
+ * @return true if the device service is idle.
+ */
+ public boolean isIdle() {
+ if (Activator.DEBUG) {
+ log.log(device, log.LOG_DEBUG, "Check device service idle: " + device); //$NON-NLS-1$
+ }
+
+ Filter filter = manager.driverFilter;
+ Bundle[] users = device.getUsingBundles();
+
+ int userCount = (users == null) ? 0 : users.length;
+
+ for (int i = 0; i < userCount; i++) {
+ ServiceReference[] services = users[i].getRegisteredServices();
+
+ int servicesCount = (services == null) ? 0 : services.length;
+
+ for (int j = 0; j < servicesCount; j++) {
+ if (filter.match(services[j])) {
+ if (Activator.DEBUG) {
+ log.log(log.LOG_DEBUG, "Device " + device + " already in use by bundle " + users[i]); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ return (false);
+ }
+ }
+ }
+
+ return (true);
+ }
+
+ /**
+ * Called by the device manager after it has failed to attach
+ * any driver to the device.
+ * <p>
+ * If the device can be configured in alternate ways, the driver
+ * may respond by unregistering the device service and registering
+ * a different device service instead.</p>
+ */
+
+ public void noDriverFound() {
+ BundleContext context = manager.context;
+
+ Object service = context.getService(device);
+
+ try {
+ //It is possible that this is a Free Format Device that does not
+ //implement Device
+ if (service instanceof Device) {
+ log.log(device, log.LOG_INFO, DeviceMsg.Device_noDriverFound_called);
+
+ try {
+ ((Device) service).noDriverFound();
+ } catch (Throwable t) {
+ log.log(device, log.LOG_ERROR, NLS.bind(DeviceMsg.Device_noDriverFound_error, t));
+ }
+ }
+ } finally {
+ context.ungetService(device);
+ }
+
+ }
+
+ public String toString() {
+ return "DeviceTracker"; //$NON-NLS-1$
+ }
+
+ /**
+ * Readonly Dictionary for device properties.
+ *
+ */
+ static class Properties extends Hashtable {
+ /**
+ * keys in original case.
+ */
+ protected Vector keys;
+
+ /**
+ * Create a properties object for the service.
+ *
+ * @param device The service to get the properties of.
+ */
+ protected Properties(ServiceReference device) {
+ super();
+
+ String[] props = device.getPropertyKeys();
+
+ if (props != null) {
+ int size = props.length;
+
+ keys = new Vector(size);
+
+ for (int i = 0; i < size; i++) {
+ String key = props[i];
+ Object value = device.getProperty(key);
+
+ if (value != null) {
+ keys.addElement(key);
+
+ super.put(key.toLowerCase(), value);
+ }
+ }
+ } else {
+ keys = new Vector(0);
+ }
+ }
+
+ /**
+ * Override keys to support case-preserving of keys.
+ */
+ public Enumeration keys() {
+ return (keys.elements());
+ }
+
+ /**
+ * Override get to support case-insensitivity.
+ *
+ * @param key header name.
+ */
+ public Object get(Object key) {
+ if (key instanceof String) {
+ return (super.get(((String) key).toLowerCase()));
+ }
+
+ return (null);
+ }
+
+ /**
+ * Override put to disable it. This Dictionary is readonly once built.
+ *
+ * @param key header name.
+ * @param value header value.
+ * @throws UnsupportedOperationException.
+ */
+ public Object put(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Override remove to disable it. This Dictionary is readonly once built.
+ *
+ * @param key header name.
+ * @throws UnsupportedOperationException.
+ */
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverLocatorTracker.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverLocatorTracker.java
new file mode 100644
index 000000000..329fd6738
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverLocatorTracker.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import java.io.InputStream;
+import java.util.Dictionary;
+import java.util.Vector;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+import org.osgi.service.device.DriverLocator;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * DriverLocatorTracker class. This class tracks all DriverLocator services.
+ *
+ */
+public class DriverLocatorTracker extends ServiceTracker {
+ protected final static String clazz = "org.osgi.service.device.DriverLocator"; //$NON-NLS-1$
+
+ /** DeviceManager object. */
+ protected Activator manager;
+
+ /** LogService object */
+ protected LogService log;
+
+ /** List of bundles to be uninstalled. */
+ protected Vector bundles;
+
+ /**
+ * Create the DriverLocatorTracker.
+ *
+ * @param context Device manager bundle context.
+ * @param log LogService object
+ */
+ public DriverLocatorTracker(Activator manager) {
+ super(manager.context, clazz, null);
+
+ this.manager = manager;
+ log = manager.log;
+ bundles = new Vector(10, 10);
+
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, "DriverLocatorTracker constructor"); //$NON-NLS-1$
+ }
+
+ open();
+ }
+
+ /**
+ * A service is being added to the ServiceTracker.
+ *
+ * <p>This method is called before a service which matched
+ * the search parameters of the ServiceTracker is
+ * added to the ServiceTracker. This method should return the
+ * service object to be tracked for this ServiceReference.
+ * The returned service object is stored in the ServiceTracker
+ * and is available from the getService and getServices
+ * methods.
+ *
+ * @param reference Reference to service being added to the ServiceTracker.
+ * @return The service object to be tracked for the
+ * ServiceReference or <tt>null</tt> if the ServiceReference should not
+ * be tracked.
+ */
+ public Object addingService(ServiceReference reference) {
+ if (Activator.DEBUG) {
+ log.log(reference, LogService.LOG_DEBUG, "DriverLocatorTracker adding service"); //$NON-NLS-1$
+ }
+
+ return (context.getService(reference));
+ }
+
+ /**
+ * A service tracked by the ServiceTracker has been modified.
+ *
+ * <p>This method is called when a service being tracked
+ * by the ServiceTracker has had it properties modified.
+ *
+ * @param reference Reference to service that has been modified.
+ * @param service The service object for the modified service.
+ */
+ public void modifiedService(ServiceReference reference, Object service) {
+ }
+
+ /**
+ * A service tracked by the ServiceTracker is being removed.
+ *
+ * <p>This method is called after a service is no longer being tracked
+ * by the ServiceTracker.
+ *
+ * @param reference Reference to service that has been removed.
+ * @param service The service object for the removed service.
+ */
+ public void removedService(ServiceReference reference, Object object) {
+ if (Activator.DEBUG) {
+ log.log(reference, LogService.LOG_DEBUG, "DriverLocatorTracker removing service"); //$NON-NLS-1$
+ }
+
+ context.ungetService(reference);
+ }
+
+ /**
+ * Call the DriverLocator services in an attempt to locate and
+ * install driver bundles to refine the device service.
+ *
+ * @param locators Array of DriverLocator objects
+ * @param drivers Dictionary of drivers with key=DRIVER_ID, value=Driver object
+ */
+ public void loadDrivers(Dictionary properties, DriverTracker drivers) {
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocatorTracker loadDrivers called"); //$NON-NLS-1$
+ }
+
+ ServiceReference[] references = getServiceReferences();
+
+ if (references != null) {
+ int size = references.length;
+
+ for (int i = 0; i < size; i++) {
+ ServiceReference locator = references[i];
+ DriverLocator service = (DriverLocator) getService(locator);
+
+ if (service != null) {
+ if (Activator.DEBUG) {
+ log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator findDrivers called"); //$NON-NLS-1$
+ }
+
+ try {
+ String[] driver_ids = service.findDrivers(properties);
+
+ if (Activator.DEBUG) {
+ int count = (driver_ids == null) ? 0 : driver_ids.length;
+
+ StringBuffer sb = new StringBuffer();
+
+ sb.append('<');
+
+ for (int k = 0; k < count; k++) {
+ if (k > 0) {
+ sb.append(',');
+ }
+ sb.append(driver_ids[k]);
+ }
+
+ sb.append('>');
+
+ log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator findDrivers returned: " + sb); //$NON-NLS-1$
+ }
+
+ if (driver_ids != null) {
+ int count = driver_ids.length;
+
+ for (int j = 0; j < count; j++) {
+ String driver_id = driver_ids[j];
+
+ if (drivers.getDriver(driver_id) == null) {
+ if (Activator.DEBUG) {
+ log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator loadDriver called for driver: " + driver_id); //$NON-NLS-1$
+ }
+
+ try {
+ InputStream in = service.loadDriver(driver_id);
+
+ if (Activator.DEBUG) {
+ log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator loadDriver returned: " + in); //$NON-NLS-1$
+ }
+
+ installDriverBundle(driver_id, in);
+ } catch (Throwable t) {
+ log.log(locator, LogService.LOG_ERROR, NLS.bind(DeviceMsg.DriverLocator_unable_to_load_driver, driver_id), t);
+ }
+ }
+ }
+ }
+ } catch (Throwable t) {
+ log.log(locator, LogService.LOG_ERROR, DeviceMsg.DriverLocator_error_calling_findDrivers, t);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Get an <code>InputStream</code> from which the driver bundle providing a driver with the giving ID can be installed.
+ *
+ * @param id the ID of the driver that needs to be installed.
+ * @return the <code>InputStream</code> from which the driver
+ * bundle can be installed
+ */
+
+ public void loadDriver(String driver_id, DriverTracker drivers) {
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocatorTracker loadDriver called for driver: " + driver_id); //$NON-NLS-1$
+ }
+
+ if (drivers.getDriver(driver_id) == null) {
+ ServiceReference[] references = getServiceReferences();
+
+ if (references != null) {
+ int size = references.length;
+
+ for (int i = 0; i < size; i++) {
+ ServiceReference locator = references[i];
+ DriverLocator service = (DriverLocator) getService(locator);
+
+ if (service != null) {
+ if (Activator.DEBUG) {
+ log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator loadDriver called for driver: " + driver_id); //$NON-NLS-1$
+ }
+
+ try {
+ InputStream in = service.loadDriver(driver_id);
+
+ if (Activator.DEBUG) {
+ log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator loadDriver returned: " + in); //$NON-NLS-1$
+ }
+
+ if (in != null) {
+ installDriverBundle(driver_id, in);
+
+ break;
+ }
+ } catch (Throwable t) {
+ log.log(locator, LogService.LOG_ERROR, NLS.bind(DeviceMsg.DriverLocator_unable_to_load_driver, driver_id), t);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Install a Driver bundle.
+ *
+ * @param driver_id DRIVER_ID for new driver bundle.
+ * @param in InputStream to a new driver bundle.
+ */
+ public void installDriverBundle(String driver_id, InputStream in) {
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": installDriverBundle from InputStream: " + driver_id); //$NON-NLS-1$
+ }
+
+ if (in != null) {
+ Bundle bundle = null;
+
+ try {
+ bundle = context.installBundle(driver_id, in);
+ /* installBundle will close the InputStream */
+
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": Driver bundle installed: " + driver_id); //$NON-NLS-1$
+ }
+
+ synchronized (bundles) {
+ if (!bundles.contains(bundle)) {
+ bundles.addElement(bundle);
+ }
+ }
+
+ bundle.start();
+
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": Driver bundle started: " + driver_id); //$NON-NLS-1$
+ }
+ } catch (BundleException e) {
+ log.log(LogService.LOG_ERROR, NLS.bind(DeviceMsg.Unable_to_install_or_start_driver_bundle, driver_id), e);
+
+ if (bundle != null) {
+ bundles.removeElement(bundle);
+
+ try {
+ bundle.uninstall();
+
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": Driver bundle uninstalled: " + driver_id); //$NON-NLS-1$
+ }
+ } catch (BundleException ee) {
+ log.log(LogService.LOG_ERROR, NLS.bind(DeviceMsg.Unable_to_uninstall_driver_bundle_number, driver_id), ee);
+ }
+
+ bundle = null;
+ }
+ }
+ }
+ }
+
+ /**
+ * Remove bundle from uninstall list.
+ *
+ * @param bundle bundle to remove from list.
+ */
+ public void usingDriverBundle(Bundle bundle) {
+ bundles.removeElement(bundle);
+ }
+
+ /**
+ * Uninstall the recently installed but unused driver bundles.
+ *
+ */
+ public void uninstallDriverBundles() {
+ int size;
+ Bundle[] uninstall = null;
+
+ synchronized (bundles) {
+ size = bundles.size();
+
+ if (size > 0) {
+ uninstall = new Bundle[size];
+ bundles.copyInto(uninstall);
+ }
+ }
+
+ for (int i = 0; i < size; i++) {
+ Bundle bundle = uninstall[i];
+
+ if ((bundle.getState() & Bundle.UNINSTALLED) == 0) { /* if bundle not already uninstalled */
+ try {
+ bundle.uninstall();
+
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": Driver bundle uninstalled"); //$NON-NLS-1$
+ }
+ } catch (BundleException ee) {
+ log.log(LogService.LOG_ERROR, NLS.bind(DeviceMsg.Unable_to_uninstall_driver_bundle, ee));
+ }
+ }
+ }
+
+ bundles.removeAllElements();
+ }
+
+ public boolean isUninstallCandidate(Bundle bundle) {
+ return bundles.contains(bundle);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverSelectorTracker.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverSelectorTracker.java
new file mode 100644
index 000000000..cbd469a0f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverSelectorTracker.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.device.Device;
+import org.osgi.service.device.DriverSelector;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * DriverSelectorTracker class. This class tracks all DriverSelector services.
+ *
+ */
+public class DriverSelectorTracker extends ServiceTracker {
+ /** Driver service name */
+ protected final static String clazz = "org.osgi.service.device.DriverSelector"; //$NON-NLS-1$
+
+ /** LogService object */
+ protected LogService log;
+
+ /** DeviceManager object. */
+ protected Activator manager;
+
+ /**
+ * Create the DriverTracker.
+ *
+ * @param manager DeviceManager object.
+ * @param device DeviceTracker we are working for.
+ */
+ public DriverSelectorTracker(Activator manager) {
+ super(manager.context, clazz, null);
+
+ this.manager = manager;
+ log = manager.log;
+
+ if (Activator.DEBUG) {
+ log.log(log.LOG_DEBUG, "DriverSelectorTracker constructor"); //$NON-NLS-1$
+ }
+
+ open();
+ }
+
+ /**
+ * Select the matching driver.
+ *
+ * @param device Device service being matched.
+ * @param matches Array of the successful matches from Driver services.
+ * @return ServiceReference to best matched Driver or null of their is no match.
+ */
+ public ServiceReference select(ServiceReference device, Match[] matches) {
+ if (Activator.DEBUG) {
+ log.log(device, log.LOG_DEBUG, "DriverSelector select called"); //$NON-NLS-1$
+ }
+
+ //This should give us the highest ranking DriverSelector (if available)
+ ServiceReference selector = getServiceReference();
+
+ if (selector != null) {
+ DriverSelector service = (DriverSelector) getService(selector);
+
+ try {
+ int index = service.select(device, matches);
+
+ if (index == DriverSelector.SELECT_NONE) {
+ return null;
+ }
+
+ return matches[index].getDriver();
+ } catch (Throwable t) {
+ log.log(selector, log.LOG_ERROR, DeviceMsg.DriverSelector_error_during_match, t);
+ }
+ }
+
+ return defaultSelection(matches);
+ }
+
+ /**
+ * Default match selection algorithm from OSGi SPR2 spec.
+ *
+ * @param matchArray An array of the successful matches.
+ * @return ServiceReference to the selected Driver service
+ */
+ public ServiceReference defaultSelection(Match[] matches) {
+ int size = matches.length;
+
+ int max = Device.MATCH_NONE;
+ ServiceReference reference = null;
+
+ for (int i = 0; i < size; i++) {
+ Match driver = matches[i];
+
+ int match = driver.getMatchValue();
+
+ if (match >= max) {
+ if (match == max) /* we must break the tie */
+ {
+ reference = breakTie(reference, driver.getDriver());
+ } else {
+ max = match;
+ reference = driver.getDriver();
+ }
+ }
+ }
+
+ return reference;
+ }
+
+ /**
+ * Select the service with the highest service.ranking. Break ties
+ * buy selecting the lowest service.id.
+ *
+ */
+ public ServiceReference breakTie(ServiceReference ref1, ServiceReference ref2) {
+ //first we check service rankings
+ Object property = ref1.getProperty(org.osgi.framework.Constants.SERVICE_RANKING);
+
+ int ref1Ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
+
+ property = ref2.getProperty(org.osgi.framework.Constants.SERVICE_RANKING);
+
+ int ref2Ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
+
+ if (ref1Ranking > ref2Ranking) {
+ return ref1;
+ } else if (ref2Ranking > ref1Ranking) {
+ return ref2;
+ } else // The rankings must match here
+ {
+ //we now check service ids
+ long ref1ID = ((Long) (ref1.getProperty(org.osgi.framework.Constants.SERVICE_ID))).longValue();
+
+ long ref2ID = ((Long) (ref2.getProperty(org.osgi.framework.Constants.SERVICE_ID))).longValue();
+
+ if (ref1ID < ref2ID) {
+ return ref1;
+ }
+
+ return ref2;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverTracker.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverTracker.java
new file mode 100644
index 000000000..a7026c401
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/DriverTracker.java
@@ -0,0 +1,485 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Hashtable;
+import java.util.Vector;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+import org.osgi.service.device.Device;
+import org.osgi.service.device.Driver;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * DriverTracker class. This class tracks all Driver services.
+ *
+ */
+public class DriverTracker extends ServiceTracker {
+ /** Driver service name */
+ protected final static String clazz = "org.osgi.service.device.Driver"; //$NON-NLS-1$
+
+ /** LogService object */
+ protected LogService log;
+
+ /** Dictionary mapping DRIVER_ID strings <==> Driver ServiceReferences */
+ protected Hashtable drivers;
+
+ /** DeviceManager object. */
+ protected Activator manager;
+
+ /** Dictionary mapping Driver ID String =>
+ * Hashtable (Device ServiceReference => cached Match objects) */
+ protected Hashtable matches;
+
+ /** Dictionary mapping Driver ID String =>
+ * Hashtable (Device ServiceReference => cached referral String) */
+ protected Hashtable referrals;
+
+ /**
+ * Create the DriverTracker.
+ *
+ * @param manager DeviceManager object.
+ * @param device DeviceTracker we are working for.
+ */
+ public DriverTracker(Activator manager) {
+ super(manager.context, clazz, null);
+
+ this.manager = manager;
+ log = manager.log;
+
+ drivers = new Hashtable(37);
+ matches = new Hashtable(37);
+ referrals = new Hashtable(37);
+
+ if (Activator.DEBUG) {
+ log.log(LogService.LOG_DEBUG, this + " constructor"); //$NON-NLS-1$
+ }
+
+ open();
+ }
+
+ /**
+ * A service is being added to the ServiceTracker.
+ *
+ * <p>This method is called before a service which matched
+ * the search parameters of the ServiceTracker is
+ * added to the ServiceTracker. This method should return the
+ * service object to be tracked for this ServiceReference.
+ * The returned service object is stored in the ServiceTracker
+ * and is available from the getService and getServices
+ * methods.
+ *
+ * @param reference Reference to service being added to the ServiceTracker.
+ * @return The service object to be tracked for the
+ * ServiceReference or <tt>null</tt> if the ServiceReference should not
+ * be tracked.
+ */
+ public Object addingService(ServiceReference reference) {
+ if (Activator.DEBUG) {
+ log.log(reference, LogService.LOG_DEBUG, this + " adding service"); //$NON-NLS-1$
+ }
+
+ String driver_id = getDriverID(reference);
+
+ if (drivers.get(driver_id) != null) {
+ log.log(reference, LogService.LOG_WARNING, NLS.bind(DeviceMsg.Multiple_Driver_services_with_the_same_DRIVER_ID, driver_id));
+
+ return (null); /* don't track this driver */
+ }
+
+ drivers.put(driver_id, reference);
+ drivers.put(reference, driver_id);
+
+ manager.driverServiceRegistered = true;
+
+ /* OSGi SPR2 Device Access 1.1
+ * Section 8.4.3 - When a new Driver service is registered,
+ * the Device Attachment Algorithm must be applied to all
+ * idle Device services.
+ *
+ * We do not refine idle Devices when the manager has not fully
+ * started or the Driver service is from a bundle just installed
+ * by the devicemanager.
+ */
+ Bundle bundle = reference.getBundle();
+
+ if (manager.running && !manager.locators.isUninstallCandidate(bundle)) {
+ manager.refineIdleDevices();
+ }
+
+ return (context.getService(reference));
+ }
+
+ /**
+ * A service tracked by the ServiceTracker has been modified.
+ *
+ * <p>This method is called when a service being tracked
+ * by the ServiceTracker has had it properties modified.
+ *
+ * @param reference Reference to service that has been modified.
+ * @param service The service object for the modified service.
+ */
+ public void modifiedService(ServiceReference reference, Object service) {
+ if (Activator.DEBUG) {
+ log.log(reference, LogService.LOG_DEBUG, this + " modified service"); //$NON-NLS-1$
+ }
+
+ String driver_id = getDriverID(reference);
+
+ String old_id = (String) drivers.get(reference);
+
+ if (!driver_id.equals(old_id)) {
+ drivers.put(driver_id, reference);
+ drivers.put(reference, driver_id);
+ drivers.remove(old_id);
+ }
+ }
+
+ /**
+ * A service tracked by the ServiceTracker is being removed.
+ *
+ * <p>This method is called after a service is no longer being tracked
+ * by the ServiceTracker.
+ *
+ * @param reference Reference to service that has been removed.
+ * @param service The service object for the removed service.
+ */
+ public void removedService(ServiceReference reference, Object object) {
+ if (Activator.DEBUG) {
+ log.log(reference, LogService.LOG_DEBUG, this + " removing service"); //$NON-NLS-1$
+ }
+
+ String driver_id = getDriverID(reference);
+ drivers.remove(driver_id);
+ drivers.remove(reference);
+
+ matches.remove(driver_id);
+ referrals.remove(driver_id);
+
+ context.ungetService(reference);
+
+ /* OSGi SPR2 Device Access 1.1
+ * Section 8.4.4 - When a Driver service is unregistered,
+ * the Device Attachment Algorithm must be applied to all
+ * idle Device services.
+ *
+ * We do not refine idle Devices when the manager has not fully
+ * started or the Driver service is from a bundle just installed
+ * by the devicemanager.
+ */
+
+ Bundle bundle = reference.getBundle();
+
+ if (manager.running && !manager.locators.isUninstallCandidate(bundle)) {
+ DriverUpdate update = new DriverUpdate(bundle, manager);
+
+ Thread thread = (new SecureAction()).createThread(update, DeviceMsg.DeviceManager_Update_Wait);
+
+ thread.start();
+ }
+ }
+
+ /**
+ * Return the DRIVER_ID string for a ServiceReference.
+ *
+ * Per Section 8.4.3 of the OSGi SP R2 spec,
+ * "A Driver service registration must have a DRIVER_ID property"
+ *
+ * This method is somewhat more lenient. If no DRIVER_ID property
+ * is set, it will use the Bundle's location instead.
+ *
+ * @param reference Reference to driver service.
+ * @param log LogService object.
+ * @return DRIVER_ID string.
+ */
+ public String getDriverID(final ServiceReference reference) {
+ String driver_id = (String) reference.getProperty(org.osgi.service.device.Constants.DRIVER_ID);
+
+ if (driver_id == null) {
+ log.log(reference, LogService.LOG_WARNING, DeviceMsg.Driver_service_has_no_DRIVER_ID);
+ driver_id = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return reference.getBundle().getLocation();
+ }
+ });
+ }
+
+ return (driver_id);
+ }
+
+ /**
+ * Get the ServiceReference for a given DRIVER_ID.
+ *
+ * @param driver_id
+ * @return ServiceReference to a Driver service.
+ */
+ public ServiceReference getDriver(String driver_id) {
+ return ((ServiceReference) drivers.get(driver_id));
+ }
+
+ /**
+ * Search the driver list to find the best match for the device.
+ *
+ * @return ServiceReference to best matched Driver or null of their is no match.
+ */
+ public ServiceReference match(ServiceReference device, Vector exclude) {
+ if (Activator.DEBUG) {
+ log.log(device, LogService.LOG_DEBUG, this + ": Driver match called"); //$NON-NLS-1$
+ }
+
+ ServiceReference[] references = getServiceReferences();
+
+ if (references != null) {
+ int size = references.length;
+
+ Vector successfulMatches = new Vector(size);
+
+ for (int i = 0; i < size; i++) {
+ ServiceReference driver = references[i];
+
+ if (exclude.contains(driver)) {
+ if (Activator.DEBUG) {
+ log.log(driver, LogService.LOG_DEBUG, this + ": Driver match excluded: " + drivers.get(driver)); //$NON-NLS-1$
+ }
+ } else {
+ if (Activator.DEBUG) {
+ log.log(driver, LogService.LOG_DEBUG, this + ": Driver match called: " + drivers.get(driver)); //$NON-NLS-1$
+ }
+
+ Match match = getMatch(driver, device);
+
+ if (match == null) {
+ Driver service = (Driver) getService(driver);
+
+ if (service == null) {
+ continue;
+ }
+
+ int matchValue = Device.MATCH_NONE;
+
+ try {
+ matchValue = service.match(device);
+ } catch (Throwable t) {
+ log.log(driver, LogService.LOG_ERROR, DeviceMsg.Driver_error_during_match, t);
+
+ continue;
+ }
+
+ if (Activator.DEBUG) {
+ log.log(driver, LogService.LOG_DEBUG, this + ": Driver match value: " + matchValue); //$NON-NLS-1$
+ }
+
+ match = new Match(driver, matchValue);
+
+ storeMatch(driver, device, match);
+ }
+
+ if (match.getMatchValue() > Device.MATCH_NONE) {
+ successfulMatches.addElement(match);
+ }
+ }
+ }
+
+ size = successfulMatches.size();
+
+ if (size > 0) {
+ Match[] matchArray = new Match[size];
+ successfulMatches.copyInto(matchArray);
+
+ return manager.selectors.select(device, matchArray);
+ }
+ }
+
+ return null;
+ }
+
+ public Match getMatch(ServiceReference driver, ServiceReference device) {
+ String driverid = getDriverID(driver);
+
+ Hashtable driverMatches = (Hashtable) matches.get(driverid);
+
+ if (driverMatches == null) {
+ return null;
+ }
+
+ return (Match) driverMatches.get(device);
+ }
+
+ public void storeMatch(ServiceReference driver, ServiceReference device, Match match) {
+ String driverid = getDriverID(driver);
+
+ Hashtable driverMatches = (Hashtable) matches.get(driverid);
+
+ if (driverMatches == null) {
+ driverMatches = new Hashtable(37);
+
+ matches.put(driverid, driverMatches);
+ }
+
+ driverMatches.put(device, match);
+ }
+
+ /**
+ * Attempt to attach the driver to the device. If the driver
+ * refers, add the referred driver to the driver list.
+ *
+ * @param driver Driver to attach
+ * @param device Device to be attached
+ * @return true is the Driver successfully attached.
+ */
+ public boolean attach(ServiceReference driver, ServiceReference device, Vector exclude) {
+ if (Activator.DEBUG) {
+ log.log(driver, LogService.LOG_DEBUG, this + ": Driver attach called: " + drivers.get(driver)); //$NON-NLS-1$
+ }
+
+ Driver service = (Driver) getService(driver);
+
+ if (service != null) {
+ String referral = getReferral(driver, device);
+
+ if (referral == null) {
+ try {
+ referral = service.attach(device);
+ } catch (Throwable t) {
+ log.log(driver, LogService.LOG_ERROR, DeviceMsg.Driver_error_during_attach, t);
+
+ exclude.addElement(driver);
+
+ return (false);
+ }
+
+ storeReferral(driver, device, (referral == null) ? "" : referral); //$NON-NLS-1$
+ } else {
+ if (referral.length() == 0) {
+ referral = null;
+ }
+ }
+
+ if (referral == null) {
+ log.log(device, LogService.LOG_INFO, NLS.bind(DeviceMsg.Device_attached_by_DRIVER_ID, drivers.get(driver)));
+
+ manager.locators.usingDriverBundle(driver.getBundle());
+
+ return (true);
+ }
+
+ log.log(device, LogService.LOG_INFO, NLS.bind(DeviceMsg.Device_referred_to, referral));
+ manager.locators.loadDriver(referral, this);
+ }
+
+ exclude.addElement(driver);
+
+ return (false);
+ }
+
+ public String getReferral(ServiceReference driver, ServiceReference device) {
+ String driverid = getDriverID(driver);
+
+ Hashtable driverReferrals = (Hashtable) referrals.get(driverid);
+
+ if (driverReferrals == null) {
+ return null;
+ }
+
+ return (String) driverReferrals.get(device);
+ }
+
+ public void storeReferral(ServiceReference driver, ServiceReference device, String referral) {
+ String driverid = getDriverID(driver);
+
+ Hashtable driverReferrals = (Hashtable) referrals.get(driverid);
+
+ if (driverReferrals == null) {
+ driverReferrals = new Hashtable(37);
+
+ referrals.put(driverid, driverReferrals);
+ }
+
+ driverReferrals.put(device, referral);
+ }
+
+ public String toString() {
+ return "DriverTracker"; //$NON-NLS-1$
+ }
+
+ public class DriverUpdate implements Runnable, ServiceListener, BundleListener {
+ private Activator manager;
+ private Bundle bundle;
+ private BundleContext context;
+
+ /** if false the thread must terminate */
+ private volatile boolean running;
+
+ private long updatewait;
+
+ DriverUpdate(Bundle bundle, Activator manager) {
+ this.manager = manager;
+ this.bundle = bundle;
+
+ context = manager.context;
+ updatewait = manager.updatewait;
+ running = true;
+
+ context.addBundleListener(this);
+ try {
+ context.addServiceListener(this, manager.driverFilter.toString());
+ } catch (InvalidSyntaxException e) {
+ /* this should not happen */
+ }
+ }
+
+ public void run() {
+ // 1. Wait for some time
+ // 2. if bundle registers Driver; terminate
+ // 3. if bundle uninstalls; cancel wait
+ // 4. manager.refineIdleDevices()
+
+ try {
+ if (updatewait > 0) {
+ synchronized (this) {
+ wait(updatewait);
+ }
+ }
+ } catch (InterruptedException e) {
+ }
+
+ context.removeServiceListener(this);
+ context.removeBundleListener(this);
+
+ if (running) {
+ manager.refineIdleDevices();
+ }
+ }
+
+ public void serviceChanged(ServiceEvent event) {
+ if ((event.getType() == ServiceEvent.REGISTERED) && bundle.equals(event.getServiceReference().getBundle())) {
+ context.removeServiceListener(this);
+
+ running = false; /* cancel */
+
+ /* should probably interrupt waiting thread here */
+ }
+ }
+
+ public void bundleChanged(BundleEvent event) {
+ if ((event.getType() == Bundle.UNINSTALLED) && bundle.equals(event.getBundle())) {
+ context.removeBundleListener(this);
+
+ updatewait = 0; /* avoid wait */
+
+ /* should probably interrupt waiting thread here */
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/ExternalMessages.properties b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/ExternalMessages.properties
new file mode 100644
index 000000000..380f8f015
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/ExternalMessages.properties
@@ -0,0 +1,37 @@
+###############################################################################
+# Copyright (c) 2000, 2005 IBM Corporation.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+# NLS_MESSAGEFORMAT_ALL
+
+DeviceManager_started=DeviceManager started
+Device_service_unregistered=Device service unregistered
+Device_noDriverFound_called=No matching driver found for device
+Multiple_Driver_services_with_the_same_DRIVER_ID=Multiple Driver services with the same DRIVER_ID: {0}
+DeviceManager_Update_Wait=DeviceManager Update Wait
+Driver_service_has_no_DRIVER_ID_property=Driver service has no DRIVER_ID property. Using bundle location as DRIVER_ID.
+Device_attached_by_DRIVER_ID=Device attached by DRIVER_ID={0}
+Device_referred_to=Device referred to {0}
+Unable_to_create_Filter_for_DeviceManager=Unable to create Filter for DeviceManager
+DeviceManager_has_thrown_an_error=DeviceManager has thrown an error
+Device_noDriverFound_error=Device noDriverFound error
+DriverLocator_unable_to_load_driver=DriverLocator unable to load driver: {0}
+DriverLocator_error_calling_findDrivers=DriverLocator error calling findDrivers
+Unable_to_install_or_start_driver_bundle=Unable to install or start driver bundle: {0}
+Unable_to_uninstall_driver_bundle=Unable to uninstall driver bundle
+Unable_to_uninstall_driver_bundle_number=Unable to uninstall driver bundle: {0}
+DriverSelector_error_during_match=DriverSelector error during match
+Driver_service_has_no_DRIVER_ID=Driver service has no DRIVER_ID property. Using bundle location as DRIVER_ID.
+Driver_error_during_match=Driver error during match
+Driver_error_during_attach=Driver error during attach
+
+Unknown_Log_level=Unknown Log Level
+Info=Log Info
+Warning=Log Warning
+Error=Log Error \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/LogTracker.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/LogTracker.java
new file mode 100644
index 000000000..25debd056
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/LogTracker.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import java.io.PrintStream;
+import java.text.DateFormat;
+import java.util.Calendar;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * LogTracker class. This class encapsulates the LogService
+ * and handles all issues such as the service coming and going.
+ */
+
+public class LogTracker extends ServiceTracker implements LogService {
+ /** LogService interface class name */
+ protected final static String clazz = "org.osgi.service.log.LogService"; //$NON-NLS-1$
+
+ /** PrintStream to use if LogService is unavailable */
+ protected PrintStream out;
+
+ /** Calendar and DateFormat to user if LogService is unavailable */
+ private static Calendar calendar;
+ private static DateFormat dateFormat;
+ private String timestamp;
+
+ /**
+ * Create new LogTracker.
+ *
+ * @param context BundleContext of parent bundle.
+ * @param out Default PrintStream to use if LogService is unavailable.
+ */
+ public LogTracker(BundleContext context, PrintStream out) {
+ super(context, clazz, null);
+ this.out = out;
+ calendar = Calendar.getInstance();
+ dateFormat = DateFormat.getDateTimeInstance();
+ open();
+ }
+
+ /*
+ * ----------------------------------------------------------------------
+ * LogService Interface implementation
+ * ----------------------------------------------------------------------
+ */
+
+ public void log(int level, String message) {
+ log(null, level, message, null);
+ }
+
+ public void log(int level, String message, Throwable exception) {
+ log(null, level, message, exception);
+ }
+
+ public void log(ServiceReference reference, int level, String message) {
+ log(reference, level, message, null);
+ }
+
+ public synchronized void log(ServiceReference reference, int level, String message, Throwable exception) {
+ ServiceReference[] references = getServiceReferences();
+
+ if (references != null) {
+ int size = references.length;
+
+ for (int i = 0; i < size; i++) {
+ LogService service = (LogService) getService(references[i]);
+ if (service != null) {
+ try {
+ service.log(reference, level, message, exception);
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ return;
+ }
+
+ noLogService(level, message, exception, reference);
+ }
+
+ /**
+ * The LogService is not available so we write the message to a PrintStream.
+ *
+ * @param level Logging level
+ * @param message Log message.
+ * @param throwable Log exception or null if none.
+ * @param reference ServiceReference associated with message or null if none.
+ */
+ protected void noLogService(int level, String message, Throwable throwable, ServiceReference reference) {
+ if (out != null) {
+ synchronized (out) {
+ // Bug #113286. If no log service present and messages are being
+ // printed to stdout, prepend message with a timestamp.
+ timestamp = dateFormat.format(calendar.getTime());
+ out.print(timestamp + " "); //$NON-NLS-1$
+
+ switch (level) {
+ case LOG_DEBUG : {
+ out.print("Debug: "); //$NON-NLS-1$
+
+ break;
+ }
+ case LOG_INFO : {
+ out.print(LogTrackerMsg.Info);
+
+ break;
+ }
+ case LOG_WARNING : {
+ out.print(LogTrackerMsg.Warning);
+
+ break;
+ }
+ case LOG_ERROR : {
+ out.print(LogTrackerMsg.Error);
+
+ break;
+ }
+ default : {
+ out.print("["); //$NON-NLS-1$
+ out.print(LogTrackerMsg.Unknown_Log_level);
+ out.print("]: "); //$NON-NLS-1$
+
+ break;
+ }
+ }
+
+ out.println(message);
+
+ if (reference != null) {
+ out.println(reference);
+ }
+
+ if (throwable != null) {
+ throwable.printStackTrace(out);
+ }
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/LogTrackerMsg.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/LogTrackerMsg.java
new file mode 100644
index 000000000..75c1b48d4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/LogTrackerMsg.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import org.eclipse.osgi.util.NLS;
+
+public class LogTrackerMsg extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.device.ExternalMessages"; //$NON-NLS-1$
+
+ public static String Unknown_Log_level;
+ public static String Info;
+ public static String Warning;
+ public static String Error;
+
+ static {
+ // initialize resource bundles
+ NLS.initializeMessages(BUNDLE_NAME, LogTrackerMsg.class);
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/Match.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/Match.java
new file mode 100644
index 000000000..39482e87c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/Match.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.device;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Match implementation class.
+ *
+ */
+public class Match implements org.osgi.service.device.Match {
+
+ private ServiceReference driver;
+ private int matchValue;
+
+ Match(ServiceReference driver, int matchValue) {
+ this.driver = driver;
+ this.matchValue = matchValue;
+ }
+
+ public ServiceReference getDriver() {
+ return driver;
+ }
+
+ public int getMatchValue() {
+ return matchValue;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/SecureAction.java b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/SecureAction.java
new file mode 100644
index 000000000..132cfae1a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.device/src/org/eclipse/equinox/device/SecureAction.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2005 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.device;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.*;
+
+/**
+ * Utility class to execute common privileged code.
+ */
+public class SecureAction {
+ // make sure we use the correct controlContext;
+ private AccessControlContext controlContext;
+
+ /**
+ * Constructs a new SecureAction object. The constructed SecureAction object
+ * uses the caller's AccessControlContext to perform security checks
+ */
+ public SecureAction() {
+ // save the control context to be used.
+ this.controlContext = AccessController.getContext();
+ }
+
+ /**
+ * Creates a new Thread from a Runnable. Same as calling
+ * new Thread(target,name).
+ * @param target the Runnable to create the Thread from.
+ * @param name The name of the Thread.
+ * @return The new Thread
+ */
+ public Thread createThread(final Runnable target, final String name) {
+ if (System.getSecurityManager() == null)
+ return new Thread(target, name);
+ return (Thread) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Thread(target, name);
+ }
+ }, controlContext);
+ }
+
+
+}

Back to the top