/**
* This file is protected by Copyright.
* Please refer to the COPYRIGHT file distributed with this source distribution.
*
* This file is part of REDHAWK IDE.
*
* 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.
*
*/
package gov.redhawk.sca;
import gov.redhawk.model.sca.ScaDomainManager;
import gov.redhawk.model.sca.ScaDomainManagerRegistry;
import gov.redhawk.model.sca.ScaFactory;
import gov.redhawk.model.sca.ScaPackage;
import gov.redhawk.model.sca.commands.ScaModelCommand;
import gov.redhawk.model.sca.services.IScaObjectLocator;
import gov.redhawk.sca.compatibility.ICompatibilityUtil;
import gov.redhawk.sca.internal.ScaDomainRegistryObjectLocator;
import gov.redhawk.sca.preferences.ScaPreferenceConstants;
import gov.redhawk.sca.properties.IPropertiesProviderRegistry;
import gov.redhawk.sca.properties.PropertiesProviderRegistry;
import gov.redhawk.sca.util.CorbaURIUtil;
import gov.redhawk.sca.util.IPreferenceAccessor;
import gov.redhawk.sca.util.ORBUtil;
import gov.redhawk.sca.util.OrbSession;
import gov.redhawk.sca.util.ScopedPreferenceAccessor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Callable;
import mil.jpeojtrs.sca.util.CorbaUtils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.jacorb.JacorbActivator;
import org.omg.CosNaming.Binding;
import org.omg.CosNaming.BindingIteratorHolder;
import org.omg.CosNaming.BindingListHolder;
import org.omg.CosNaming.BindingType;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import CF.DomainManagerHelper;
/**
* The activator class controls the plug-in life cycle.
*/
public class ScaPlugin extends Plugin {
/**
* @since 4.0
*/
public static final String PLUGIN_ID = "gov.redhawk.sca";
/**
* @since 6.0
*/
public static final String EDITING_DOMAIN_ID = ScaPlugin.PLUGIN_ID + ".editingDomain";
// The shared instance
/** The plugin. */
private static ScaPlugin plugin;
private ScopedPreferenceAccessor scaPreferenceStore;
private ServiceTracker<IScaDomainManagerRegistryFactoryService, IScaDomainManagerRegistryFactoryService> registryService;
private ServiceTracker<ICompatibilityUtil, ICompatibilityUtil> compatibilityUtil;
private ServiceRegistration< ? > serviceReg;
/**
* The constructor.
*/
public ScaPlugin() {
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
*/
/**
* {@inheritDoc}
*/
@Override
public void start(final BundleContext context) throws Exception {
ScaPlugin.plugin = this;
super.start(context);
JacorbActivator.getDefault().init();
this.compatibilityUtil = new ServiceTracker<ICompatibilityUtil, ICompatibilityUtil>(getBundle().getBundleContext(), ICompatibilityUtil.class, null);
this.compatibilityUtil.open(true);
this.registryService = new ServiceTracker<IScaDomainManagerRegistryFactoryService, IScaDomainManagerRegistryFactoryService>(context,
IScaDomainManagerRegistryFactoryService.class, null);
this.registryService.open();
this.serviceReg = context.registerService(IScaObjectLocator.class.getName(), new ScaDomainRegistryObjectLocator(), null);
}
/**
* Returns the bundle id of the bundle that contains the provided object, or
* <code>null</code> if the bundle could not be determined.
*
* @since 2.4
*/
public String getBundleId(final Object object) {
if (object == null) {
return null;
}
final Bundle source = FrameworkUtil.getBundle(object.getClass());
if (source != null && source.getSymbolicName() != null) {
return source.getSymbolicName();
}
return null;
}
/**
* @since 7.0
*
* Returns the domain manager registry.
* @param context
* the current Display (meaningful in RAP only), used to ensure user-specific context.
* @return the domain manager registry
*/
public ScaDomainManagerRegistry getDomainManagerRegistry(Object context) {
IScaDomainManagerRegistryFactoryService service = this.registryService.getService();
if (service != null) {
IScaDomainManagerRegistryContainer container = service.getRegistryContainer(context);
if (container != null) {
return container.getRegistry(context);
}
}
return null;
}
/**
* @since 7.0
*
* Creates a domain outside of the domain manager registry, this domain will not be saved by the domain manager
* registry service
*/
public ScaDomainManager createTransientDomain(final String domainName, Map<String, String> connectionProperties) {
TransactionalEditingDomain editingDomain = TransactionalEditingDomain.Registry.INSTANCE.getEditingDomain(ScaPlugin.EDITING_DOMAIN_ID);
final ResourceSet scaModelResourceSet = editingDomain.getResourceSet();
URI uri = org.eclipse.emf.common.util.URI.createURI("virtual://transientDomains.sca");
final Resource resource = scaModelResourceSet.createResource(uri);
final ScaDomainManager newDomain = ScaFactory.eINSTANCE.createScaDomainManager();
newDomain.setName(domainName);
if (connectionProperties == null) {
connectionProperties = Collections.emptyMap();
}
newDomain.getConnectionProperties().putAll(connectionProperties);
editingDomain.getCommandStack().execute(new ScaModelCommand() {
@Override
public void execute() {
resource.getContents().add(newDomain);
newDomain.eAdapters().add(new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
switch (msg.getFeatureID(ScaDomainManager.class)) {
case ScaPackage.SCA_DOMAIN_MANAGER__DISPOSED:
if (msg.getNewBooleanValue()) {
resource.getContents().remove(newDomain);
}
newDomain.eAdapters().remove(this);
scaModelResourceSet.getResources().remove(resource);
break;
default:
break;
}
}
});
}
});
return newDomain;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
*/
/**
* {@inheritDoc}
*/
@Override
public void stop(final BundleContext context) throws Exception {
try {
if (this.compatibilityUtil != null) {
this.compatibilityUtil.close();
this.compatibilityUtil = null;
}
if (this.registryService != null) {
this.registryService.close();
this.registryService = null;
}
if (this.serviceReg != null) {
this.serviceReg.unregister();
this.serviceReg = null;
}
ScaPlugin.plugin = null;
} finally {
super.stop(context);
}
}
/**
* Returns the shared instance.
*
* @return the shared instance
*/
public static ScaPlugin getDefault() {
return ScaPlugin.plugin;
}
/**
* @since 3.0
*
* Returns an object that can be used to read and write system Preferences.
*
* @return
* an object used to access system preferences. For RAP, preferences are generally scoped and
* persisted on a per-user basis. That is not the case with this plug-in. Because there are no UI
* dependencies, there is no way to access a user context.
*/
public IPreferenceAccessor getScaPreferenceAccessor() {
if (this.scaPreferenceStore == null) {
this.scaPreferenceStore = new ScopedPreferenceAccessor(InstanceScope.INSTANCE, ScaPlugin.getPluginId());
}
return this.scaPreferenceStore;
}
/**
* @since 7.0
*
* Returns a utility class that provides platform-specific implementations for RAP
* and RCP runtime environments.
*
* @return
* the utility class
*/
public ICompatibilityUtil getCompatibilityUtil() {
return compatibilityUtil.getService();
}
/**
* @since 3.0
*/
public static String getPluginId() {
return ScaPlugin.PLUGIN_ID;
}
/**
* @since 5.0
*/
public static IPropertiesProviderRegistry getPropertiesProviderRegistry() {
return PropertiesProviderRegistry.INSTANCE;
}
/**
* Determines if a domain of the given name is bound to the default naming service and
* appears to be existant.
* @throws InterruptedException
* @throws CoreException
* @since 7.0
*/
public static boolean isDomainOnline(final String domainName, IProgressMonitor monitor) throws CoreException, InterruptedException {
IPreferenceAccessor prefs = ScaPlugin.getDefault().getScaPreferenceAccessor();
final String namingService = prefs.getString(ScaPreferenceConstants.SCA_DEFAULT_NAMING_SERVICE);
//final String namingService = Platform.getPreferencesService().getString(ScaPreferenceConstants.SCA_DEFAULT_NAMING_SERVICE);
return ScaPlugin.isDomainOnline(domainName, namingService, monitor);
}
/**
* Determines if a domain of the given name is bound to the naming service and
* appears to be existant.
* @throws InterruptedException
* @throws CoreException
* @since 7.0
*/
public static boolean isDomainOnline(final String domainName, final String namingService, IProgressMonitor monitor) throws CoreException,
InterruptedException {
return ScaPlugin.nameServiceObjectExists(domainName, namingService, monitor);
}
/**
* Determine's if an object with a given name is bound to the provided nameservice and
* the object exists.
* @throws InterruptedException
* @throws CoreException
*
* @since 7.0
*/
public static boolean nameServiceObjectExists(final String name, final String nameServiceInitRef, IProgressMonitor parentMonitor) throws CoreException,
InterruptedException {
SubMonitor subMonitor = SubMonitor.convert(parentMonitor, "Checking if name service object exists...", 2);
final String nameServiceRef = CorbaURIUtil.addDefaultPort(nameServiceInitRef);
OrbSession session = OrbSession.createSession();
// Allow the user to specify the DomainManager. If there is no '/'
// then the user did not specify it(Use the SCA 2.2.2 specific
// implementation which is <name>/<name>)
final String orbName;
if (name.indexOf('/') == -1) {
orbName = name + "/" + name;
} else {
orbName = name;
}
NamingContextExt rootContext = null;
org.omg.CORBA.Object object = null;
try {
final org.omg.CORBA.Object ref = CorbaUtils.string_to_object(session.getOrb(), nameServiceRef, subMonitor.newChild(1));
rootContext = CorbaUtils.invoke(new Callable<NamingContextExt>() {
@Override
public NamingContextExt call() throws Exception {
return NamingContextExtHelper.narrow(ref);
}
}, subMonitor.newChild(1));
object = CorbaUtils.resolve_str(rootContext, orbName, subMonitor.newChild(1));
return !CorbaUtils.non_existent(object, subMonitor.newChild(1));
} catch (CoreException e1) {
return false;
} finally {
subMonitor.done();
if (rootContext != null) {
ORBUtil.release(rootContext);
rootContext = null;
}
if (object != null) {
ORBUtil.release(object);
object = null;
}
session.dispose();
}
}
/**
* Scan the naming service to find available domains
* @param monitor Progress monitor to interrupt the opperations with
* @throws InterruptedException
* @throws CoreException
*
* @since 7.0
*/
public static String[] findDomainNamesOnDefaultNameServer(IProgressMonitor monitor) throws CoreException, InterruptedException {
IPreferenceAccessor prefs = ScaPlugin.getDefault().getScaPreferenceAccessor();
final String namingService = prefs.getString(ScaPreferenceConstants.SCA_DEFAULT_NAMING_SERVICE);
return ScaPlugin.findDomainNamesOnNameServer(namingService, monitor);
}
/**
* Scan the naming service to find available domains
* @throws InterruptedException
* @throws CoreException
*
* @since 7.0
*/
public static String[] findDomainNamesOnNameServer(final String nameServiceInitRef, IProgressMonitor monitor) throws CoreException,
InterruptedException {
final int WORK_OTHER = 4;
final int WORK_ALL_BINDINGS = 10;
final int WORK_EACH_BINDING = 4;
final SubMonitor progress = SubMonitor.convert(monitor, "Finding domains on name server...", WORK_OTHER + WORK_ALL_BINDINGS);
final ArrayList<String> retVal = new ArrayList<String>();
final String nameServiceRef = CorbaURIUtil.addDefaultPort(nameServiceInitRef);
OrbSession session = OrbSession.createSession();
NamingContextExt rootContext = null;
try {
final org.omg.CORBA.Object rootContextRef = CorbaUtils.string_to_object(session.getOrb(), nameServiceRef, progress.newChild(1));
rootContext = CorbaUtils.invoke(new Callable<NamingContextExt>() {
@Override
public NamingContextExt call() throws Exception {
return NamingContextExtHelper.narrow(rootContextRef);
}
}, progress.newChild(1));
// Get a listing of root names
final BindingListHolder bl = new BindingListHolder();
rootContext.list(-1, bl, new BindingIteratorHolder());
progress.worked(1);
final SubMonitor progressBindings = progress.newChild(WORK_ALL_BINDINGS).setWorkRemaining(bl.value.length * WORK_EACH_BINDING);
for (Binding b : bl.value) {
// Domains are always bound in a context with the same name as the domain
if (b.binding_type.value() == BindingType._ncontext) {
String guessedDomainName = b.binding_name[0].id + "/" + b.binding_name[0].id;
org.omg.CORBA.Object object = null;
try {
object = CorbaUtils.resolve_str(rootContext, guessedDomainName, progressBindings.newChild(1));
if (!CorbaUtils.non_existent(object, progressBindings.newChild(1))
&& CorbaUtils.is_a(object, DomainManagerHelper.id(), progressBindings.newChild(1))) {
retVal.add(b.binding_name[0].id);
}
} catch (CoreException ex) {
if (!(ex.getCause() instanceof NotFound)) {
throw ex;
}
} finally {
ORBUtil.release(object);
object = null;
progressBindings.worked(1);
}
}
}
return retVal.toArray(new String[retVal.size()]);
} finally {
if (rootContext != null) {
ORBUtil.release(rootContext);
}
session.dispose();
progress.worked(1);
}
}
}