| /******************************************************************************* |
| * Copyright (c) 1997, 2011 by ProSyst Software GmbH and others. |
| * http://www.prosyst.com |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * ProSyst Software GmbH - initial API and implementation |
| * IBM Corporation - bug fix 347974 |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.wireadmin; |
| |
| import java.util.*; |
| import org.osgi.framework.*; |
| import org.osgi.service.wireadmin.*; |
| |
| /** |
| * @author Pavlin Dobrev |
| * @version 1.0 |
| */ |
| |
| class WireImpl implements Wire, ServiceListener { |
| |
| private BundleContext bc; |
| |
| /** Holds all the properties associated with this <code>Wire</code> object */ |
| private WireProperties properties; |
| |
| /** Holds a service reference to the associated <code>Producer</code> */ |
| ServiceReference producerRef; |
| |
| /** Holds a service reference to the associated <code>Consumer</code> */ |
| ServiceReference consumerRef; |
| |
| private Producer producer; |
| private Consumer consumer; |
| |
| private Class[] flavors; |
| |
| /** Holds the last value passed to this <code>Wire</code> by the <code>Producer</code>. */ |
| private Object lastValue; |
| /** Holds the previous value passed through this <code>Wire</code> to the <code>Consumer</code>. */ |
| private Object previousValue; |
| |
| private Vector envelopes; |
| |
| /** |
| * <code>WireAdmin</code> object whit which this <code>Wire</code> was |
| * created. |
| */ |
| private WireAdminImpl parent; |
| |
| private Filter filter = null; |
| |
| /** Holds the time of previous <code>Consumer</code> update in milliseconds */ |
| private long previousUpdateTime = -1; |
| |
| /** Holds the available wire values (filter attributes) */ |
| private Hashtable wireValues; |
| |
| /* holds a list of scopes */ |
| private String[] scope; |
| |
| /** Indicates that this <code>Wire</code> object has been deleted */ |
| boolean isValid = true; |
| |
| private boolean interoperate = true; |
| |
| private boolean allAccepted = true; |
| |
| /** |
| * Creates a <code>Wire</code> object, representing a connection between a |
| * <code>Producer</code> and <code>Consumer</code>. |
| * |
| * @param bc |
| * is the Wiring <code>BundleContext</code>. |
| * @param parent |
| * is the <code>WireAdmin</code> which is the creator of this |
| * <code>Wire</code>. |
| * @param wirePID |
| * is a <code>String</code> holding a unique presistent |
| * identifier of this <code>Wire</code>, generated by the |
| * parent <code>WireAdmin</code>. |
| * @param properties |
| * is a collection of the initial wire properties. |
| */ |
| WireImpl(BundleContext bc, WireAdminImpl parent, Dictionary properties) { |
| this.bc = bc; |
| this.parent = parent; |
| this.properties = new WireProperties(); |
| |
| for (Enumeration en = properties.keys(); en.hasMoreElements();) { |
| Object key = en.nextElement(); |
| this.properties.put0(key, properties.get(key)); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#isValid() |
| */ |
| public boolean isValid() { |
| return isValid; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#getFlavors() |
| */ |
| public Class[] getFlavors() { |
| return isConnected() ? flavors : null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#getProperties() |
| */ |
| public Dictionary getProperties() { |
| return properties; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#getLastValue() |
| */ |
| public synchronized Object getLastValue() { |
| return lastValue; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#update(java.lang.Object) |
| */ |
| public synchronized void update(Object value) { |
| if (!isConnected() || !interoperate || !isAcceptable(value)) { |
| return; |
| } |
| |
| if (value instanceof Envelope) { |
| Envelope e = (Envelope) value; |
| if (!hasScope(e.getScope())) { |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(Activator.PREFIX + "Try to pass a value in an Envelop without permission, silent return.", null); |
| } |
| return; |
| } |
| } |
| |
| try { |
| if (filter != null) { |
| wireValues.put(WireConstants.WIREVALUE_CURRENT, value); |
| |
| // #3329 |
| if (previousValue != null) { |
| wireValues.put(WireConstants.WIREVALUE_PREVIOUS, previousValue); |
| wireValues.put(WireConstants.WIREVALUE_ELAPSED, new Long(System.currentTimeMillis() - previousUpdateTime)); |
| } else { |
| previousValue = value; // this is to "prime the pump" |
| } |
| |
| if (Number.class.isInstance(value) && Number.class.isInstance(previousValue)) { |
| double val = ((Number) value).doubleValue(); |
| double prevVal = ((Number) previousValue).doubleValue(); |
| |
| wireValues.put(WireConstants.WIREVALUE_DELTA_ABSOLUTE, new Double(Math.abs(val - prevVal))); |
| // #3328 |
| wireValues.put(WireConstants.WIREVALUE_DELTA_RELATIVE, new Double(Math.abs(1 - prevVal / val))); |
| } else { |
| wireValues.remove(WireConstants.WIREVALUE_DELTA_ABSOLUTE); |
| wireValues.remove(WireConstants.WIREVALUE_DELTA_RELATIVE); |
| } |
| |
| if (!filter.match(wireValues)) { |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(0, 10012, filter + " / " + value, null, false); |
| } |
| return; |
| } |
| } |
| |
| if (consumer != null) { |
| try { |
| consumer.updated(this, value); |
| } catch (Throwable t) { |
| parent.notifyListeners(this, WireAdminEvent.CONSUMER_EXCEPTION, t); |
| } finally { |
| previousValue = value; |
| previousUpdateTime = System.currentTimeMillis(); |
| parent.notifyListeners(this, WireAdminEvent.WIRE_TRACE, null); |
| } |
| } |
| } finally { |
| lastValue = value; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#poll() |
| */ |
| public synchronized Object poll() { |
| Object value = null; |
| if (isConnected() && interoperate) { |
| try { |
| value = producer.polled(this); |
| } catch (Throwable t) { |
| // no exception in the Producer must prevent correct Wire |
| // functioning |
| parent.notifyListeners(this, WireAdminEvent.PRODUCER_EXCEPTION, t); |
| return null; |
| } |
| parent.notifyListeners(this, WireAdminEvent.WIRE_TRACE, null); |
| if (!isAcceptable(value) && (!(value instanceof Envelope[]))) { |
| value = null; |
| } |
| } |
| |
| if (value != null) { |
| lastValue = value; |
| if (value instanceof Envelope[]) { |
| |
| if (allAccepted) { |
| return value; |
| } |
| Envelope[] envs = (Envelope[]) value; |
| if (scope == null) { |
| return value; |
| } |
| |
| if (envelopes == null) { |
| envelopes = new Vector(envs.length); |
| } |
| boolean changed = false; |
| for (int i = 0; i < envs.length; i++) { |
| if (hasScope(envs[i].getScope())) { |
| envelopes.addElement(envs[i]); |
| } else { |
| changed = true; |
| } |
| } |
| |
| if (changed) { |
| value = new Envelope[envelopes.size()]; |
| envelopes.copyInto((Envelope[]) value); |
| envelopes.removeAllElements(); |
| } |
| } |
| } |
| return value; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#isConnected() |
| */ |
| public boolean isConnected() { |
| return isValid && (consumerRef != null) && (producerRef != null); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#getScope() |
| */ |
| public synchronized String[] getScope() { |
| return scope; |
| } |
| |
| private void setScope() { |
| if ((producerRef == null) || (consumerRef == null)) { |
| return; |
| } |
| |
| Vector prodScope = checkPermission((String[]) producerRef.getProperty(WireConstants.WIREADMIN_PRODUCER_SCOPE), WirePermission.PRODUCE, producerRef.getBundle()); |
| |
| Vector consScope = checkPermission((String[]) consumerRef.getProperty(WireConstants.WIREADMIN_CONSUMER_SCOPE), WirePermission.CONSUME, consumerRef.getBundle()); |
| |
| if ((prodScope == null) || (consScope == null)) { |
| return; |
| } |
| |
| if ((consScope.size() == 1) && consScope.elementAt(0).equals("*")) { |
| scope = new String[prodScope.size()]; |
| prodScope.copyInto(scope); |
| return; |
| } |
| |
| if ((prodScope.size() != ((String[]) producerRef.getProperty(WireConstants.WIREADMIN_PRODUCER_SCOPE)).length) || (consScope.size() != ((String[]) consumerRef.getProperty(WireConstants.WIREADMIN_CONSUMER_SCOPE)).length)) { |
| this.allAccepted = false; |
| } |
| |
| Vector cloning = (Vector) prodScope.clone(); |
| |
| for (Enumeration en = cloning.elements(); en.hasMoreElements();) { |
| Object next = en.nextElement(); |
| if (!consScope.contains(next)) { |
| prodScope.removeElement(next); |
| this.allAccepted = false; |
| } |
| } |
| |
| scope = new String[prodScope.size()]; |
| prodScope.copyInto(scope); |
| } |
| |
| private static Vector checkPermission(String[] scope, String action, Bundle b) { |
| if (scope == null) { |
| return null; |
| } |
| |
| Vector v = new Vector(); |
| for (int i = 0; i < scope.length; i++) { |
| WirePermission wp = new WirePermission(scope[i], action); |
| if (b.hasPermission(wp)) { |
| v.addElement(scope[i]); |
| } |
| } |
| return v; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.service.wireadmin.Wire#hasScope(java.lang.String) |
| */ |
| public boolean hasScope(String name) { |
| if ((scope == null) || ((scope.length == 1) && scope[0].equals("*"))) { |
| return true; |
| } |
| |
| for (int i = 0; i < scope.length; i++) { |
| if (name.equals(scope[i]) || scope[i].equals(WireConstants.WIREADMIN_SCOPE_ALL[0])) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| // Utility methods |
| /** |
| * Creates a string representation for this <code>Wire</code> |
| * |
| * @return a string representation of this object. |
| */ |
| public String toString() { |
| StringBuffer sb = new StringBuffer(100); |
| sb.append("Wire[PID="); |
| sb.append(properties.get(WireConstants.WIREADMIN_PID)); |
| sb.append(";prodPID="); |
| sb.append(properties.get(WireConstants.WIREADMIN_PRODUCER_PID)); |
| sb.append(";consPID="); |
| sb.append(properties.get(WireConstants.WIREADMIN_CONSUMER_PID)); |
| sb.append(";connected="); |
| sb.append(isConnected()); |
| // sb.append(";valid="); |
| // sb.append(isValid()); |
| // sb.append(";Scope={"); |
| // if (scope == null) { |
| // sb.append("null"); |
| // } else { |
| // for (int i = 0; i < scope.length; i++) { |
| // sb.append(scope[i]); |
| // if (i != scope.length - 2) { |
| // sb.append(", "); |
| // } |
| // } |
| // } |
| sb.append("}]"); |
| |
| return sb.toString(); |
| } |
| |
| /** |
| * This method starts tracking of |
| * <code>Producer</code> <code>Consumer</code>services associated with |
| * this <code>Wire</code> object. First we check if there are already such |
| * services started on the framework, after that two |
| * <code>ServiceTracker</code> objects are created to handle |
| * <code>Producer</code> and <code>Consumer</code> service tracking. |
| */ |
| synchronized void start() { |
| String producerPID = (String) properties.get(WireConstants.WIREADMIN_PRODUCER_PID); |
| String consumerPID = (String) properties.get(WireConstants.WIREADMIN_CONSUMER_PID); |
| updateListenerFilter(); |
| // check if there are such services already started |
| ServiceReference ref = getSingleRef(Producer.class.getName(), producerPID); |
| |
| if (ref != null) { |
| serviceRegistered(ref); |
| } |
| |
| ref = getSingleRef(Consumer.class.getName(), consumerPID); |
| |
| if (ref != null) { |
| serviceRegistered(ref); |
| } |
| |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(0, 10013, properties.get(WireConstants.WIREADMIN_PID).toString(), null, false); |
| } |
| } |
| |
| void updateListenerFilter() { |
| String producerPID = escapeSpecialCharacters((String) properties.get(WireConstants.WIREADMIN_PRODUCER_PID)); |
| String consumerPID = escapeSpecialCharacters((String) properties.get(WireConstants.WIREADMIN_CONSUMER_PID)); |
| |
| try { |
| // Create filter for tracking services regstered as Consumer's with |
| // the current |
| // WIRE_CONSUMER_PID and as Producer's with current |
| // WIRE_PRODUCER_PID |
| // escaping *, ) and ( in the pid. |
| StringBuffer sb = new StringBuffer();// "("); |
| sb.append('('); |
| sb.append('|'); |
| |
| sb.append('(').append('&'); |
| sb.append('(').append(Constants.SERVICE_PID).append('=').append(consumerPID).append(')'); |
| sb.append('(').append(Constants.OBJECTCLASS).append('=').append(Consumer.class.getName()).append(')'); |
| sb.append(')'); |
| |
| sb.append('(').append('&'); |
| sb.append('(').append(Constants.SERVICE_PID).append('=').append(producerPID).append(')'); |
| sb.append('(').append(Constants.OBJECTCLASS).append('=').append(Producer.class.getName()).append(')'); |
| sb.append(')'); |
| |
| if (consumerRef != null) {// in case service.pid changes |
| Long id = (Long) consumerRef.getProperty(Constants.SERVICE_ID); |
| sb.append('(').append(Constants.SERVICE_ID).append('=').append(id).append(')'); |
| } |
| |
| if (producerRef != null) {// in case service.pid changes |
| Long id = (Long) producerRef.getProperty(Constants.SERVICE_ID); |
| sb.append('(').append(Constants.SERVICE_ID).append('=').append(id).append(')'); |
| } |
| |
| sb.append(')'); |
| |
| // System.out.println("Filter is: " + sb.toString()); |
| |
| bc.addServiceListener(this, sb.toString()); |
| } catch (InvalidSyntaxException ise) { |
| /* Syntax is valid */ |
| } |
| |
| } |
| |
| private ServiceReference getSingleRef(String clazz, String pid) { |
| ServiceReference[] ref = null; |
| |
| try { |
| ref = bc.getServiceReferences(clazz, "(" + Constants.SERVICE_PID + "=" + escapeSpecialCharacters(pid) + ")"); |
| } catch (InvalidSyntaxException e) { |
| } |
| |
| if (ref != null) { |
| if (ref.length > 1) { |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(Activator.PREFIX + "Found more than one " + clazz + " services registered with the same pid: " + pid + "Wire was not created, please unregister all services which duplicate the pid.", null); |
| } |
| |
| parent.deleteWire(this); |
| } else if (ref.length == 1) { |
| return ref[0]; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Stops service tracking, removes this <code>Wire</code> from the wire |
| * lists of the associated Consumer and Producer services and informs them |
| * for disconnecting. |
| */ |
| synchronized void stop() { |
| if (!isValid) |
| return; // already stopped |
| |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(0, 10014, this.toString(), null, false); |
| } |
| bc.removeServiceListener(this); |
| if ((producerRef != null) && (consumerRef != null)) { |
| // if this wire was connected |
| isValid = false; |
| informServices(); |
| } |
| isValid = false; |
| |
| if (producerRef != null) { |
| bc.ungetService(producerRef); |
| } |
| if (consumerRef != null) { |
| bc.ungetService(consumerRef); |
| } |
| |
| // let gc do his work |
| producerRef = null; |
| consumerRef = null; |
| |
| producer = null; |
| consumer = null; |
| |
| lastValue = null; |
| previousValue = null; |
| parent = null; |
| filter = null; |
| wireValues = null; |
| scope = null; |
| bc = null; |
| } |
| |
| /** |
| * This method is invoked when the Wiring tracker detects a service |
| * registration or when the Wire is created The service type is determined |
| * (Producer or Consumer) and added to this <code>Wire</code>. Both |
| * Consumer and Producer (if available) are informed for connecting. |
| * |
| * @param sRef |
| * the service reference of the wire's producer or consumer |
| * @param notifyService |
| * specifies whether notification of the Producer/Consumer is |
| * necessary if it is the only one available part. |
| */ |
| private void serviceRegistered(ServiceReference sRef) { |
| String pid = (String) sRef.getProperty(Constants.SERVICE_PID); |
| |
| if (pid.equals(properties.get(WireConstants.WIREADMIN_PRODUCER_PID))) { |
| if (producerRef == null) { |
| this.producerRef = sRef; |
| this.producer = (Producer) bc.getService(producerRef); |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(Activator.PREFIX + "Wire " + properties.get(WireConstants.WIREADMIN_PID) + " detected producer " + pid, null); |
| } |
| } else |
| return; |
| } else { |
| if (consumerRef == null) { |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(Activator.PREFIX + "Wire " + properties.get(WireConstants.WIREADMIN_PID) + " detected consumer " + pid, null); |
| } |
| this.consumerRef = sRef; |
| this.consumer = (Consumer) bc.getService(consumerRef); |
| try { |
| this.flavors = (Class[]) consumerRef.getProperty(WireConstants.WIREADMIN_CONSUMER_FLAVORS); |
| } catch (ClassCastException cce) { |
| /* won't be initialized */ |
| } |
| } else |
| return; |
| } |
| |
| if (isConnected()) { |
| // inform the Producer/Consumer for connecting |
| setScope(); |
| informServices(); |
| parent.notifyListeners(this, WireAdminEvent.WIRE_CONNECTED, null); |
| checkInteroperability(); |
| } else if (!parent.hasAConnectedWire(pid.equals(properties.get(WireConstants.WIREADMIN_PRODUCER_PID)), pid)) { |
| // this service has no connected wire objects attached to it |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(0, 10015, pid, null, false); |
| } |
| // if (notifyService) { // The service is notified if it is only |
| // just registered |
| // informServices(); |
| // } |
| } |
| |
| updateListenerFilter(); |
| checkWireFilter(); |
| } |
| |
| private void checkWireFilter() { |
| boolean performFiltering = ((producerRef != null) && producerRef.getProperty(WireConstants.WIREADMIN_PRODUCER_FILTERS) == null) && (properties.get(WireConstants.WIREADMIN_FILTER) != null); |
| |
| if (performFiltering) { |
| if ((wireValues == null)) { |
| wireValues = new Hashtable(6, 1.0f); |
| } |
| |
| try { |
| filter = bc.createFilter((String) properties.get(WireConstants.WIREADMIN_FILTER)); |
| } catch (InvalidSyntaxException ise) { |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(Activator.PREFIX + "Filter syntax is invalid, filtering won't be made", null); |
| } |
| } |
| } else { |
| filter = null; |
| } |
| } |
| |
| private void serviceModified(ServiceReference sRef) { // fix #1073 |
| String pid = (String) sRef.getProperty(Constants.SERVICE_PID); |
| |
| if (sRef.equals(producerRef)) { |
| String currentPID = (String) properties.get(WireConstants.WIREADMIN_PRODUCER_PID); |
| |
| if (!currentPID.equals(pid)) { |
| // System.out.println("The pid of the PRODUCER is changed"); |
| serviceUnregistered(sRef); |
| return; |
| } |
| } |
| |
| if (sRef.equals(consumerRef)) { |
| String currentPID = (String) properties.get(WireConstants.WIREADMIN_CONSUMER_PID); |
| |
| if (!currentPID.equals(pid)) { |
| serviceUnregistered(sRef); |
| // System.out.println("The pid of the CONSUMER is changed"); |
| return; |
| } |
| try { |
| this.flavors = (Class[]) consumerRef.getProperty(WireConstants.WIREADMIN_CONSUMER_FLAVORS); |
| } catch (ClassCastException cce) { |
| /* won't be initialized */ |
| } |
| } |
| |
| if (producerRef == null || consumerRef == null) { |
| // System.out.println("Check if PID is BACK"); |
| serviceRegistered(sRef); |
| return; |
| } |
| |
| if (!isConnected()) { |
| return; |
| } |
| |
| setScope(); |
| checkInteroperability(); |
| checkWireFilter(); |
| } |
| |
| private void checkInteroperability() { |
| String[] p = (String[]) producerRef.getProperty(WireConstants.WIREADMIN_PRODUCER_COMPOSITE); |
| String[] c = (String[]) consumerRef.getProperty(WireConstants.WIREADMIN_CONSUMER_COMPOSITE); |
| |
| if ((p != null) && (c != null)) { |
| for (int i = 0; i < p.length; i++) { |
| for (int j = 0; j < c.length; j++) { |
| if (p[i].equals(c[j])) { |
| // found at least one match |
| interoperate = true; |
| return; |
| } |
| } |
| } |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(0, 10016, this.toString(), null, false); |
| } |
| interoperate = false; |
| } else { |
| interoperate = true; |
| } |
| } |
| |
| private void serviceUnregistered(ServiceReference sRef) { |
| boolean lastStatus = isConnected(); |
| |
| if (sRef.equals(producerRef)) { |
| this.producerRef = null; |
| this.producer = null; |
| } else if (sRef.equals(consumerRef)) { |
| this.consumerRef = null; |
| this.consumer = null; |
| this.flavors = null; |
| } else { |
| if (Activator.LOG_DEBUG) { |
| Activator.log.debug(Activator.PREFIX + "Unregistering another consumer with the same pid, ignoring it ...", null); |
| } |
| return; |
| } |
| |
| updateListenerFilter(); |
| |
| if (lastStatus) { |
| // last wire state was connected - now it is disconnected |
| informServices(); |
| parent.notifyListeners(this, WireAdminEvent.WIRE_DISCONNECTED, null); |
| } |
| if (bc != null) { |
| bc.ungetService(sRef); |
| } |
| |
| } |
| |
| /** |
| * This method checks if the given String contains one of the characters *, (, |
| * and ) which have a special meaning for the LDAP search filters. If there |
| * are such characters they are escaped with the backslash character ('\'). |
| */ |
| static String escapeSpecialCharacters(String s) { |
| char[] content = s.toCharArray(); |
| StringBuffer result = new StringBuffer(s); |
| int offset = 0; |
| |
| for (int i = 0; i < content.length; i++) { |
| if ((content[i] == 40) || (content[i] == 41) || (content[i] == 42)) { |
| result.insert(i + offset, "\\"); // fix #1078 |
| offset++; |
| } |
| } |
| return result.toString(); |
| } |
| |
| /** |
| * Change the properties of this wire. If the changes concern one of the |
| * properties WIRE_PRODUCER_PID and WIRE_CONSUMER_PID this wire must be |
| * stopped and started again to begin tracking of the new Services. |
| */ |
| void setProperties(Dictionary newProps) { |
| if (newProps != null) { |
| String newConsPID = (String) newProps.get(WireConstants.WIREADMIN_CONSUMER_PID); |
| String newProdPID = (String) newProps.get(WireConstants.WIREADMIN_PRODUCER_PID); |
| |
| String oldConsPID = (String) properties.get(WireConstants.WIREADMIN_CONSUMER_PID); |
| String oldProdPID = (String) properties.get(WireConstants.WIREADMIN_PRODUCER_PID); |
| |
| boolean restart = false; |
| |
| if (newConsPID == null) { |
| newProps.put(WireConstants.WIREADMIN_CONSUMER_PID, oldConsPID); |
| } else if (!newConsPID.equals(oldConsPID)) { |
| restart = true; |
| } |
| |
| if (newProdPID == null) { |
| newProps.put(WireConstants.WIREADMIN_PRODUCER_PID, oldProdPID); |
| } else if (!newProdPID.equals(oldProdPID)) { |
| restart = true; |
| } |
| // fix #1074 |
| if (newProps.get(WireConstants.WIREADMIN_PID) == null) { |
| newProps.put(WireConstants.WIREADMIN_PID, properties.get(WireConstants.WIREADMIN_PID)); |
| } |
| |
| // WireProperties wprops = new WireProperties(); |
| properties.clear(); |
| |
| for (Enumeration en = newProps.keys(); en.hasMoreElements();) { |
| Object key = en.nextElement(); |
| properties.put0(key, newProps.get(key)); |
| } |
| |
| checkWireFilter(); |
| |
| if (restart) { |
| // One of the Consumer or Producer has been changed so restart |
| // the wire |
| stop(); |
| start(); |
| return; |
| } |
| } |
| |
| if (isConnected()) { |
| informServices(); |
| } |
| |
| parent.notifyListeners(this, WireAdminEvent.WIRE_UPDATED, null); |
| } |
| |
| private boolean isAcceptable(Object value) { |
| Class[] flavors = getFlavors(); |
| |
| if (flavors == null) { |
| return true; |
| } |
| |
| for (int i = 0; i < flavors.length; i++) { |
| if (flavors[i].isInstance(value)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent) |
| */ |
| public void serviceChanged(ServiceEvent evt) { |
| if (bc == null) { |
| return; |
| } |
| switch (evt.getType()) { |
| case ServiceEvent.REGISTERED : |
| // System.out.println("E V E N T : registered"); |
| serviceRegistered(evt.getServiceReference()); |
| break; |
| |
| case ServiceEvent.UNREGISTERING : |
| // System.out.println("E V E N T : unregistering"); |
| serviceUnregistered(evt.getServiceReference()); |
| break; |
| |
| case ServiceEvent.MODIFIED : |
| // System.out.println("E V E N T : modified"); |
| serviceModified(evt.getServiceReference()); |
| } |
| } |
| |
| String getWirePID() { |
| return (String) properties.get(WireConstants.WIREADMIN_PID); |
| } |
| |
| /** |
| * This method simply informs both Producer and Consumer with the methods |
| * consumersConnected, producersConnected if a wire bacames connected and |
| * the remaining service if the wire becames disconnected. |
| */ |
| private void informServices() { |
| if (producerRef != null) { |
| String producerPID = (String) properties.get(WireConstants.WIREADMIN_PRODUCER_PID); |
| NotificationEvent ne = new NotificationEvent(producer, null, this, parent.getConnected(WireConstants.WIREADMIN_PRODUCER_PID, producerPID)); |
| parent.notifyConsumerProducer(ne); |
| |
| // try { |
| // producer.consumersConnected(parent.getConnected(WireConstants.WIREADMIN_PRODUCER_PID, |
| // producerPID)); |
| // } catch (Exception ex) { |
| // parent.notifyListeners(this, WireAdminEvent.PRODUCER_EXCEPTION , |
| // ex); |
| // } |
| } |
| |
| if (consumerRef != null) { |
| String consumerPID = (String) properties.get(WireConstants.WIREADMIN_CONSUMER_PID); |
| NotificationEvent ne = new NotificationEvent(null, consumer, this, parent.getConnected(WireConstants.WIREADMIN_CONSUMER_PID, consumerPID)); |
| parent.notifyConsumerProducer(ne); |
| |
| // try { |
| // consumer.producersConnected(parent.getConnected(WireConstants.WIREADMIN_CONSUMER_PID, |
| // consumerPID)); |
| // } catch (Exception ex) { |
| // parent.notifyListeners(this, WireAdminEvent.CONSUMER_EXCEPTION , |
| // ex); |
| // } |
| } |
| } |
| |
| } |