Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'osgi/bundles/org.eclipse.ecf.osgi.services.remoteserviceadmin/src/org/eclipse/ecf/osgi/services/remoteserviceadmin/TopologyManager.java')
-rw-r--r--osgi/bundles/org.eclipse.ecf.osgi.services.remoteserviceadmin/src/org/eclipse/ecf/osgi/services/remoteserviceadmin/TopologyManager.java263
1 files changed, 263 insertions, 0 deletions
diff --git a/osgi/bundles/org.eclipse.ecf.osgi.services.remoteserviceadmin/src/org/eclipse/ecf/osgi/services/remoteserviceadmin/TopologyManager.java b/osgi/bundles/org.eclipse.ecf.osgi.services.remoteserviceadmin/src/org/eclipse/ecf/osgi/services/remoteserviceadmin/TopologyManager.java
new file mode 100644
index 000000000..e0af2de5d
--- /dev/null
+++ b/osgi/bundles/org.eclipse.ecf.osgi.services.remoteserviceadmin/src/org/eclipse/ecf/osgi/services/remoteserviceadmin/TopologyManager.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Composent, Inc. and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Composent, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.osgi.services.remoteserviceadmin;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.SafeRunner;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.hooks.service.EventListenerHook;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.EndpointEvent;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdminListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @since 4.6
+ */
+public class TopologyManager
+ implements EventListenerHook, RemoteServiceAdminListener, ITopologyManager {
+
+ protected static final Logger logger = LoggerFactory.getLogger(TopologyManager.class);
+
+ class EndpointEventHolder {
+ private final EndpointDescription endpointDescription;
+ private final String filter;
+
+ public EndpointEventHolder(EndpointDescription d, String f) {
+ this.endpointDescription = d;
+ this.filter = f;
+ }
+
+ public EndpointDescription getEndpoint() {
+ return this.endpointDescription;
+ }
+
+ public String getFilter() {
+ return this.filter;
+ }
+ }
+
+ class ProxyEndpointEventListener implements EndpointEventListener {
+
+ private final Bundle bundle;
+
+ public ProxyEndpointEventListener(Bundle b) {
+ this.bundle = b;
+ }
+
+ public void endpointChanged(EndpointEvent event, String filter) {
+ int type = event.getType();
+ if (type == EndpointEvent.ADDED) {
+ synchronized (bundleEndpointEventListenerMap) {
+ List<EndpointEventHolder> endpointEventHolders = bundleEndpointEventListenerMap.get(this.bundle);
+ if (endpointEventHolders == null)
+ endpointEventHolders = new ArrayList<EndpointEventHolder>();
+ endpointEventHolders.add(new EndpointEventHolder(event.getEndpoint(), filter));
+ bundleEndpointEventListenerMap.put(this.bundle, endpointEventHolders);
+ }
+ } else if (type == EndpointEvent.REMOVED) {
+ synchronized (bundleEndpointEventListenerMap) {
+ List<EndpointEventHolder> endpointEventHolders = bundleEndpointEventListenerMap.get(this.bundle);
+ if (endpointEventHolders != null) {
+ for (Iterator<EndpointEventHolder> i = endpointEventHolders.iterator(); i.hasNext();) {
+ EndpointEventHolder eh = i.next();
+ EndpointDescription oldEd = eh.getEndpoint();
+ EndpointDescription newEd = event.getEndpoint();
+ if (oldEd.equals(newEd))
+ i.remove();
+ }
+ if (endpointEventHolders.size() == 0)
+ bundleEndpointEventListenerMap.remove(this.bundle);
+ }
+
+ }
+ }
+ deliverSafe(event, filter);
+ }
+
+ private void logError(String methodName, String message, Throwable e) {
+ logger.error(((methodName == null) ? "<unknown>" //$NON-NLS-1$
+ : methodName) + ":" //$NON-NLS-1$
+ + ((message == null) ? "<empty>" //$NON-NLS-1$
+ : message),
+ e);
+ }
+
+ private void deliverSafe(final EndpointEvent endpointEvent, final String matchingFilter) {
+ final EndpointEventListener listener = topologyManagerImpl;
+ SafeRunner.run(new ISafeRunnable() {
+ public void run() throws Exception {
+ if (listener != null)
+ listener.endpointChanged(endpointEvent, matchingFilter);
+ }
+
+ public void handleException(Throwable exception) {
+ String message = "Exception in EndpointEventListener listener=" //$NON-NLS-1$
+ + listener + " event=" //$NON-NLS-1$
+ + endpointEvent + " matchingFilter=" //$NON-NLS-1$
+ + matchingFilter;
+ logError("deliverSafe", message, exception); //$NON-NLS-1$
+ };
+ });
+ }
+
+ public void deliverRemoveEventForBundle(EndpointEventHolder eventHolder) {
+ deliverSafe(new EndpointEvent(EndpointEvent.REMOVED, eventHolder.getEndpoint()), eventHolder.getFilter());
+ }
+ }
+
+ private Map<Bundle, List<EndpointEventHolder>> bundleEndpointEventListenerMap = new HashMap<Bundle, List<EndpointEventHolder>>();
+
+ protected TopologyManagerImpl topologyManagerImpl;
+ protected ServiceRegistration<?> endpointListenerRegistration;
+ protected List<String> matchingFilters;
+
+ protected void activate(BundleContext context, Map<String, ?> properties) throws Exception {
+ String endpointConditionalOp = (String) properties.get(ENDPOINT_CONDITIONAL_OP_PROP);
+ if (endpointConditionalOp == null)
+ endpointConditionalOp = ENDPOINT_CONDITIONAL_OP;
+
+ Boolean endpointAllowLocalhost = (Boolean) properties.get(ENDPOINT_ALLOWLOCALHOST_PROP);
+ if (endpointAllowLocalhost == null)
+ endpointAllowLocalhost = ENDPOINT_ALLOWLOCALHOST;
+
+ String extraFilters = (String) properties.get(ENDPOINT_EXTRA_FILTERS_PROP);
+ if (extraFilters == null)
+ extraFilters = ENDPOINT_EXTRA_FILTERS;
+
+ String[] extraFiltersArr = null;
+ if (extraFilters != null)
+ extraFiltersArr = extraFilters.split(","); //$NON-NLS-1$
+
+ String extraConditional = (String) properties.get(ENDPOINT_EXTRA_CONDITIONAL_PROP);
+ if (extraConditional == null)
+ extraConditional = ENDPOINT_EXTRA_CONDITIONAL;
+ this.matchingFilters = Collections.synchronizedList(new ArrayList<String>());
+ this.topologyManagerImpl = new TopologyManagerImpl(context);
+ StringBuffer elScope = new StringBuffer(""); //$NON-NLS-1$
+ if (endpointConditionalOp != null && !"".equals(endpointConditionalOp)) { //$NON-NLS-1$
+ elScope.append("(").append(endpointConditionalOp).append("("); //$NON-NLS-1$ //$NON-NLS-2$
+ if (!ENDPOINT_ALLOWLOCALHOST)
+ elScope.append("!(").append(org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_FRAMEWORK_UUID) //$NON-NLS-1$
+ .append("=").append(topologyManagerImpl.getFrameworkUUID()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
+ elScope.append(")"); //$NON-NLS-1$
+ elScope.append(ONLY_ECF_SCOPE);
+ if (extraConditional != null && !"".equals(extraConditional)) //$NON-NLS-1$
+ elScope.append(extraConditional);
+ elScope.append(")"); //$NON-NLS-1$
+ }
+ String elString = elScope.toString();
+ if (!"".equals(elString)) //$NON-NLS-1$
+ matchingFilters.add(elString);
+
+ if (extraFiltersArr != null)
+ for (String filter : extraFiltersArr)
+ if (filter != null && !"".equals(filter)) //$NON-NLS-1$
+ matchingFilters.add(filter);
+
+ Dictionary<String, Object> props = createEndpointListenerProps(matchingFilters);
+
+ endpointListenerRegistration = context.registerService(EndpointEventListener.class,
+ new ServiceFactory<EndpointEventListener>() {
+ public EndpointEventListener getService(Bundle bundle,
+ ServiceRegistration<EndpointEventListener> registration) {
+ return new ProxyEndpointEventListener(bundle);
+ }
+
+ public void ungetService(Bundle bundle, ServiceRegistration<EndpointEventListener> registration,
+ EndpointEventListener service) {
+ ProxyEndpointEventListener peel = (service instanceof ProxyEndpointEventListener)
+ ? (ProxyEndpointEventListener) service
+ : null;
+ if (peel == null)
+ return;
+ synchronized (bundleEndpointEventListenerMap) {
+ List<EndpointEventHolder> endpointEventHolders = bundleEndpointEventListenerMap.get(bundle);
+ if (endpointEventHolders != null)
+ for (EndpointEventHolder eh : endpointEventHolders)
+ peel.deliverRemoveEventForBundle(eh);
+ }
+ }
+ }, (Dictionary<String, Object>) props);
+ }
+
+ protected Dictionary<String, Object> createEndpointListenerProps(List<String> filters) {
+ Hashtable<String, Object> props = new Hashtable<String, Object>();
+ props.put(org.osgi.service.remoteserviceadmin.EndpointEventListener.ENDPOINT_LISTENER_SCOPE,
+ matchingFilters.toArray(new String[filters.size()]));
+ return props;
+ }
+
+ protected void deactivate() {
+ if (endpointListenerRegistration != null) {
+ endpointListenerRegistration.unregister();
+ endpointListenerRegistration = null;
+ }
+ if (this.topologyManagerImpl != null) {
+ this.topologyManagerImpl.close();
+ this.topologyManagerImpl = null;
+ }
+ if (this.matchingFilters != null) {
+ this.matchingFilters.clear();
+ this.matchingFilters = null;
+ }
+ }
+
+ // RemoteServiceAdminListener impl
+ public void remoteAdminEvent(RemoteServiceAdminEvent event) {
+ if (topologyManagerImpl == null)
+ return;
+ topologyManagerImpl.handleRemoteAdminEvent(event);
+ }
+
+ // EventListenerHook impl
+ public void event(ServiceEvent event, @SuppressWarnings("rawtypes") Map listeners) {
+ if (topologyManagerImpl == null)
+ return;
+ topologyManagerImpl.handleEvent(event, listeners);
+ }
+
+ public String[] getEndpointFilters() {
+ return this.matchingFilters.toArray(new String[this.matchingFilters.size()]);
+ }
+
+ public String[] setEndpointFilters(String[] newFilters) {
+ List<String> f = this.matchingFilters;
+ if (f == null || newFilters == null)
+ return null;
+ List<String> result = new ArrayList<String>(f);
+ synchronized (f) {
+ f.clear();
+ for (int i = 0; i < newFilters.length; i++)
+ f.add(newFilters[i]);
+ }
+ if (endpointListenerRegistration != null)
+ endpointListenerRegistration.setProperties(createEndpointListenerProps(Arrays.asList(newFilters)));
+ return result.toArray(new String[result.size()]);
+ }
+
+}

Back to the top