This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git
The following commit(s) were added to refs/heads/master by this push:
new ef6eb56a6b Unmaintained code removal - wireadmin
ef6eb56a6b is described below
commit ef6eb56a6b9d40d7d969dbccb50997b284b8265d
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Tue Aug 22 17:53:37 2023 +0200
Unmaintained code removal - wireadmin
---
wireadmin/pom.xml | 70 --
.../java/org/apache/felix/wireadmin/Activator.java | 128 ---
.../org/apache/felix/wireadmin/EventManager.java | 269 -----
.../org/apache/felix/wireadmin/WireAdminImpl.java | 1037 --------------------
.../java/org/apache/felix/wireadmin/WireImpl.java | 955 ------------------
5 files changed, 2459 deletions(-)
diff --git a/wireadmin/pom.xml b/wireadmin/pom.xml
deleted file mode 100644
index 4a1ba6ed4c..0000000000
--- a/wireadmin/pom.xml
+++ /dev/null
@@ -1,70 +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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>org.apache.felix</groupId>
- <artifactId>felix-parent</artifactId>
- <version>1.2.0</version>
- <relativePath>../pom/pom.xml</relativePath>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <packaging>bundle</packaging>
- <name>Apache Felix Wire Admin</name>
- <artifactId>org.apache.felix.wireadmin</artifactId>
- <version>0.9.0-SNAPSHOT</version>
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>4.0.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <version>4.0.0</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>2.3.5</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Name>WireAdmin</Bundle-Name>
- <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
- <Bundle-Description>
- Implementation of the WireAdmin Service.
- </Bundle-Description>
- <Bundle-Activator>
- org.apache.felix.wireadmin.Activator
- </Bundle-Activator>
-
<Bundle-SymbolicName>org.apache.felix.wireadmin</Bundle-SymbolicName>
- <Private-Package>org.apache.felix.wireadmin.*</Private-Package>
- <Export-Package>org.osgi.service.wireadmin</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/wireadmin/src/main/java/org/apache/felix/wireadmin/Activator.java
b/wireadmin/src/main/java/org/apache/felix/wireadmin/Activator.java
deleted file mode 100644
index 7607ce2faf..0000000000
--- a/wireadmin/src/main/java/org/apache/felix/wireadmin/Activator.java
+++ /dev/null
@@ -1,128 +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.wireadmin;
-
-import java.util.Dictionary;
-import java.util.Properties;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.wireadmin.WireAdmin;
-import org.osgi.service.wireadmin.WireConstants;
-import org.osgi.service.wireadmin.WireAdminListener;
-import org.osgi.service.wireadmin.WireAdminEvent;
-/**
- * The activator
- *
- * @author <a href="mailto:[email protected]">Felix Project Team</a>
- */
-public class Activator implements BundleActivator {
-
- private final static String WIREADMIN_PID="org.apache.felix.wireadmin";
- private ServiceRegistration m_reg=null;
- private WireAdminImpl m_wai=null;
-
- /**
- * Called upon starting of the bundle.
- *
- * @param context The bundle context passed by the framework
- * @exception Exception
- */
- public void start(BundleContext bundleContext) throws BundleException {
-
- m_wai= new WireAdminImpl(bundleContext);
-
- // Register the service
- Dictionary properties=new Properties();
- properties.put(WireConstants.WIREADMIN_PID,WIREADMIN_PID);
- m_reg =
bundleContext.registerService(WireAdmin.class.getName(),m_wai,properties);
-
- // Event dispatching does not start until the reference is set
- m_wai.setServiceReference(m_reg.getReference());
-
- if(bundleContext.getProperty("fr.imag.adele.wireadmin.traceEvt") !=
null)
- {
- String value =
bundleContext.getProperty("fr.imag.adele.wireadmin.traceEvt");
- if(value.equals("true"))
- {
- Dictionary props=new Properties();
- props.put(WireConstants.WIREADMIN_EVENTS,new
Integer(0x80|0x40|0x20|0x10|0x08|0x04|0x02|0x01));
- properties.put(WireConstants.WIREADMIN_PID,WIREADMIN_PID);
-
bundleContext.registerService(WireAdminListener.class.getName(),new
eventTracer(),props);
- }
- }
- }
-
- /**
- * Called upon stopping the bundle.
- *
- * @param context The bundle context passed by the framework
- * @exception Exception
- */
- public void stop(BundleContext bundleContext) throws BundleException
- {
- m_wai.releaseAll();
- m_wai = null;
- }
-
- class eventTracer implements WireAdminListener
- {
- public void wireAdminEvent(WireAdminEvent evt)
- {
- int type = evt.getType();
- if((type & WireAdminEvent.WIRE_CREATED)!=0)
- {
- WireAdminImpl.traceln("Received event WIRE_CREATED");
- }
- if((type & WireAdminEvent.WIRE_CONNECTED)!=0)
- {
- WireAdminImpl.traceln("Received event WIRE_CONNECTED");
- }
- if((type & WireAdminEvent.WIRE_UPDATED)!=0)
- {
- WireAdminImpl.traceln("Received event WIRE_UPDATED");
- }
- if((type & WireAdminEvent.WIRE_TRACE)!=0)
- {
- WireAdminImpl.traceln("Received event WIRE_TRACE");
- }
- if((type & WireAdminEvent.WIRE_DISCONNECTED)!=0)
- {
- WireAdminImpl.traceln("Received event WIRE_DISCONNECTED");
- }
- if((type & WireAdminEvent.WIRE_DELETED)!=0)
- {
- WireAdminImpl.traceln("Received event WIRE_DELETED");
- }
- if((type & WireAdminEvent.PRODUCER_EXCEPTION)!=0)
- {
- WireAdminImpl.traceln("Received event PRODUCER_EXCEPTION");
- evt.getThrowable().printStackTrace();
- }
- if((type & WireAdminEvent.CONSUMER_EXCEPTION)!=0)
- {
- WireAdminImpl.traceln("Received event CONSUMER_EXCEPTION");
- evt.getThrowable().printStackTrace();
- }
- }
- }
-}
diff --git
a/wireadmin/src/main/java/org/apache/felix/wireadmin/EventManager.java
b/wireadmin/src/main/java/org/apache/felix/wireadmin/EventManager.java
deleted file mode 100644
index ed014d1edd..0000000000
--- a/wireadmin/src/main/java/org/apache/felix/wireadmin/EventManager.java
+++ /dev/null
@@ -1,269 +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.wireadmin;
-
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.BundleContext;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.osgi.service.wireadmin.WireAdminEvent;
-import org.osgi.service.wireadmin.WireAdminListener;
-import org.osgi.service.wireadmin.WireConstants;
-
-/**
- * Class that tracks listeners and manages event dispatching
- *
- * @author <a href="mailto:[email protected]">Felix Project Team</a>
- */
-class EventManager implements ServiceListener
-{
- // <ServiceReference,WireAdminListener>
- private Map m_wireAdminListeners = new HashMap();
-
- // The bundle context
- private BundleContext m_bundleContext;
-
- // Asynchronous dispatcher
- private AsyncDispatcher m_eventDispatcher = new AsyncDispatcher();
-
- // Service reference from the WireAdmin service
- private ServiceReference m_ref;
-
- /**
- * The constructor receives the bundle context and a service reference
- * corresponding to the wire admin service
- *
- * @param ctxt
- * @param ref
- */
- EventManager(BundleContext ctxt)
- {
- m_bundleContext = ctxt;
- ServiceReference [] serviceRefs = null;
-
- try
- {
-
m_bundleContext.addServiceListener(this,"(objectClass=org.osgi.service.wireadmin.WireAdminListener)");
- serviceRefs =
m_bundleContext.getServiceReferences(WireAdminListener.class.getName(),null);
- }
- catch(Exception ex)
- {
- // Exception never thrown since filter is correct
- }
-
- if(serviceRefs != null)
- {
- // lock the producers Map to avoid concurrent modifications due
- // to service events
- synchronized(m_wireAdminListeners)
- {
- for(int i=0;i<serviceRefs.length;i++)
- {
- ServiceReference
currentRef=(ServiceReference)serviceRefs[i];
-
-
m_wireAdminListeners.put(currentRef,m_bundleContext.getService(currentRef));
- }
- }
- }
- }
-
- /**
- * When the service reference is set the event dispatching thread is
- * started. This is necessary since events require m_ref to be set
- *
- * @param ref <tt>ServiceReference</tt> to the wire admin service.
- */
- void setServiceReference(ServiceReference ref)
- {
- m_ref = ref;
-
- // Activate thread that does asynchronous calls to
- // the producersConnected and consummersConnected methods
- new Thread(m_eventDispatcher).start();
- }
-
- /**
- * Stop the event manager
- *
- */
- void stop()
- {
- m_eventDispatcher.stop();
- }
-
- /**
- * Tracks Listener changes
- */
- public void serviceChanged(ServiceEvent e)
- {
- ServiceReference serviceRef = e.getServiceReference();
- switch (e.getType())
- {
- case ServiceEvent.REGISTERED:
- synchronized(m_wireAdminListeners)
- {
-
m_wireAdminListeners.put(serviceRef,m_bundleContext.getService(serviceRef));
- }
- break;
- case ServiceEvent.UNREGISTERING:
- synchronized(m_wireAdminListeners)
- {
- m_wireAdminListeners.remove(serviceRef);
- }
- break;
- case ServiceEvent.MODIFIED:
- // Not necessary
- break;
- }
- }
-
- /**
- * Fire an event
- *
- * @param eventType (see WireAdminEvent)
- * @param wire the wire
- */
- void fireEvent(int eventType,WireImpl wire)
- {
- fireEvent(eventType, wire, null);
- }
-
- /**
- * Fire an event that contains an exception
- *
- * @param eventType
- * @param wire
- * @param exception
- */
- void fireEvent(int eventType,WireImpl wire, Throwable exception)
- {
- WireAdminEvent evt = new
WireAdminEvent(m_ref,eventType,wire,exception);
- m_eventDispatcher.queueEvent(evt);
- }
-
- /**
- * p. 345 "A WireAdminEvent object can be sent asynchronously but must be
- * ordered for each WireAdminListener service"
- * But the API doc says "WireAdminEvent objects are delivered
asynchronously
- * to all registered WireAdminListener service objects which specify an
- * interest in the WireAdminEvent type."
- * We choose asynchronous delivery to be safe
- *
- **/
- class AsyncDispatcher implements Runnable
- {
- private boolean m_stop = false;
- private boolean m_empty = true;
-
- private List m_eventStack = new ArrayList();
-
- public void run()
- {
- while (m_stop == false || (m_stop == true && m_empty == false))
- {
- WireAdminEvent nextEvent = null;
-
- synchronized (m_eventStack)
- {
- while (m_eventStack.size() == 0)
- {
- try
- {
- m_eventStack.wait();
- }
- catch (InterruptedException ex)
- {
- // Ignore.
- }
- }
- nextEvent = (WireAdminEvent) m_eventStack.remove(0);
-
- if(m_eventStack.size()==0)
- {
- // This allows the queue to be flushed upon termination
- m_empty = true;
- }
- }
-
- synchronized (m_wireAdminListeners)
- {
- Iterator listenerIt =
m_wireAdminListeners.keySet().iterator();
- while(listenerIt.hasNext())
- {
- ServiceReference listenerRef =
(ServiceReference)listenerIt.next();
- WireAdminListener listener =
(WireAdminListener)m_wireAdminListeners.get(listenerRef);
-
- try
- {
- Integer evtsInteger = (Integer)
listenerRef.getProperty(WireConstants.WIREADMIN_EVENTS);
- if(evtsInteger != null)
- {
- int events = evtsInteger.intValue();
- if((nextEvent.getType()&events)!=0)
- {
- listener.wireAdminEvent(nextEvent);
- }
- }
- else
- {
- WireAdminImpl.trace(new Exception("Listener
with no WIREADMIN_EVENTS"+listenerRef));
- }
- }
- catch(ClassCastException ex)
- {
- WireAdminImpl.trace("Listener returned
WIREADMIN_EVENTS of wrong type:"+ex);
- }
- }
- }
- }
- }
-
- /**
- * Queue an event on the stack
- *
- * @param evt the event
- */
- public void queueEvent(WireAdminEvent evt)
- {
- synchronized (m_eventStack)
- {
- m_eventStack.add(evt);
- m_empty = false;
- m_eventStack.notify();
- }
- }
-
- /**
- * stop the dispatcher
- *
- */
- void stop()
- {
- m_stop = true;
- }
- }
-}
diff --git
a/wireadmin/src/main/java/org/apache/felix/wireadmin/WireAdminImpl.java
b/wireadmin/src/main/java/org/apache/felix/wireadmin/WireAdminImpl.java
deleted file mode 100644
index ef067e9de6..0000000000
--- a/wireadmin/src/main/java/org/apache/felix/wireadmin/WireAdminImpl.java
+++ /dev/null
@@ -1,1037 +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.wireadmin;
-
-import java.io.PrintStream;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Enumeration;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.wireadmin.Consumer;
-import org.osgi.service.wireadmin.Producer;
-import org.osgi.service.wireadmin.Wire;
-import org.osgi.service.wireadmin.WireAdmin;
-import org.osgi.service.wireadmin.WireConstants;
-import org.osgi.service.wireadmin.WireAdminEvent;
-
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-
-/**
- * Wire Administration service.
- *
- * <p>This service can be used to create <tt>Wire</tt> objects connecting
- * a Producer service and a Consumer service.
- * <tt>Wire</tt> objects also have wire properties that may be specified
- * when a <tt>Wire</tt> object is created. The Producer and Consumer
- * services may use the <tt>Wire</tt> object's properties to manage or control
their
- * interaction.
- * The use of <tt>Wire</tt> object's properties by a Producer or Consumer
- * services is optional.
- *
- * <p>Security Considerations.
- * A bundle must have <tt>ServicePermission[GET,WireAdmin]</tt> to get the
Wire Admin service to
- * create, modify, find, and delete <tt>Wire</tt> objects.
- *
- * @author <a href="mailto:[email protected]">Felix Project Team</a>
- */
-public class WireAdminImpl implements WireAdmin, ServiceListener {
-
- private BundleContext m_bundleContext;
-
- // A Map containing a service reference associated to a producer and a List
- // of wire objects
- private Map m_consumers = new HashMap(); /* ServiceReferences, List */
-
- private Map m_producers = new HashMap(); /* ServiceReferences, List */
-
- private List m_wires; // List containing the wires
-
- //private BindingController wireAdminListenersBindingController;
-
- // Filter corresponding to a consumer service
- private Filter m_consumerFilter;
-
- // Filter corresponding to a producer service
- private Filter m_producerFilter;
-
- // EventManager
- private EventManager m_eventManager;
-
- private static int m_wireCount = 0;
-
- private AsyncMethodCaller m_asyncMethodCaller = new AsyncMethodCaller();
//m_eventDispatcher.stop();
-
- private static PrintStream m_traceout = null;
-
- private static PrintStream m_errorout = System.err;
-
- /**
- * Constructor with package visibility
- *
- * @param bundleContext the bundle context
- */
- WireAdminImpl(BundleContext bundleContext)
- {
- m_bundleContext = bundleContext;
-
- if(bundleContext.getProperty("fr.imag.adele.wireadmin.trace") != null)
- {
- String value =
bundleContext.getProperty("fr.imag.adele.wireadmin.trace");
- if(value.equals("true"))
- {
- m_traceout = System.out;
- }
- }
- // Create the event manager (the event manager will start its own
thread)
- m_eventManager = new EventManager(m_bundleContext);
-
- try
- {
- m_producerFilter = m_bundleContext.createFilter(
-
"(objectClass=org.osgi.service.wireadmin.Producer)");
- m_consumerFilter = m_bundleContext.createFilter(
-
"(objectClass=org.osgi.service.wireadmin.Consumer)");
- }
- catch (InvalidSyntaxException e)
- {
- // never thrown since LDAP expressions are correct
- }
-
- // Recover persistent wires
- getPersistentWires();
-
- // Activate thread that does asynchronous calls to
- // the producersConnected and consummersConnected methods
- new Thread(m_asyncMethodCaller).start();
-
- // Gets all producers and consumers that are present at the
- // moment the wire admin is created
- try
- {
- // Registration for events must be done first, as some service
- // can be registered during initialization
-
-
m_bundleContext.addServiceListener(this,"(|"+m_producerFilter.toString()+m_consumerFilter.toString()+")");
-
- // Replacement for the two following lines which work under OSCAR,
- // but not work under IBM's SMF
-
//m_bundleContext.addServiceListener(this,m_consumerFilter.toString());
-
//m_bundleContext.addServiceListener(this,m_producerFilter.toString());
-
- // Get all producers
- ServiceReference[] producerRefs =
m_bundleContext.getServiceReferences(Producer.class.getName(),null);
-
- if(producerRefs!=null)
- {
- // lock the producers Map to avoid concurrent modifications due
- // to service events
- synchronized(m_producers)
- {
- for(int i=0;i<producerRefs.length;i++)
- {
- ServiceReference
currentRef=(ServiceReference)producerRefs[i];
-
- Iterator wireIt = m_wires.iterator();
- while(wireIt.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIt.next();
-
if(currentWire.getProducerPID().equals(currentRef.getProperty(Constants.SERVICE_PID)))
- {
- currentWire.bindProducer(currentRef);
- }
- }
- m_producers.put(currentRef,new ArrayList());
- }
- }
- }
-
- // Get all the consumers
- ServiceReference[] consumerRefs =
m_bundleContext.getServiceReferences(Consumer.class.getName(),null);
-
- if(consumerRefs!=null)
- {
- for(int i=0;i<consumerRefs.length;i++)
- {
- // lock the consumers to avoid concurrent modifications due
- // to service events
- synchronized(m_consumers)
- {
- ServiceReference
currentRef=(ServiceReference)consumerRefs[i];
-
- Iterator wireIt = m_wires.iterator();
- while(wireIt.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIt.next();
-
if(currentWire.getConsumerPID().equals(currentRef.getProperty(Constants.SERVICE_PID)))
- {
- currentWire.bindConsumer(currentRef);
- }
- }
- m_consumers.put(currentRef,new ArrayList());
- }
- }
- }
- }
- catch (InvalidSyntaxException e)
- {
- trace(e);
- }
-
- // Iterate over all the wires, when a wire is connected
- // add it to the list of wires associated to a particular
- // producer or consumer
- synchronized(m_wires)
- {
- Iterator wireIterator = m_wires.iterator();
- while(wireIterator.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIterator.next();
- if(currentWire.isConnected())
- {
- // p. 327 "If both Producer and consumer services are
registered
- // with the framework, they are connected by the WireAdmin
service"
- List wires = (List)
m_producers.get(currentWire.getProducerServiceRef());
- wires.add(currentWire);
-
m_asyncMethodCaller.consumersConnected(currentWire.getProducer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
-
- wires = (List)
m_consumers.get(currentWire.getConsumerServiceRef());
- wires.add(currentWire);
-
m_asyncMethodCaller.producersConnected(currentWire.getConsumer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
- }
- }
- }
- }
-
- /**
- * Pass the service reference to the event dispatcher
- *
- * @param ref the service reference
- */
- void setServiceReference(ServiceReference ref)
- {
- m_eventManager.setServiceReference(ref);
- }
-
- /**
- * Create a new <tt>Wire</tt> object that connects a Producer
- * service to a Consumer service.
- *
- * The Producer service and Consumer service do not
- * have to be registered when the <tt>Wire</tt> object is created.
- *
- * <p>The <tt>Wire</tt> configuration data must be persistently stored.
- * All <tt>Wire</tt> connections are reestablished when the
- * <tt>WireAdmin</tt> service is registered.
- * A <tt>Wire</tt> can be permanently removed by using the
- * {@link #deleteWire} method.
- *
- * <p>The <tt>Wire</tt> object's properties must have case
- * insensitive <tt>String</tt> objects as keys (like the Framework).
- * However, the case of the key must be preserved.
- * The type of the value of the property must be one of the following:
- *
- * <pre>
- * type = basetype
- * | vector | arrays
- *
- * basetype = String | Integer | Long
- * | Float | Double | Byte
- * | Short | Character
- * | Boolean
- *
- * primitive = long | int | short
- * | char | byte | double | float
- *
- * arrays = primitive '[]' | basetype '[]'
- *
- * vector = Vector of basetype
- * </pre>
- *
- * <p>The <tt>WireAdmin</tt> service must automatically add the
- * following <tt>Wire</tt> properties:
- * <ul>
- * <li>
- * {@link WireConstants#WIREADMIN_PID} set to the value of the
<tt>Wire</tt> object's
- * persistent identity (PID). This value is generated by the
- * Wire Admin service when a <tt>Wire</tt> object is created.
- * </li>
- * <li>
- * {@link WireConstants#WIREADMIN_PRODUCER_PID} set to the value of
- * Producer service's PID.
- * </li>
- * <li>
- * {@link WireConstants#WIREADMIN_CONSUMER_PID} set to the value of
- * Consumer service's PID.
- * </li>
- * </ul>
- * If the <tt>properties</tt> argument
- * already contains any of these keys, then the supplied values
- * are replaced with the values assigned by the Wire Admin service.
- *
- * <p>The Wire Admin service must broadcast a <tt>WireAdminEvent</tt>
of type
- * {@link WireAdminEvent#WIRE_CREATED}
- * after the new <tt>Wire</tt> object becomes available from {@link
#getWires}.
- *
- * @param producerPID The <tt>service.pid</tt> of the Producer service
- * to be connected to the <tt>Wire</tt> object.
- * @param consumerPID The <tt>service.pid</tt> of the Consumer service
- * to be connected to the <tt>Wire</tt> object.
- * @param properties The <tt>Wire</tt> object's properties. This
argument may be <tt>null</tt>
- * if the caller does not wish to define any <tt>Wire</tt> object's
properties.
- * @return The <tt>Wire</tt> object for this connection.
- * @throws java.lang.IllegalArgumentException If
- * <tt>properties</tt> contains case variants of the same key name.
- */
- public Wire createWire(String producerPID, String consumerPID,
Dictionary props)
- {
- ServiceReference producerServiceRef = null;
- ServiceReference consumerServiceRef = null;
-
- Dictionary properties;
-
- if(props == null)
- {
- properties = new Hashtable();
- }
- else
- {
- //Clone the dictionary
- properties = cloneProperties(props);
- }
-
- // Addition of mandatory properties
- properties.put(WireConstants.WIREADMIN_CONSUMER_PID, consumerPID);
- properties.put(WireConstants.WIREADMIN_PRODUCER_PID, producerPID);
- properties.put(WireConstants.WIREADMIN_PID, generateWirePID());
-
- // p.327 "Wire objects can be created when the producer or consumer
- // service is not registered
- WireImpl wire = new WireImpl(producerPID, consumerPID, properties);
-
- // Initialize the wire
- wire.initialize(m_bundleContext,m_eventManager);
-
- // Add the wire to the list
- synchronized(m_wires)
- {
- m_wires.add(wire);
- }
-
- // p. 357 "The Wire Admin service must broadcast a WireAdminEvent of
- // type WireAdminEvent.WIRE_CREATED after the new Wire object becomes
- // available from getWires(java.lang.String)."
- m_eventManager.fireEvent(WireAdminEvent.WIRE_CREATED,wire);
-
- synchronized (m_producers)
- {
- Iterator producerIterator = m_producers.keySet().iterator();
- while(producerIterator.hasNext())
- {
- producerServiceRef = (ServiceReference)
producerIterator.next();
- if
(producerServiceRef.getProperty(Constants.SERVICE_PID).equals(producerPID))
- {
- wire.bindProducer(producerServiceRef);
- break;
- }
- }
- }
-
- synchronized (m_consumers)
- {
- Iterator consumerIterator = m_consumers.keySet().iterator();
- while(consumerIterator.hasNext())
- {
- consumerServiceRef = (ServiceReference)
consumerIterator.next();
- if
(consumerServiceRef.getProperty(Constants.SERVICE_PID).equals(consumerPID))
- {
- wire.bindConsumer(consumerServiceRef);
- break;
- }
-
- }
- }
-
-
- // p.327 If both Producer and Consumer services are registered, they
are
- // connected by the wire admin service.
- if(wire.isConnected())
- {
- List wires = (List) m_producers.get(producerServiceRef);
- wires.add(wire);
-
m_asyncMethodCaller.consumersConnected(wire.getProducer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
-
- wires = (List) m_consumers.get(consumerServiceRef);
- wires.add(wire);
-
m_asyncMethodCaller.producersConnected(wire.getConsumer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
- }
-
- // Newly created wires are immediately persisted to avoid information
- // loss in case of crashes. (spec not clear about this)
- persistWires();
-
- return wire;
- }
-
- /**
- * Delete a <tt>Wire</tt> object.
- *
- * <p>The <tt>Wire</tt> object representing a connection between
- * a Producer service and a Consumer service must be
- * removed.
- * The persistently stored configuration data for the <tt>Wire</tt>
object
- * must destroyed. The <tt>Wire</tt> object's method {@link
Wire#isValid} will return <tt>false</tt>
- * after it is deleted.
- *
- * <p>The Wire Admin service must broadcast a <tt>WireAdminEvent</tt>
of type
- * {@link WireAdminEvent#WIRE_DELETED}
- * after the <tt>Wire</tt> object becomes invalid.
- *
- * @param wire The <tt>Wire</tt> object which is to be deleted.
- */
- public void deleteWire(Wire wire)
- {
- if(m_wires.contains(wire))
- {
- WireImpl wireImpl = (WireImpl) wire;
- m_wires.remove(wire);
- if(wireImpl.isConnected())
- {
- List wires = (List)
m_producers.get(wireImpl.getProducerServiceRef());
- wires.remove(wireImpl);
-
m_asyncMethodCaller.consumersConnected(wireImpl.getProducer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
-
- wires = (List)
m_consumers.get(wireImpl.getConsumerServiceRef());
- wires.remove(wireImpl);
-
m_asyncMethodCaller.producersConnected(wireImpl.getConsumer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
- }
-
- wireImpl.invalidate();
-
- // fire an event
- m_eventManager.fireEvent(WireAdminEvent.WIRE_DELETED,wireImpl);
-
- // Persist state to avoid losses in case of crashes (spec not
clear about this).
- persistWires();
- }
- else
- {
- traceln("WireAdminImpl: Cannot delete a wire that is not managed
by this service");
- }
-
- }
-
- /**
- * Update the properties of a <tt>Wire</tt> object.
- *
- * The persistently stored configuration data for the <tt>Wire</tt>
object
- * is updated with the new properties and then the Consumer and Producer
- * services will be called at the respective {@link
Consumer#producersConnected}
- * and {@link Producer#consumersConnected} methods.
- *
- * <p>The Wire Admin service must broadcast a <tt>WireAdminEvent</tt>
of type
- * {@link WireAdminEvent#WIRE_UPDATED}
- * after the updated properties are available from the <tt>Wire</tt>
object.
- *
- * @param wire The <tt>Wire</tt> object which is to be updated.
- * @param properties The new <tt>Wire</tt> object's properties or
<tt>null</tt> if no properties are required.
- */
- public void updateWire(Wire wire, Dictionary props)
- {
- if(m_wires.contains(wire) == false)
- {
- traceln("WireAdminImpl: Cannot update a wire that is not managed
by this service");
- return;
- }
-
- // Clone the dictionary
- Dictionary properties = cloneProperties(props);
-
- // Put again the mandatory properties, in case they are not set
-
properties.put(WireConstants.WIREADMIN_CONSUMER_PID,wire.getProperties().get(WireConstants.WIREADMIN_CONSUMER_PID));
-
properties.put(WireConstants.WIREADMIN_PRODUCER_PID,wire.getProperties().get(WireConstants.WIREADMIN_PRODUCER_PID));
-
properties.put(WireConstants.WIREADMIN_PID,wire.getProperties().get(WireConstants.WIREADMIN_PID));
-
- WireImpl wireImpl = (WireImpl) wire;
-
- wireImpl.updateProperties(properties);
-
- // Call methods on Consumer and Producer
- if(wireImpl.isConnected())
- {
- List wires = (List)
m_producers.get(wireImpl.getProducerServiceRef());
-
m_asyncMethodCaller.consumersConnected(wireImpl.getProducer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
-
- wires = (List) m_consumers.get(wireImpl.getConsumerServiceRef());
-
m_asyncMethodCaller.producersConnected(wireImpl.getConsumer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
- }
-
- // fire an event
- m_eventManager.fireEvent(WireAdminEvent.WIRE_UPDATED,wireImpl);
- }
-
- /**
- * Return the <tt>Wire</tt> objects that match the given
<tt>filter</tt>.
- *
- * <p>The list of available <tt>Wire</tt> objects is matched against the
- * specified <tt>filter</tt>. <tt>Wire</tt> objects which match the
- * <tt>filter</tt> must be returned. These <tt>Wire</tt> objects are
not necessarily
- * connected. The Wire Admin service should not return
- * invalid <tt>Wire</tt> objects, but it is possible that a
<tt>Wire</tt>
- * object is deleted after it was placed in the list.
- *
- * <p>The filter matches against the <tt>Wire</tt> object's properties
including
- * {@link WireConstants#WIREADMIN_PRODUCER_PID}, {@link
WireConstants#WIREADMIN_CONSUMER_PID}
- * and {@link WireConstants#WIREADMIN_PID}.
- *
- * @param filter Filter string to select <tt>Wire</tt> objects
- * or <tt>null</tt> to select all <tt>Wire</tt> objects.
- * @return An array of <tt>Wire</tt> objects which match the
<tt>filter</tt>
- * or <tt>null</tt> if no <tt>Wire</tt> objects match the
<tt>filter</tt>.
- * @throws org.osgi.framework.InvalidSyntaxException If the specified
<tt>filter</tt>
- * has an invalid syntax.
- * @see org.osgi.framework.Filter
- */
- public Wire[] getWires(String filter) throws InvalidSyntaxException
- {
- List res = null;
- if (filter == null)
- {
- return (Wire [])m_wires.toArray(new Wire[m_wires.size()]);
- }
- else
- {
- Filter tempFilter =
m_bundleContext.createFilter(filter);
- Iterator iter = m_wires.iterator();
- while (iter.hasNext())
- {
- WireImpl currentWire = (WireImpl) iter.next();
- if
(tempFilter.match(currentWire.getProperties()))
- {
- if (res == null)
- {
- res = new ArrayList();
- }
- res.add(currentWire);
- }
- }
- }
- if (res == null)
- {
- return null;
- }
- else
- {
- return (Wire [])res.toArray(new Wire[res.size()]);
- }
- }
-
- /**
- * listens Producer and Consumer services changes
- * @see
org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
- */
- public void serviceChanged(ServiceEvent e)
- {
- ServiceReference serviceRef = e.getServiceReference();
- // A consumer service changed
- if (m_consumerFilter.match(serviceRef))
- {
- switch (e.getType())
- {
- case ServiceEvent.REGISTERED :
- traceln("consumer registered");
-
- List wires = new ArrayList();
-
- synchronized(m_consumers)
- {
- m_consumers.put(serviceRef,wires);
- }
- synchronized(m_wires)
- {
- Iterator wireIt = m_wires.iterator();
- boolean called = false;
- // Iterate over all existing wires
- while(wireIt.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIt.next();
-
-
if(currentWire.getConsumerPID().equals(serviceRef.getProperty(Constants.SERVICE_PID)))
- {
- // This wire is associated to the newly
arrived consumer
- currentWire.bindConsumer(serviceRef);
- if(currentWire.isConnected())
- {
- // The wire has been connected, both
producer and consumer
- // must be updated
- wires.add(currentWire);
- called = true;
-
m_asyncMethodCaller.producersConnected(currentWire.getConsumer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
- List producerWires = (List)
m_producers.get(currentWire.getProducerServiceRef());
- producerWires.add(currentWire);
-
m_asyncMethodCaller.consumersConnected(currentWire.getProducer(),(Wire[])producerWires.toArray(new
Wire[producerWires.size()]));
- }
- }
- }
- if(!called)
- {
- // P. 329 "If the Consumer service has no Wire
objects attached when it
- // is registered, the WireAdmin service must
always call producersConnected(null)
- m_asyncMethodCaller.producersConnected((Consumer)
m_bundleContext.getService(serviceRef),null);
- }
- }
- break;
- case ServiceEvent.UNREGISTERING :
- traceln("consumer unregistering");
-
- synchronized(m_consumers)
- {
- m_consumers.remove(serviceRef);
- }
- synchronized(m_wires)
- {
- Iterator wireIt = m_wires.iterator();
- while(wireIt.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIt.next();
-
if(currentWire.getConsumerPID().equals(serviceRef.getProperty(Constants.SERVICE_PID)))
- {
- // p. 328 "When a Consumer or Producer service
is unregistered
- // from the OSGi framework, the other object
in the association
- // is informed that the Wire object is no
longer valid"
-
- if(currentWire.isConnected())
- {
- currentWire.unbindConsumer();
- List producerWires = (List)
m_producers.get(currentWire.getProducerServiceRef());
- producerWires.remove(currentWire);
-
m_asyncMethodCaller.consumersConnected(currentWire.getProducer(),(Wire[])producerWires.toArray(new
Wire[producerWires.size()]));
- }
- else
- {
- currentWire.unbindConsumer();
- }
- }
- }
- }
- break;
- case ServiceEvent.MODIFIED :
- // TODO Respond to consumer service modification
- traceln("consumer service modified");
- break;
-
- }
- }
- // Removed else to manage services which are both producers AND
consumers
- if (m_producerFilter.match(serviceRef))
- {
- switch (e.getType())
- {
- case ServiceEvent.REGISTERED :
- traceln("producer registered");
-
- List wires = new ArrayList();
-
- synchronized(m_producers)
- {
- m_producers.put(serviceRef,wires);
- }
- synchronized(m_wires)
- {
- Iterator wireIt = m_wires.iterator();
- boolean called = false;
- // Iterate over all existing wires
- while(wireIt.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIt.next();
-
if(currentWire.getProducerPID().equals(serviceRef.getProperty(Constants.SERVICE_PID)))
- {
- // This wire is associated to the newly
arrived producer
- currentWire.bindProducer(serviceRef);
- if(currentWire.isConnected())
- {
- // The wire has been connected, both
producer and consumer
- // must be updated
- wires.add(currentWire);
- called = true;
-
m_asyncMethodCaller.consumersConnected(currentWire.getProducer(),(Wire[])wires.toArray(new
Wire[wires.size()]));
- List consumerWires = (List)
m_consumers.get(currentWire.getConsumerServiceRef());
- consumerWires.add(currentWire);
-
m_asyncMethodCaller.producersConnected(currentWire.getConsumer(),(Wire[])consumerWires.toArray(new
Wire[consumerWires.size()]));
- }
- }
- }
- if(!called)
- {
- // P. 329 "If the Producer service has no Wire
objects attached when it
- // is registered, the WireAdmin service must
always call consumersConnected(null)
- m_asyncMethodCaller.consumersConnected((Producer)
m_bundleContext.getService(serviceRef),null);
- }
- }
- break;
- case ServiceEvent.UNREGISTERING :
- traceln("Producer unregistering");
-
- synchronized(m_producers)
- {
- m_producers.remove(serviceRef);
- }
- synchronized(m_wires)
- {
- Iterator wireIt = m_wires.iterator();
- while(wireIt.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIt.next();
-
if(currentWire.getProducerPID().equals(serviceRef.getProperty(Constants.SERVICE_PID)))
- {
- // p. 328 "When a Consumer or Producer service
is unregistered
- // from the OSGi framework, the other object
in the association
- // is informed that the Wire object is no
longer valid"
-
- if(currentWire.isConnected())
- {
- currentWire.unbindProducer();
- List consumerWires = (List)
m_consumers.get(currentWire.getConsumerServiceRef());
- consumerWires.remove(currentWire);
-
m_asyncMethodCaller.producersConnected(currentWire.getConsumer(),(Wire[])consumerWires.toArray(new
Wire[consumerWires.size()]));
- }
- else
- {
- currentWire.unbindProducer();
- }
- }
- }
- }
- break;
- case ServiceEvent.MODIFIED :
- // TODO Respond to producer service modification
- traceln("producer service modified");
- break;
- }
- }
- }
-
-
- /**
- * release all references before stop
- */
- synchronized void releaseAll()
- {
- Iterator wireIt = m_wires.iterator();
- while(wireIt.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIt.next();
- currentWire.invalidate();
- }
-
- Iterator producerIt = m_producers.keySet().iterator();
- while (producerIt.hasNext())
- {
- ServiceReference producerRef = (ServiceReference)
producerIt.next();
-
((Producer)m_bundleContext.getService(producerRef)).consumersConnected(null);
- }
-
- Iterator consumerIt = m_consumers.keySet().iterator();
- while (consumerIt.hasNext())
- {
- ServiceReference consumerRef = (ServiceReference)
consumerIt.next();
-
((Consumer)m_bundleContext.getService(consumerRef)).producersConnected(null);
- }
-
- // Stop the thread
- m_asyncMethodCaller.stop();
-
- // Notify the event manager so that it stops its thread
- m_eventManager.stop();
-
- persistWires();
-
- }
-
- /**
- * This method generates a PID. The pid is generated from the bundle id,
- * a hash code from the current time and a counter.
- *
- * @return a wire PID
- */
- private String generateWirePID()
- {
- Date d = new Date();
- String
PID="wire."+m_bundleContext.getBundle().getBundleId()+d.hashCode()+m_wireCount;
- m_wireCount ++;
-
- // Maybe the counter should go above 9?
- if(m_wireCount>9)
- {
- m_wireCount = 0;
- }
- return PID;
- }
-
- /**
- * Recover persistent wires
- *
- */
- private void getPersistentWires()
- {
-
- try
- {
- ObjectInputStream ois = new ObjectInputStream(new
FileInputStream(m_bundleContext.getDataFile("wires.ser")));
- m_wires = (ArrayList) ois.readObject();
- ois.close();
- if(m_wires!=null)
- {
- traceln("Deserialized "+m_wires.size()+" wires");
- Iterator wireIt = m_wires.iterator();
- while(wireIt.hasNext())
- {
- WireImpl currentWire = (WireImpl) wireIt.next();
- currentWire.initialize(m_bundleContext,m_eventManager);
- }
- }
- else
- {
- traceln("Couldn't Deserialize wires");
- m_wires = new ArrayList();
- }
- }
- catch(FileNotFoundException ex)
- {
- // do not show anything as this exception is thrown every
- // time the wire admin service is launched for the first
- // time
- m_wires = new ArrayList();
- }
- catch(Exception ex)
- {
- trace(ex);
- m_wires = new ArrayList();
- }
- }
-
- /**
- * Persist existing wires
- *
- */
- private void persistWires()
- {
- try
- {
- ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream(m_bundleContext.getDataFile("wires.ser")));
- oos.writeObject(m_wires);
- oos.close();
- traceln("Serialized "+m_wires.size()+" wires");
- }
- catch(Exception ex)
- {
- trace(ex);
- }
- }
-
- /**
- * print an error
- * @param message message to error
- */
- static void error(String message)
- {
- if (m_errorout != null)
- {
- m_errorout.println(message);
- }
- }
-
- /**
- * print a trace
- * @param message message to trace
- */
- static void traceln(String message)
- {
- if (m_traceout != null)
- {
- trace(message);
- trace("\n");
- }
- }
-
- /**
- * print a trace
- * @param message message to trace
- */
- static void trace(String message)
- {
- if (m_traceout != null)
- {
- m_traceout.print(message);
- }
- }
- /**
- * print a trace
- * @param e exception to trace
- */
- static void trace(Exception e)
- {
- if (m_traceout != null)
- {
- e.printStackTrace(m_traceout);
- }
- }
-
- /**
- * Clone a dictionary
- *
- * @param dictionary The dictionary to clone
- * @return a copy of the dicionary
- */
- private Dictionary cloneProperties(Dictionary dictionary){
- Dictionary properties=new Hashtable();
-
- if (dictionary == null) {
- properties = new Hashtable();
- } else {
- Enumeration enumeration=dictionary.keys();
- while(enumeration.hasMoreElements()){
- Object key=enumeration.nextElement();
- Object value=dictionary.get(key);
- properties.put(key,value);
- }
- }
-
- return properties;
- }
-
- /**
- * This class enables calls to Producer.consumersConnected and
Consumer.producersConnected
- * to be done asynchronously
- *
- * p.333 "The WireAdmin service can call the consumersConnected or
producersConnected
- * methods during the registration of the consumer of producer service"
- *
- **/
- class AsyncMethodCaller implements Runnable
- {
- private boolean m_stop = false;
-
- private List m_methodCallStack = new ArrayList();
-
- public void run()
- {
- while (!m_stop)
- {
- Object nextTarget[] = null;
-
- synchronized (m_methodCallStack)
- {
- while (m_methodCallStack.size() == 0)
- {
- try
- {
- m_methodCallStack.wait();
- }
- catch (InterruptedException ex)
- {
- // Ignore.
- }
- }
- nextTarget = (Object[]) m_methodCallStack.remove(0);
- }
-
- if(nextTarget[0] instanceof Producer)
- {
- try
- {
-
((Producer)nextTarget[0]).consumersConnected((Wire[])nextTarget[1]);
- }
- catch(Exception ex)
- {
- trace(ex);
- }
- }
- // Removed else because nextTarget can be both producer and
consumer
- if(nextTarget[0] instanceof Consumer)
- {
- try
- {
-
((Consumer)nextTarget[0]).producersConnected((Wire[])nextTarget[1]);
- }
- catch(Exception ex)
- {
- trace(ex);
- }
- }
- }
- }
-
- /**
- * Place a call to Consumer.producersConnected on the stack
- *
- * @param c the consumer
- * @param wires the wires
- */
- public void producersConnected(Consumer c,Wire []wires)
- {
- synchronized (m_methodCallStack)
- {
- m_methodCallStack.add(new Object[]{c,wires});
- m_methodCallStack.notify();
- }
- }
-
- /**
- * Place a call to Producer.consumersConnected on the stack
- *
- * @param p the producer
- * @param wires the wires
- */
- public void consumersConnected(Producer p,Wire []wires)
- {
- synchronized (m_methodCallStack)
- {
- m_methodCallStack.add(new Object[]{p,wires});
- m_methodCallStack.notify();
- }
- }
-
- /**
- * stop the dispatcher
- *
- */
- void stop()
- {
- m_stop = true;
- }
- }
-}
diff --git a/wireadmin/src/main/java/org/apache/felix/wireadmin/WireImpl.java
b/wireadmin/src/main/java/org/apache/felix/wireadmin/WireImpl.java
deleted file mode 100644
index 25bd78e932..0000000000
--- a/wireadmin/src/main/java/org/apache/felix/wireadmin/WireImpl.java
+++ /dev/null
@@ -1,955 +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.wireadmin;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Vector;
-import java.util.Date;
-
-import org.osgi.framework.Filter;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import org.osgi.service.wireadmin.Consumer;
-import org.osgi.service.wireadmin.Producer;
-import org.osgi.service.wireadmin.Wire;
-import org.osgi.service.wireadmin.WireConstants;
-import org.osgi.service.wireadmin.WireAdminEvent;
-
-/**
- * A connection between a Producer service and a Consumer service.
- *
- * <p>A <tt>Wire</tt> object connects a Producer service
- * to a Consumer service.
- * Both the Producer and Consumer services are identified
- * by their unique <tt>service.pid</tt> values.
- * The Producer and Consumer services may communicate with
- * each other via <tt>Wire</tt> objects that connect them.
- * The Producer service may send updated values to the
- * Consumer service by calling the {@link #update} method.
- * The Consumer service may request an updated value from the
- * Producer service by calling the {@link #poll} method.
- *
- * <p>A Producer service and a Consumer service may be
- * connected through multiple <tt>Wire</tt> objects.
- *
- * <p>Security Considerations. <tt>Wire</tt> objects are available to
- * Producer and Consumer services connected to a given
- * <tt>Wire</tt> object and to bundles which can access the <tt>WireAdmin</tt>
service.
- * A bundle must have <tt>ServicePermission[GET,WireAdmin]</tt> to get the
<tt>WireAdmin</tt> service to
- * access all <tt>Wire</tt> objects.
- * A bundle registering a Producer service or a Consumer service
- * must have the appropriate
<tt>ServicePermission[REGISTER,Consumer|Producer]</tt> to register the service
and
- * will be passed <tt>Wire</tt> objects when the service object's
- * <tt>consumersConnected</tt> or <tt>producersConnected</tt> method is called.
- *
- * <p>Scope. Each Wire object can have a scope set with the <tt>setScope</tt>
method. This
- * method should be called by a Consumer service when it assumes a Producer
service that is
- * composite (supports multiple information items). The names in the scope
must be
- * verified by the <tt>Wire</tt> object before it is used in communication.
The semantics of the
- * names depend on the Producer service and must not be interpreted by the
Wire Admin service.
- *
- * @author <a href="mailto:[email protected]">Felix Project Team</a> *
- */
-public class WireImpl implements Wire, java.io.Serializable
-{
- static final long serialVersionUID = -3637966367104019136L;
-
- // Persistent attributes
-
- // p. 327 "The Wire admin object contains a Persistend Identity (PID) for
- // a consumer service and a PID for a producer service" These properties
- // are also contained in the dictionary, but they are stored to optimize
- // access.
- private String m_producerPID;
- private String m_consumerPID;
-
- private Dictionary m_properties;
-
- // Transient attributes
-
- transient private boolean m_isValid = true;
- transient private boolean m_isConnected = false;
- transient private Filter m_filter = null;
-
- transient private ServiceReference m_producerServiceRef;
- transient private Producer m_producer;
- transient private boolean m_producerIsComposite = false;
- transient private String [] m_producerScope = null;
-
- transient private ServiceReference m_consumerServiceRef;
- transient private Consumer m_consumer;
- transient private boolean m_consumerIsComposite = false;
- transient private String [] m_consumerScope = null;
-
- transient private BundleContext m_bundleContext;
- transient private EventManager m_eventManager;
- transient private Object m_lastValue;
- transient private String[] m_scope;
-
- transient private long m_lastUpdate;
- transient private boolean m_isFirstUpdate;
- transient FilterDictionary m_dictionary;
-
- /**
- * Constructor with package visibility
- *
- * @param producerPID
- * @param consumerPID
- * @param properties
- */
- WireImpl(String producerPID, String consumerPID, Dictionary properties)
- {
- m_producerPID = producerPID;
- m_consumerPID = consumerPID;
- m_properties = properties;
-
- // set the scope which is the intersection of strings in the
WIREADMIN_PRODUCER_SCOPE properties and the strings in the
WIREADMIN_CONSUMER_SCOPE
- m_scope = null;
- }
-
- /**
- * Method called after construction and after deserialization
- *
- * @param ctxt
- * @param eventManager
- */
- void initialize(BundleContext ctxt, EventManager eventManager)
- {
- m_isValid = true;
- m_isConnected = false;
-
- m_bundleContext = ctxt;
- m_eventManager = eventManager;
-
- m_lastValue = null;
-
- m_lastUpdate = 0;
-
- m_isFirstUpdate = true;
-
- /*
- if(m_date == null)
- {
- m_date = new Date();
- }
- */
- m_dictionary = new FilterDictionary();
- }
-
- /**
- * Return the state of this <tt>Wire</tt> object.
- *
- * <p>A connected <tt>Wire</tt> must always be disconnected before
- * becoming invalid.
- *
- * @return <tt>false</tt> if this <tt>Wire</tt> object is invalid
because it
- * has been deleted via {@link WireAdmin#deleteWire};
- * <tt>true</tt> otherwise.
- */
- public boolean isValid()
- {
- return m_isValid;
- }
-
- /**
- * Return the connection state of this <tt>Wire</tt> object.
- *
- * <p>A <tt>Wire</tt> is connected after the Wire Admin service receives
- * notification that the Producer service and
- * the Consumer service for this <tt>Wire</tt> object are both
registered.
- * This method will return <tt>true</tt> prior to notifying the Producer
- * and Consumer services via calls
- * to their respective <tt>consumersConnected</tt> and
<tt>producersConnected</tt>
- * methods.
- * <p>A <tt>WireAdminEvent</tt> of type {@link
WireAdminEvent#WIRE_CONNECTED}
- * must be broadcast by the Wire Admin service when
- * the <tt>Wire</tt> becomes connected.
- *
- * <p>A <tt>Wire</tt> object
- * is disconnected when either the Consumer or Producer
- * service is unregistered or the <tt>Wire</tt> object is deleted.
- * <p>A <tt>WireAdminEvent</tt> of type {@link
WireAdminEvent#WIRE_DISCONNECTED}
- * must be broadcast by the Wire Admin service when
- * the <tt>Wire</tt> becomes disconnected.
- *
- * @return <tt>true</tt> if both the Producer and Consumer
- * for this <tt>Wire</tt> object are connected to the <tt>Wire</tt>
object;
- * <tt>false</tt> otherwise.
- */
- public boolean isConnected()
- {
- return m_isConnected;
- }
-
- /**
- * Return the list of data types understood by the
- * Consumer service connected to this <tt>Wire</tt> object. Note that
- * subclasses of the classes in this list are acceptable data types as
well.
- *
- * <p>The list is the value of the {@link
WireConstants#WIREADMIN_CONSUMER_FLAVORS}
- * service property of the
- * Consumer service object connected to this object. If no such
- * property was registered or the type of the property value is not
- * <tt>Class[]</tt>, this method must return <tt>null</tt>.
- *
- * @return An array containing the list of classes understood by the
- * Consumer service or <tt>null</tt> if
- * the <tt>Wire</tt> is not connected,
- * or the consumer did not register a {@link
WireConstants#WIREADMIN_CONSUMER_FLAVORS} property
- * or the value of the property is not of type <tt>Class[]</tt>.
- */
-
- public Class[] getFlavors()
- {
- if(isConnected())
- {
- try
- {
- return (Class
[])m_consumerServiceRef.getProperty(WireConstants.WIREADMIN_CONSUMER_FLAVORS);
- }
- catch(ClassCastException ex)
- {
- return null;
- }
- }
- else
- {
- return null;
-
- }
- }
-
- /**
- * Update the value.
- *
- * <p>This methods is called by the Producer service to
- * notify the Consumer service connected to this <tt>Wire</tt> object
- * of an updated value.
- * <p>If the properties of this <tt>Wire</tt> object contain a
- * {@link WireConstants#WIREADMIN_FILTER} property,
- * then filtering is performed.
- * If the Producer service connected to this <tt>Wire</tt>
- * object was registered with the service
- * property {@link WireConstants#WIREADMIN_PRODUCER_FILTERS}, the
- * Producer service will perform the filtering according to the rules
specified
- * for the filter. Otherwise, this <tt>Wire</tt> object
- * will perform the filtering of the value.
- * <p>If no filtering is done, or the filter indicates the updated
value should
- * be delivered to the Consumer service, then
- * this <tt>Wire</tt> object must call
- * the {@link Consumer#updated} method with the updated value.
- * If this <tt>Wire</tt> object is not connected, then the Consumer
- * service must not be called and the value is ignored.<p>
- * If the value is an <tt>Envelope</tt> object, and the scope name is
not permitted, then the
- * <tt>Wire</tt> object must ignore this call and not transfer the
object to the Consumer
- * service.
- *
- * <p>A <tt>WireAdminEvent</tt> of type {@link
WireAdminEvent#WIRE_TRACE}
- * must be broadcast by the Wire Admin service after
- * the Consumer service has been successfully called.
- *
- * @param value The updated value. The value should be an instance of
- * one of the types returned by {@link #getFlavors}.
- * @see WireConstants#WIREADMIN_FILTER
- */
- public void update(Object value)
- {
- // TODO Implement Access Control (p. 338)
- if (isConnected())
- {
- if(m_producerIsComposite == true)
- {
- // TODO Implement update for composite producers
- WireAdminImpl.traceln("WireImpl.update: update for composite
producers not yet implemented");
- return;
- }
- else // not a composite (Note: p. 341 "Filtering for composite
producer services is not supported")
- {
- //long time = m_date.getTime();
- long time = new Date().getTime();
-
- // We ignore filtering the first time...
- if(m_isFirstUpdate == false && m_filter != null)
- {
- // If the Producer service was registered with the
WIREADMIN_PRODUCER_FILTERS
- // service property indicating that the Producer service
will perform the data
- // filtering then the Wire object will not perform data
filtering. Otherwise,
- // the Wire object must perform basic filtering.
- try
- {
- m_dictionary.reset(value,time);
- if(!m_filter.match(m_dictionary))
- {
- WireAdminImpl.traceln("### Update rejected
("+m_properties.get(WireConstants.WIREADMIN_PID)+") filter evaluated to
false:"+m_filter);
- WireAdminImpl.traceln("
WIREVALUE_CURRENT.class"+m_dictionary.get(WireConstants.WIREVALUE_CURRENT).getClass().getName());
- WireAdminImpl.traceln("
WIREVALUE_CURRENT="+m_dictionary.get(WireConstants.WIREVALUE_CURRENT));
- WireAdminImpl.traceln("
WIREVALUE_PREVIOUS="+m_dictionary.get(WireConstants.WIREVALUE_PREVIOUS));
- WireAdminImpl.traceln("
WIREVALUE_DELTA_ABSOLUTE="+m_dictionary.get(WireConstants.WIREVALUE_DELTA_ABSOLUTE));
- WireAdminImpl.traceln("
WIREVALUE_DELTA_RELATIVE="+m_dictionary.get(WireConstants.WIREVALUE_DELTA_RELATIVE));
- WireAdminImpl.traceln("
WIREVALUE_ELAPSED="+m_dictionary.get(WireConstants.WIREVALUE_ELAPSED));
- return;
- }
- }
- catch(Exception ex)
- {
- // Could happen...
- WireAdminImpl.trace(ex);
- }
-
- }
- try
- {
- m_consumer.updated(this, value);
- if(m_isFirstUpdate == true)
- {
- m_isFirstUpdate = false;
- }
- m_lastUpdate = time;
- m_lastValue = value;
- // Fire event
- m_eventManager.fireEvent(WireAdminEvent.WIRE_TRACE,this);
- }
- catch(Exception ex)
- {
-
m_eventManager.fireEvent(WireAdminEvent.CONSUMER_EXCEPTION,this,ex);
- }
- }
- }
- }
-
- /**
- * Poll for an updated value.
- *
- * <p>This methods is normally called by the Consumer service to
- * request an updated value from the Producer service
- * connected to this <tt>Wire</tt> object.
- * This <tt>Wire</tt> object will call
- * the {@link Producer#polled} method to obtain an updated value.
- * If this <tt>Wire</tt> object is not connected, then the Producer
- * service must not be called.<p>
- *
- * If this <tt>Wire</tt> object has a scope, then this method
- * must return an array of <tt>Envelope</tt> objects. The objects
returned must
- * match the scope of this object. The <tt>Wire</tt> object must remove
- * all <tt>Envelope</tt> objects with a scope name that is not in the
<tt>Wire</tt> object's scope.
- * Thus, the list of objects returned
- * must only contain <tt>Envelope</tt> objects with a permitted scope
name. If the
- * array becomes empty, <tt>null</tt> must be returned.
- *
- * <p>A <tt>WireAdminEvent</tt> of type {@link
WireAdminEvent#WIRE_TRACE}
- * must be broadcast by the Wire Admin service after
- * the Producer service has been successfully called.
- *
- * @return A value whose type should be one of the types
- * returned by {@link #getFlavors}, <tt>Envelope[]</tt>, or
<tt>null</tt> if
- * the <tt>Wire</tt> object is not connected,
- * the Producer service threw an exception, or
- * the Producer service returned a value which is not an instance of
- * one of the types returned by {@link #getFlavors}.
- */
- public Object poll() {
- // p.330 "Update filtering must not apply to polling"
- if (isConnected())
- {
- try
- {
- Object value = m_producer.polled(this);
- Class []flavors = getFlavors();
-
- boolean valueOk = false;
-
- // Test if the value is ok with respect to the flavors
understood by
- // the consumer
- for(int i=0; i<flavors.length; i++)
- {
- Class currentClass = flavors[i];
- if(currentClass.isInstance(value))
- {
- valueOk = true;
- }
- }
- if(valueOk)
- {
- m_eventManager.fireEvent(WireAdminEvent.WIRE_TRACE,this);
- m_lastValue = value;
- return m_lastValue;
- }
- else
- {
- WireAdminImpl.traceln("WireImpl.poll: value returned by
producer is not undestood by consumer");
- return null;
- }
- }
- catch(Exception ex)
- {
-
m_eventManager.fireEvent(WireAdminEvent.PRODUCER_EXCEPTION,this,ex);
- return null;
- }
- }
- else
- {
- // p. 333 "If the poll() method on the wire object is called and
the
- // producer is unregistered it must return a null value"
- return null;
- }
- }
-
- /**
- * Return the last value sent through this <tt>Wire</tt> object.
- *
- * <p>The returned value is the most recent, valid value passed to the
- * {@link #update} method or returned by the {@link #poll} method
- * of this object. If filtering is performed by this <tt>Wire</tt>
object,
- * this methods returns the last value provided by the Producer
service. This
- * value may be an <tt>Envelope[]</tt> when the Producer service
- * uses scoping. If the return value is an Envelope object (or array),
it
- * must be verified that the Consumer service has the proper
WirePermission to see it.
- *
- * @return The last value passed though this <tt>Wire</tt> object
- * or <tt>null</tt> if no valid values have been passed or the Consumer
service has no permission.
- */
- public Object getLastValue()
- {
- return m_lastValue;
- }
-
- /**
- * Return the wire properties for this <tt>Wire</tt> object.
- *
- * @return The properties for this <tt>Wire</tt> object.
- * The returned <tt>Dictionary</tt> must be read only.
- */
- public Dictionary getProperties()
- {
- return m_properties;
- }
-
- /**
- * Return the calculated scope of this <tt>Wire</tt> object.
- *
- * The purpose of the <tt>Wire</tt> object's scope is to allow a
Producer
- * and/or Consumer service to produce/consume different types
- * over a single <tt>Wire</tt> object (this was deemed necessary for
efficiency
- * reasons). Both the Consumer service and the
- * Producer service must set an array of scope names (their scope) with
- * the service registration property <tt>WIREADMIN_PRODUCER_SCOPE</tt>,
or <tt>WIREADMIN_CONSUMER_SCOPE</tt> when they can
- * produce multiple types. If a Producer service can produce different
types, it should set this property
- * to the array of scope names it can produce, the Consumer service
- * must set the array of scope names it can consume. The scope of a
<tt>Wire</tt>
- * object is defined as the intersection of permitted scope names of the
- * Producer service and Consumer service.
- * <p>If neither the Consumer, or the Producer service registers scope
names with its
- * service registration, then the <tt>Wire</tt> object's scope must be
<tt>null</tt>.
- * <p>The <tt>Wire</tt> object's scope must not change when a Producer
or Consumer services
- * modifies its scope.
- * <p>A scope name is permitted for a Producer service when the
registering bundle has
- * <tt>WirePermission[PRODUCE]</tt>, and for a Consumer service when
- * the registering bundle has <tt>WirePermission[CONSUME]</tt>.<p>
- * If either Consumer service or Producer service has not set a
<tt>WIREADMIN_*_SCOPE</tt> property, then
- * the returned value must be <tt>null</tt>.<p>
- * If the scope is set, the <tt>Wire</tt> object must enforce the scope
names when <tt>Envelope</tt> objects are
- * used as a parameter to update or returned from the <tt>poll</tt>
method. The <tt>Wire</tt> object must then
- * remove all <tt>Envelope</tt> objects with a scope name that is not
permitted.
- *
- * @return A list of permitted scope names or null if the Produce or
Consumer service has set no scope names.
- */
- public String[] getScope()
- {
- return m_scope;
- }
-
- /**
- * Return true if the given name is in this <tt>Wire</tt> object's
scope.
- *
- * @param name The scope name
- * @return true if the name is listed in the permitted scope names
- */
- public boolean hasScope(String name)
- {
- if (m_scope != null)
- {
- for (int i = 0; i < m_scope.length; i++)
- {
- if (name.equals(m_scope[i]))
- {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * @see java.lang.Object#toString()
- */
- public String toString()
- {
- return super.toString()
- + ":["
- + getProperties().get(WireConstants.WIREADMIN_PID)
- + ","
- +
getProperties().get(WireConstants.WIREADMIN_PRODUCER_PID)
- + ","
- +
getProperties().get(WireConstants.WIREADMIN_CONSUMER_PID)
- + "]";
- }
-
- /**
- * Bind the consumer.
- *
- * @param consumer A <tt>ServiceReference</tt> corresponding to the
consumer service
- */
- void bindConsumer(ServiceReference consumerRef)
- {
- if(m_consumerServiceRef != null)
- {
- WireAdminImpl.traceln("WireImpl: consumer already bound!");
- return;
- }
-
- // Pid must be present
- if(consumerRef.getProperty(Constants.SERVICE_PID) == null)
- {
- WireAdminImpl.traceln("WireImpl: Consumer service has no PID
"+consumerRef);
- return;
- }
-
- // Flavors must be present
- if(consumerRef.getProperty(WireConstants.WIREADMIN_CONSUMER_FLAVORS)
== null)
- {
- WireAdminImpl.traceln("WireImpl: Consumer service has no
WIREADMIN_CONSUMER_FLAVORS "+consumerRef);
- return;
- }
-
- // Is this a composite?
- if(consumerRef.getProperty(WireConstants.WIREADMIN_CONSUMER_COMPOSITE)
!= null)
- {
- m_consumerIsComposite = true;
- m_consumerScope = (String [])
consumerRef.getProperty(WireConstants.WIREADMIN_CONSUMER_SCOPE);
-
- }
-
- m_consumerServiceRef = consumerRef;
- m_consumer = (Consumer) m_bundleContext.getService(consumerRef);
-
- if(m_producer != null)
- {
- if(m_producerIsComposite)
- {
- if(matchComposites() == false)
- {
- WireAdminImpl.traceln("WireImpl.bindConsumer : warning
composite identities do not match");
- }
- }
- m_isConnected = true;
- m_eventManager.fireEvent(WireAdminEvent.WIRE_CONNECTED,this);
- }
- }
-
- /**
- * Unbind the consumer
- *
- */
- void unbindConsumer()
- {
- // This test is made because knopflerfish doesn't support
ungetService(null);
- if(m_consumerServiceRef != null)
- {
- m_bundleContext.ungetService(m_consumerServiceRef);
- if(m_isConnected)
- {
- m_isConnected = false;
-
m_eventManager.fireEvent(WireAdminEvent.WIRE_DISCONNECTED,this);
- }
- m_consumer = null;
- m_consumerServiceRef = null;
- }
- }
-
- /**
- * Bind the producer
- *
- * @param producer A <tt>ServiceReference</tt> corresponding to the
producer service
- */
- void bindProducer(ServiceReference producerRef)
- {
- if(m_producerServiceRef != null)
- {
- WireAdminImpl.traceln("WireImpl: producer already bound!");
- return;
- }
-
- // Pid must be present
- if(producerRef.getProperty(Constants.SERVICE_PID) == null)
- {
- WireAdminImpl.traceln("WireImpl.bindProducer: Producer service has
no PID "+producerRef);
- return;
- }
-
- // Flavors must be present
- if(producerRef.getProperty(WireConstants.WIREADMIN_PRODUCER_FLAVORS)
== null)
- {
- WireAdminImpl.traceln("WireImpl: Consumer service has no
WIREADMIN_PRODUCER_FLAVORS "+producerRef);
- return;
- }
-
- // Is this a composite?
- if(producerRef.getProperty(WireConstants.WIREADMIN_PRODUCER_COMPOSITE)
!= null)
- {
- m_producerIsComposite = true;
- m_producerScope = (String [])
producerRef.getProperty(WireConstants.WIREADMIN_PRODUCER_SCOPE);
- }
-
- m_producerServiceRef = producerRef;
- m_producer = (Producer) m_bundleContext.getService(producerRef);
-
- // p. 329 " If this property (wireadmin.producer.filters) is not set,
- // the Wire object must filter according to the description in
CompositeObjects"
- if(producerRef.getProperty(WireConstants.WIREADMIN_PRODUCER_FILTERS)
== null)
- {
- String filter = (String)
m_properties.get(WireConstants.WIREADMIN_FILTER);
- if(filter != null)
- {
- try
- {
- m_filter = m_bundleContext.createFilter(filter);
- }
- catch(InvalidSyntaxException ex)
- {
- WireAdminImpl.traceln("WireImpl.bindProducer: Ignoring
filter with invalid syntax "+filter);
- }
- }
- }
-
- if(m_consumer != null)
- {
- if(m_consumerIsComposite)
- {
- if(matchComposites() == false)
- {
- WireAdminImpl.traceln("WireImpl.bindProducer : warning
composite identities do not match");
- }
- }
- m_isConnected = true;
- // fire the corresponding event
- m_eventManager.fireEvent(WireAdminEvent.WIRE_CONNECTED,this);
- }
- }
-
- /**
- * Unbind the producer
- *
- */
- void unbindProducer()
- {
- if(m_producerServiceRef != null)
- {
- m_bundleContext.ungetService(m_producerServiceRef);
- if(m_isConnected)
- {
- m_isConnected = false;
- // fire the corresponding event
-
m_eventManager.fireEvent(WireAdminEvent.WIRE_DISCONNECTED,this);
- }
- m_producer = null;
- m_producerServiceRef = null;
- }
- }
-
- /**
- * Check if composites match. Match occurs when "at least one equal
composite identity is
- * listed on both the Producer and Consmer composite identity service
property" (p. 336)
- *
- * @return <tt>true</tt> if they match, <tt>false</tt>otherwise
- */
- private boolean matchComposites()
- {
- String [] producerIdentities = (String [])
m_producerServiceRef.getProperty(WireConstants.WIREADMIN_PRODUCER_COMPOSITE);
- String [] consumerIdentities = (String [])
m_producerServiceRef.getProperty(WireConstants.WIREADMIN_PRODUCER_COMPOSITE);
-
- boolean match = false;
-
- // confirm matching
-
- for(int i = 0; i< producerIdentities.length; i++)
- {
- String currentProducerIdentity = producerIdentities [i];
- for(int j = 0; j < consumerIdentities.length; j++)
- {
- String currentConsumerIdentity = consumerIdentities [j];
- if (currentProducerIdentity.equals(currentConsumerIdentity))
- {
- match = true;
- break;
- }
- }
- }
-
- // setup wire scope
-
- if (m_consumerScope != null && m_producerScope != null)
- {
- // p. 337 "It is allowed to register with a wildcard, indicating
that all scopenames
- // are supported. In that case, the WIREADMIN_SCOPE_ALL ({"*"})
should be registered as the
- // scope of the serivce. The WireObject's scope is then fully
defined by the
- // other service connected to the wire object
- if(m_consumerScope.length == 1 && m_consumerScope[0].equals("*"))
- {
- m_scope = m_producerScope;
- }
- else if(m_producerScope.length == 1 &&
m_producerScope[0].equals("*"))
- {
- m_scope = m_consumerScope;
- }
- else
- {
- /*
- // TODO Implement wire scope creation based on producer,
consumer and wire permissions (p. 338)
-
- ServiceReference ref =
m_bundleContext.getServiceReference(PermissionAdmin.class.getName());
- if(ref != null)
- {
- PermissionAdmin permAdmin = (PermissionAdmin)
m_bundleContext.getService(ref);
- PermissionInfo [] producerPermissions =
permAdmin.getPermissions(m_producerServiceRef.getBundle().getLocation());
- PermissionInfo [] consumerPermissions =
permAdmin.getPermissions(m_consumerServiceRef.getBundle().getLocation());
- }
- */
- }
- }
- else
- {
- // p. 337 "Not registering this property (WIREADMIN_CONSUMER_SCOPE
or WIREADMIN_PRODUCER_SCOPE)
- // by the Consumer or the Producer service indicates to the
WireAdmin service that any
- // Wire object connected to that service must return null for the
Wire.getScope() method"
- m_scope = null;
- }
-
- return match;
- }
-
- /**
- * Called to invalidate the wire
- *
- */
- void invalidate()
- {
- if(m_isValid)
- {
- unbindProducer();
- unbindConsumer();
- m_isValid=false;
- }
- }
-
- /**
- * Update the properties
- *
- * @param properties new properties
- */
- void updateProperties(Dictionary properties)
- {
- m_properties = properties;
- }
-
- /**
- * Return the service reference corresponding to the producer
- *
- * @return a <tt>ServiceReference</tt> corresponding to the producer
- */
- ServiceReference getProducerServiceRef()
- {
- return m_producerServiceRef;
- }
-
- /**
- * Return the producer service object
- *
- * @return An <tt>Object</tt> corresponding to the producer
- */
- Producer getProducer()
- {
- return m_producer;
- }
-
- /**
- * return the producer PID
- *
- * @return
- */
- String getProducerPID()
- {
- return m_producerPID;
- }
-
- /**
- * Return the service reference corresponding to the consumer
- *
- * @return a <tt>ServiceReference</tt> corresponding to the consumer
- */
- ServiceReference getConsumerServiceRef()
- {
- return m_consumerServiceRef;
- }
-
- /**
- * Returns the consumer service object
- *
- * @return An <tt>Object</tt> corresponding to the consumer
- */
- Consumer getConsumer()
- {
- return m_consumer;
- }
-
- /**
- * return the consumer PID
- *
- * @return
- */
- String getConsumerPID()
- {
- return m_consumerPID;
- }
-
- /**
- * This inner class implements a dictionary that is used to filter out
values
- * during calls to update. This design choice was favored to avoid
constructing
- * a new dictionary for every call to update and to avoid doing unnecessary
- * calculations.
- */
- class FilterDictionary extends Dictionary
- {
- private Object m_value;
- private long m_time;
-
- /**
- * Must be called prior to evaluating the filter
- *
- * @param value
- * @param time
- */
- void reset(Object value, long time)
- {
- m_value = value;
- m_time = time;
- }
-
- /**
- *
- */
- public Object get(Object key)
- {
- if(key.equals(WireConstants.WIREVALUE_CURRENT))
- {
- return m_value;
- }
- else if(key.equals(WireConstants.WIREVALUE_PREVIOUS))
- {
- return m_lastValue;
- }
- else if(m_value instanceof Number &&
key.equals(WireConstants.WIREVALUE_DELTA_ABSOLUTE))
- {
- return null;
- }
- else if(m_value instanceof Number &&
key.equals(WireConstants.WIREVALUE_DELTA_RELATIVE))
- {
- return null;
- }
- else if(key.equals(WireConstants.WIREVALUE_ELAPSED))
- {
- if(m_lastUpdate == 0)
- {
- return new Long(0);
- }
- else
- {
- long delay = m_time - m_lastUpdate;
- //System.out.println("### delay = "+(delay));
- return new Long(delay);
- }
- }
- else
- {
- WireAdminImpl.traceln("### key not found:"+key);
- return null;
- }
- }
-
- /**
- * Never empty
- */
- public boolean isEmpty()
- {
- return false;
- }
-
- /**
- * Remove not supported
- */
- public Object remove(Object obj)
- {
- return null;
- }
-
- /**
- * Size is static
- */
- public int size()
- {
- return 5;
- }
-
- /**
- * Put not supported
- */
- public Object put(Object key, Object value)
- {
- return null;
- }
-
- /**
- *
- */
- public Enumeration keys()
- {
- Vector keys=new Vector();
-
- keys.addElement(WireConstants.WIREVALUE_ELAPSED);
- keys.addElement(WireConstants.WIREVALUE_CURRENT);
- keys.addElement(WireConstants.WIREVALUE_PREVIOUS);
- keys.addElement(WireConstants.WIREVALUE_DELTA_ABSOLUTE);
- keys.addElement(WireConstants.WIREVALUE_DELTA_RELATIVE);
-
- return keys.elements();
- }
-
- /**
- * Not supported
- */
- public Enumeration elements()
- {
- return null;
- }
- }
-}