📄 activator.java
字号:
/* * Copyright (c) 2003, KNOPFLERFISH project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * - Neither the name of the KNOPFLERFISH project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */package org.knopflerfish.bundle.device;import java.io.InputStream;import java.util.Dictionary;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import org.osgi.framework.Bundle;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;import org.osgi.framework.BundleEvent;import org.osgi.framework.BundleListener;import org.osgi.framework.Filter;import org.osgi.framework.FrameworkEvent;import org.osgi.framework.FrameworkListener;import org.osgi.framework.ServiceEvent;import org.osgi.framework.ServiceListener;import org.osgi.framework.ServiceReference;import org.osgi.service.device.Device;import org.osgi.service.device.Driver;import org.osgi.service.device.DriverLocator;import org.osgi.service.device.DriverSelector;import org.osgi.service.device.Match;import org.osgi.service.log.LogService;public class Activator extends Thread implements BundleActivator, ServiceListener, BundleListener, FrameworkListener { // NB: These constants should be configurable private static final long LONG_LIFE = 15 * 60 * 1000; private static final long SHORT_LIFE = 5 * 60 * 1000; private static final long REAP_INTERVAL = 1 * 60 * 1000; static final String DYNAMIC_DRIVER_TAG = "__DD_"; private static final String LOG_FILTER = "(objectClass=" + LogService.class.getName() + ")"; private static final String DEVICE_FILTER = "(|(objectClass=" + Device.class.getName() + ")(DEVICE_CATEGORY=*))"; private static final String DRIVER_FILTER = "(objectClass=" + Driver.class.getName() + ")"; private static final String SELECTOR_FILTER = "(objectClass=" + DriverSelector.class.getName() + ")"; private static final String LOCATOR_FILTER = "(objectClass=" + DriverLocator.class.getName() + ")"; private static final String GLOBAL_FILTER = "(|" + LOG_FILTER + DEVICE_FILTER + DRIVER_FILTER + SELECTOR_FILTER + LOCATOR_FILTER + ")"; BundleContext bc; private boolean active; private boolean quit; private Filter isLog; private Filter isDevice; private Filter isDriver; private Filter isSelector; private Filter isLocator; private Vector /* DriverRef */drivers = new Vector(); private ServiceReference[] locatorRefs; DriverLocator[] locators; private ServiceReference selectorRef; private DriverSelector selector; private ServiceReference logRef; private LogService log; private Hashtable /* Integer->MatchValue */cache = new Hashtable(); private Hashtable /* ServiceReference->ServiceReference */newDevices = new Hashtable( 20); private Hashtable /* Bundle->Long */tempDrivers = new Hashtable(10); private long reapTime; public Activator() { super("DeviceManager"); } public void start(BundleContext bc) throws Exception { this.bc = bc; isLog = bc.createFilter(LOG_FILTER); isDevice = bc.createFilter(DEVICE_FILTER); isDriver = bc.createFilter(DRIVER_FILTER); isSelector = bc.createFilter(SELECTOR_FILTER); isLocator = bc.createFilter(LOCATOR_FILTER); startService(LOG_FILTER); start(); bc.addFrameworkListener(this); Bundle b = bc.getBundle(0); if (b.getState() == Bundle.ACTIVE) activate(); else info("Passive start"); } public void stop(BundleContext bc) { info("Stopping"); quit = true; synchronized (this) { notifyAll(); } } private synchronized void activate() throws Exception { if (active) return; active = true; info("Activating"); bc.addBundleListener(this); // Thanks to TID for combining the (buggy) // separate listeners into one startService(GLOBAL_FILTER); } public void frameworkEvent(FrameworkEvent e) { try { if (e.getType() == FrameworkEvent.STARTED) activate(); } catch (Exception e1) { } } private void startService(String filter) throws Exception { bc.addServiceListener(this, filter); ServiceReference[] sra = bc.getServiceReferences(null, filter); if (sra != null) { for (int i = 0; i < sra.length; i++) { try { serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sra[i])); } catch (Exception e) { } } } } public void serviceChanged(ServiceEvent e) { ServiceReference sr = e.getServiceReference(); if (isDevice.match(sr)) { switch (e.getType()) { case ServiceEvent.REGISTERED: info("device found, " + showDevice(sr)); touchDevice(sr); break; case ServiceEvent.MODIFIED: // We should most likely not do anything here // removeSRCachedMatch(sr); // touchDevice(sr); break; case ServiceEvent.UNREGISTERING: info("device lost, " + showDevice(sr)); removeSRCachedMatch(sr); break; } } if (isDriver.match(sr)) { try { switch (e.getType()) { case ServiceEvent.REGISTERED: info("driver found, " + showDriver(sr)); driverAppeared(sr); touchAllDevices(); break; case ServiceEvent.MODIFIED: // We should probably not do anything here // driverGone(sr); // driverAppeared(sr); break; case ServiceEvent.UNREGISTERING: info("driver lost, " + showDriver(sr)); driverGone(sr); touchAllDevices(); break; } } catch (Exception e1) { } } if (isSelector.match(sr)) { try { bc.ungetService(selectorRef); } catch (Exception e1) { } selector = null; try { selectorRef = bc.getServiceReference(DriverSelector.class .getName()); selector = (DriverSelector) bc.getService(selectorRef); } catch (Exception e1) { } } if (isLocator.match(sr)) { try { for (int i = 0; i < locatorRefs.length; i++) { bc.ungetService(locatorRefs[i]); } } catch (Exception e1) { } locatorRefs = null; locators = null; try { locatorRefs = bc.getServiceReferences(DriverLocator.class .getName(), null); locators = new DriverLocator[locatorRefs.length]; for (int i = 0; i < locatorRefs.length; i++) { locators[i] = (DriverLocator) bc.getService(locatorRefs[i]); } } catch (Exception e1) { } } if (isLog.match(sr)) { try { bc.ungetService(logRef); } catch (Exception e1) { } try { logRef = bc.getServiceReference(LogService.class.getName()); log = (LogService) bc.getService(logRef); } catch (Exception e1) { } } } private void driverAppeared(ServiceReference sr) { try { for (int i = 0; i < drivers.size(); i++) { DriverRef dr = (DriverRef) drivers.elementAt(i); if (dr.sr == sr) return; } DriverRef dr = new DriverRef(); try { dr.ranking = ((Integer) sr .getProperty(org.osgi.framework.Constants.SERVICE_RANKING)) .intValue(); } catch (Exception e) { } dr.servid = ((Long) sr .getProperty(org.osgi.framework.Constants.SERVICE_ID)) .longValue(); dr.id = (String) sr .getProperty(org.osgi.service.device.Constants.DRIVER_ID); dr.sr = sr; if (dr.id != null) dr.drv = (Driver) bc.getService(sr); else error("ignoring driver without id " + showDriver(sr)); if (dr.drv != null) drivers.addElement(dr); } catch (Exception e) { } } private void driverGone(ServiceReference sr) { try { for (int i = 0; i < drivers.size(); i++) { DriverRef dr = (DriverRef) drivers.elementAt(i); if (dr.sr == sr) { drivers.removeElementAt(i); return; } } } catch (Exception e) { } } public void bundleChanged(BundleEvent e) { if (e.getType() == BundleEvent.UNINSTALLED) { tempDrivers.remove(e.getBundle()); } } private void info(String msg) { try { log.log(LogService.LOG_INFO, msg); } catch (Exception e) { System.err.println("[Device Manager] info: " + msg); } } private void error(String msg) { try { log.log(LogService.LOG_ERROR, msg); } catch (Exception e) { System.err.println("[Device Manager] ERROR: " + msg); } } public void run() { while (!quit) { boolean sleep = true; try { ServiceReference dev = (ServiceReference) newDevices.keys() .nextElement(); newDevices.remove(dev); sleep = false; handleDevice(dev); } catch (Exception e) { } if (!sleep) continue; long now = System.currentTimeMillis(); if (now >= reapTime) { reapDrivers(); reapTime = now + REAP_INTERVAL; // NB: Should also clean out old matches every now // and then based on some kind of LRU scheme } synchronized (this) { if (!quit) try { wait(reapTime - now); } catch (Exception e) { } } } } private void handleDevice(ServiceReference dev) { if (isUsed(dev)) return; Dictionary props = collectProperties(dev); Vector /* MatchImpl */matches = new Vector(); // Populate matches with driver locator recommendations DriverLocator[] dla = locators;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -