Commit e663c9c6 authored by Jay Jay Billings's avatar Jay Jay Billings

Fixed client and core bugs due to Declarative Services issues.

Mic drop! Got the Core and Client working smoothly together in such a
way that the ItemViewer now works again, the workspace dialog still
works, the HttpService still works, neither are set to auto-start in the
run configuration and both are registered as services. The primary
problem was in the way that Declarative Services are activated by the
framework.
Signed-off-by: default avatarJay Jay Billings <billingsjj@ornl.gov>
parent 67d65a7c
......@@ -5,7 +5,8 @@ Bundle-SymbolicName: org.eclipse.ice.client.test
Bundle-Version: 2.1.7.20150825
Fragment-Host: org.eclipse.ice.client;bundle-version="2.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: org.eclipse.ice.client.widgets,
Import-Package: org.eclipse.ice.client.internal,
org.eclipse.ice.client.widgets,
org.eclipse.ice.datastructures.ICEObject,
org.eclipse.ice.item,
org.eclipse.swt.widgets,
......
/*******************************************************************************
* Copyright (c) 2013, 2014- UT-Battelle, LLC.
* 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:
* Initial API and implementation and/or initial documentation -
* Jay Jay Billings
*******************************************************************************/
package org.eclipse.ice.client.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ice.client.internal.ClientExtensionFactory;
import org.eclipse.ice.iclient.IClient;
import org.junit.Test;
/**
* This class is responsible for testing
* {@link org.eclipse.ice.xml.ClientExtensionFactory}.
*
* @author Jay Jay Billings
*
*/
public class ClientExtensionFactoryTester {
/**
* Test method for
* {@link org.eclipse.ice.persistence.xml.ClientExtensionFactory#create()} .
*/
@Test
public void testCreate() {
// All this test can do - at least at the moment - is make sure that the
// factory returns a non-null instance of an XMLPersistenceProvider. It
// isn't clear how to test it for more detailed behavior yet.
ClientExtensionFactory factory = new ClientExtensionFactory();
Object provider;
try {
provider = factory.create();
assertNotNull(provider);
// Remember that the factory returns an IClient from create(), not
// an instance of itself!
assertTrue(provider instanceof IClient);
} catch (CoreException e) {
// It can also fail if the exception is caught, so we test that too.
e.printStackTrace();
fail();
}
return;
}
}
......@@ -18,6 +18,7 @@ import java.io.FileWriter;
import java.net.URI;
import java.util.ArrayList;
import org.eclipse.core.resources.IProject;
import org.eclipse.ice.core.iCore.ICore;
import org.eclipse.ice.datastructures.ICEObject.ICEList;
import org.eclipse.ice.datastructures.ICEObject.ICEObject;
......@@ -26,7 +27,6 @@ import org.eclipse.ice.datastructures.form.Form;
import org.eclipse.ice.datastructures.form.FormStatus;
import org.eclipse.ice.item.ICompositeItemBuilder;
import org.eclipse.ice.item.ItemBuilder;
import org.eclipse.core.resources.IProject;
/**
* <p>
......@@ -220,17 +220,6 @@ public class FakeCore implements ICore {
}
/**
* (non-Javadoc)
*
* @see ICore#getFileSystem(int uniqueClientID)
*/
@Override
public Form getFileSystem(int uniqueClientID) {
// TODO Auto-generated method stub
return new Form();
}
/**
* (non-Javadoc)
*
......
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="false" name="org.eclipse.ice.client.widgets">
<implementation class="org.eclipse.ice.client.widgets.EclipseUIWidgetFactory"/>
<reference bind="registerFormWidgetBuilder" cardinality="0..n" interface="org.eclipse.ice.client.widgets.IFormWidgetBuilder" name="IFormWidgetBuilder" policy="dynamic"/>
<service>
<provide interface="org.eclipse.ice.iclient.uiwidgets.IWidgetFactory"/>
</service>
<reference bind="registerFormWidgetBuilder" cardinality="0..n" interface="org.eclipse.ice.client.widgets.IFormWidgetBuilder" name="IFormWidgetBuilder" policy="dynamic"/>
</scr:component>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="output" path="bin"/>
</classpath>
#Mon Aug 27 14:50:32 EDT 2012
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
......@@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: Client
Bundle-SymbolicName: org.eclipse.ice.client;singleton:=true
Bundle-Version: 2.1.7.20150825
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: org.eclipse.ice.client.common,
org.eclipse.ice.client.common.internal,
org.eclipse.ice.client.common.properties,
......@@ -23,8 +23,10 @@ Import-Package: javax.ws.rs.core,
org.eclipse.ice.item,
org.osgi.framework;version="1.7.0",
org.slf4j;version="1.7.2"
Service-Component: OSGI-INF/clientComponent.xml
Require-Bundle: org.eclipse.ice.datastructures;bundle-version="2.1.7",
com.sun.jersey;bundle-version="1.17.0",
org.eclipse.ice.client.compatibility;bundle-version="2.0.0",
org.eclipse.core.runtime;bundle-version="3.11.0"
Bundle-ActivationPolicy: lazy
Eclipse-LazyStart: true
Bundle-Activator: org.eclipse.ice.client.internal.Client
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="false" name="org.eclipse.ice.client">
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true" immediate="false" name="org.eclipse.ice.client">
<implementation class="org.eclipse.ice.client.internal.Client"/>
<service>
<provide interface="org.eclipse.ice.iclient.IClient"/>
</service>
<reference bind="setUIWidgetFactory" cardinality="0..1" interface="org.eclipse.ice.iclient.uiwidgets.IWidgetFactory" name="IWidgetFactory" policy="dynamic"/>
<reference cardinality="1..1" interface="org.eclipse.ice.iclient.uiwidgets.IWidgetFactory" name="IWidgetFactory" policy="static"/>
</scr:component>
......@@ -51,7 +51,7 @@
name="ICE Client"
point="org.eclipse.ice.client.clientInstance">
<client
class="org.eclipse.ice.client.internal.Client">
class="org.eclipse.ice.client.internal.ClientExtensionFactory">
</client>
</extension>
<extension
......
......@@ -43,8 +43,10 @@ import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.EditorPart;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -67,7 +69,8 @@ import org.slf4j.LoggerFactory;
*/
public class Client extends EditorPart
implements IUpdateEventListener, IProcessEventListener,
ISimpleResourceProvider, IWidgetClosedListener, IClient {
ISimpleResourceProvider, IWidgetClosedListener,
IClient, BundleActivator {
/**
* Logger for handling event messages and other information.
......@@ -143,6 +146,12 @@ public class Client extends EditorPart
*/
private ServiceReference<ICore> iCoreServiceRef;
/**
* This is the service registration used to register the Client as a service
* of the OSGi framework.
*/
private ServiceRegistration<IClient> registration;
/**
* <p>
* The Constructor
......@@ -173,12 +182,6 @@ public class Client extends EditorPart
statusMessageMap.put(FormStatus.Unacceptable,
"This Form will not be " + "processed or updated. It should be considered read-only.");
// Get the widgets factory service by using the Workbench. This is a
// good way to do it that prevents the ResourcesPlugin from being called
// prematurely.
IWidgetFactory factory = PlatformUI.getWorkbench().getService(IWidgetFactory.class);
setUIWidgetFactory(factory);
// Set the reference to this in the Singleton for the widget classes to
// retrieve as needed.
ClientHolder.setClient(this);
......@@ -191,32 +194,64 @@ public class Client extends EditorPart
* @param context
* the bundle's context from the OSGi
*/
public void start(BundleContext context) {
@Override
public void start(BundleContext context) throws Exception {
// Store the bundle context
this.context = context;
// Acquire the Core service if it is available
iCoreServiceRef = context.getServiceReference(ICore.class);
if (iCoreServiceRef != null) {
logger.info("Retrieving ICore for the client.");
iCore = context.getService(iCoreServiceRef);
logger.info("Core service set.");
} else {
// Failure to get the core is a catastrophic error.
logger.error("Unable to access core!.");
}
// Get the widgets factory service by using the Workbench. This is a
// good way to do it that prevents the ResourcesPlugin from being called
// prematurely.
IWidgetFactory factory = PlatformUI.getWorkbench()
.getService(IWidgetFactory.class);
setUIWidgetFactory(factory);
// I realize how hilarious it is to use two different mechanisms for
// acquiring services here. FIXME! This is just testing for now.
// Register this class as a service with the framework.
registration = context.registerService(IClient.class, this, null);
return;
}
/**
* This operation releases the ICore service references and stops the Client
* service.
*
* @param context
* the bundle's context from the OSGi
*/
public void stop() {
@Override
public void stop(BundleContext context) throws Exception {
// Release the service reference
if (iCoreServiceRef != null) {
context.ungetService(iCoreServiceRef);
}
// Unregister this service from the framework
registration.unregister();
return;
}
/**
* This operation grabs and sets the iCore if it is not already available.
*/
public ICore getCore() {
if (iCore == null) {
logger.info("IClient Message: Retrieving ICore for the client.");
iCore = PlatformUI.getWorkbench().getService(ICore.class);
logger.info("IClient Message: Core service set.");
}
return iCore;
}
......
/*******************************************************************************
* Copyright (c) 2013, 2014- UT-Battelle, LLC.
* 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:
* Initial API and implementation and/or initial documentation -
* Jay Jay Billings
*******************************************************************************/
package org.eclipse.ice.client.internal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IExecutableExtensionFactory;
import org.eclipse.ice.iclient.IClient;
import org.eclipse.ui.PlatformUI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class is responsible for obtaining as part of the Extension Registry and
* as a singleton. It just sneaks into the OSGi backend using the PlatformUI to
* grab the service.
*
* @author Jay Jay Billings
*
*/
public class ClientExtensionFactory
implements IExecutableExtensionFactory {
/**
* Logger for handling event messages and other information.
*/
private static final Logger logger = LoggerFactory
.getLogger(ClientExtensionFactory.class);
/**
* The Client
*/
private static IClient client;
/**
* The constructor
*/
public ClientExtensionFactory() {
// Nothing to do
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.IExecutableExtensionFactory#create()
*/
@Override
public Object create() throws CoreException {
// Create the provider if it doesn't exist already
if (client == null) {
client = PlatformUI.getWorkbench().getService(IClient.class);
logger.debug("Reacquiring client service throw extension factory.");
}
return client;
}
}
......@@ -18,20 +18,20 @@ import java.util.ArrayList;
import javax.ws.rs.core.MediaType;
import org.eclipse.ice.core.iCore.ICore;
import org.eclipse.core.resources.IProject;
import org.eclipse.ice.core.iCore.ICore;
import org.eclipse.ice.datastructures.ICEObject.ICEList;
import org.eclipse.ice.datastructures.ICEObject.Identifiable;
import org.eclipse.ice.datastructures.form.Form;
import org.eclipse.ice.datastructures.form.FormStatus;
import org.eclipse.ice.item.ICompositeItemBuilder;
import org.eclipse.ice.item.ItemBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>
......@@ -260,17 +260,6 @@ public class RemoteCoreProxy implements ICore {
}
/**
* (non-Javadoc)
*
* @see ICore#getFileSystem(int uniqueClientID)
*/
@Override
public Form getFileSystem(int uniqueClientID) {
// TODO Auto-generated method stub
return null;
}
/**
* (non-Javadoc)
*
......
......@@ -507,22 +507,6 @@ public class CoreTester {
return;
}
/**
* <p>
* checkFS() checks Core's ability to return a valid file system
* representation.
* </p>
*
*/
@Test
public void checkFS() {
// Assert getFileSystem returns a valid Form
assertNotNull(this.iCECore.getFileSystem(1));
return;
}
/**
* This operation checks the Core's ability to make a client connection with
* a given username, password, and Client ID.
......
......@@ -40,3 +40,5 @@ Require-Bundle: org.eclipse.equinox.http.jetty;bundle-version="2.0.100",
org.eclipse.equinox.servletbridge;bundle-version="1.2.100"
Bundle-Vendor: Oak Ridge National Laboratory
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.eclipse.ice.core.internal.Core
Eclipse-LazyStart: true
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="false" name="org.eclipse.ice.core">
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true" immediate="false" name="org.eclipse.ice.core">
<implementation class="org.eclipse.ice.core.internal.Core"/>
<service>
<provide interface="org.eclipse.ice.core.iCore.ICore"/>
</service>
<reference bind="registerCompositeItem" cardinality="0..n" interface="org.eclipse.ice.item.ICompositeItemBuilder" name="ICompositeItemBuilder" policy="dynamic" unbind="unregisterItem"/>
<reference bind="setHttpService" cardinality="0..1" interface="org.osgi.service.http.HttpService" name="HttpService" policy="dynamic"/>
<reference bind="setIOService" cardinality="1..1" interface="org.eclipse.ice.io.serializable.IOService" name="IOService" policy="static"/>
</scr:component>
......@@ -72,17 +72,6 @@ public interface ICore {
*/
public void disconnect(int uniqueClientId);
/**
* This operation retrieves the workspace file system available to the
* ICEUser. It returns a Form that contains the directory structure.
*
* @param uniqueClientID
* The unique ID of the Client calling the operation.
* @return A Form that contains a description of the workspace file system
* available to the ICEUser.
*/
public Form getFileSystem(int uniqueClientID);
/**
* This operation registers an ItemBuilder and thereby a particular Item
* class with the Core. This operation is primarily used by the underlying
......
......@@ -36,7 +36,6 @@ import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
......@@ -58,7 +57,10 @@ import org.eclipse.ice.item.ItemBuilder;
import org.eclipse.ice.item.SerializedItemBuilder;
import org.eclipse.ice.item.messaging.Message;
import org.osgi.framework.Bundle;
import org.osgi.service.component.ComponentContext;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
......@@ -85,7 +87,7 @@ import com.sun.jersey.spi.container.servlet.ServletContainer;
* @author Jay Jay Billings
*/
@ApplicationPath("/ice")
public class Core extends Application implements ICore {
public class Core extends Application implements ICore, BundleActivator {
/**
* Logger for handling event messages and other information.
......@@ -102,7 +104,7 @@ public class Core extends Application implements ICore {
* The component context for the ICE Core OSGi component.
*
*/
private ComponentContext componentContext;
private BundleContext bundleContext;
/**
* The master table of IProject Eclipse projects, keyed by username.
......@@ -115,13 +117,16 @@ public class Core extends Application implements ICore {
*/
private IProject itemDBProject;
/**
* The ServiceReference used to track the HTTP service.
*/
private ServiceReference<HttpService> httpServiceRef;
/**
* The OSGi HTTP Service used by the Core to publish itself.
*/
private HttpService httpService;
String id = "org.eclipse.ice.item.itemBuilder";
/**
* The string identifying the Item Builder extension point.
*/
......@@ -146,6 +151,12 @@ public class Core extends Application implements ICore {
*/
private AtomicBoolean updateLock;
/**
* This is the service registration used to register the Core as a service
* of the OSGi framework.
*/
private ServiceRegistration<ICore> registration;
/**
* An alternative constructor that allows the Core to be constructed with a
* particular ItemManager. This is used for testing.
......@@ -234,10 +245,11 @@ public class Core extends Application implements ICore {
* @param context
* The bundle context for this OSGi bundle.
*/
public void start(ComponentContext context) throws CoreException {
@Override
public void start(BundleContext context) throws CoreException {
// Store the component's context
componentContext = context;
bundleContext = context;
logger.info("ICore Message: Component context set!");
......@@ -262,7 +274,7 @@ public class Core extends Application implements ICore {
// Load up the
ItemBuilder builder = null;
point = Platform.getExtensionRegistry().getExtensionPoint(id);
point = Platform.getExtensionRegistry().getExtensionPoint(builderID);
// If the point is available, create all the builders and load them into
// the Item Manager.
......@@ -275,7 +287,7 @@ public class Core extends Application implements ICore {
registerItem(builder);
}
} else {
logger.error("Extension Point " + id + "does not exist");
logger.error("Extension Point " + builderID + "does not exist");
}
// Set the default project on the Persistence Provider
......@@ -291,10 +303,31 @@ public class Core extends Application implements ICore {
// Check the currently registered extensions
debugCheckExtensions();
// Register this class as a service with the framework.
registration = context.registerService(ICore.class, this, null);
return;
}
/*
* (non-Javadoc)
*
* @see
* org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext context) throws Exception {
// Update everything in the ItemManager that requires it
itemManager.persistItems();
// Unregister with the HTTP Service
bundleContext.ungetService(httpServiceRef);
// Unregister this service from the framework
registration.unregister();