Issue #239 Added persistence capability to Collaboration data events

Former-commit-id: 39e1cc313eae6df99483cc657c39cdd5e3d24533
This commit is contained in:
Max Schenkelberg 2012-04-24 13:44:16 -05:00
parent fa360c90cf
commit 32ade1a1f7
28 changed files with 703 additions and 286 deletions

View file

@ -25,6 +25,7 @@ import com.raytheon.uf.common.dataplugin.radar.RadarRecord;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
/**
* Event class used to specify the creation of a radar radial mesh
@ -43,7 +44,8 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
* @version 1.0
*/
@DynamicSerialize
public class CreateRadarRadialMesh extends AbstractDispatchingObjectEvent {
public class CreateRadarRadialMesh extends AbstractDispatchingObjectEvent
implements ICreationEvent {
@DynamicSerializeElement
private Integer numBins;

View file

@ -22,6 +22,7 @@ package com.raytheon.uf.viz.collaboration.radar.mosaic;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapParametersEvent;
/**
@ -41,7 +42,8 @@ import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapParamet
* @version 1.0
*/
@DynamicSerialize
public class CreateMosaicImageEvent extends AbstractDispatchingObjectEvent {
public class CreateMosaicImageEvent extends AbstractDispatchingObjectEvent
implements ICreationEvent {
@DynamicSerializeElement
private int[] bounds;

View file

@ -18,7 +18,8 @@ Require-Bundle: com.raytheon.viz.ui,
org.geotools;bundle-version="2.6.4",
com.raytheon.viz.core;bundle-version="1.12.1174",
com.raytheon.uf.viz.drawing;bundle-version="1.0.0",
com.raytheon.uf.viz.remote.graphics;bundle-version="1.0.0"
com.raytheon.uf.viz.remote.graphics;bundle-version="1.0.0",
com.raytheon.uf.common.comm;bundle-version="1.12.1174"
Import-Package: com.raytheon.uf.common.status,
com.raytheon.uf.viz.core.maps.display,
com.raytheon.uf.viz.core.maps.rsc,

View file

@ -19,9 +19,13 @@
**/
package com.raytheon.uf.viz.collaboration.ui.role;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Event;
import org.hibernate.InstantiationException;
import com.google.common.eventbus.Subscribe;
import com.raytheon.uf.common.status.IUFStatusHandler;
@ -83,6 +87,8 @@ public class DataProviderEventController extends AbstractRoleEventController {
private ResourceWrapperListener wrappingListener;
private List<CollaborationDispatcher> dispatchers = new LinkedList<CollaborationDispatcher>();
public DataProviderEventController(ISharedDisplaySession session) {
super(session);
}
@ -250,8 +256,18 @@ public class DataProviderEventController extends AbstractRoleEventController {
DispatchingGraphicsFactory.injectRemoteFunctionality(container,
new DispatcherFactory() {
@Override
public Dispatcher createNewDispatcher() {
return new CollaborationDispatcher(session);
public Dispatcher createNewDispatcher()
throws InstantiationException {
try {
CollaborationDispatcher dispatcher = new CollaborationDispatcher(
session);
dispatchers.add(dispatcher);
return dispatcher;
} catch (CollaborationException e) {
throw new InstantiationException(
"Error creation collaboration dispatcher",
CollaborationDispatcher.class, e);
}
}
});
try {
@ -353,6 +369,10 @@ public class DataProviderEventController extends AbstractRoleEventController {
.extractRemoteFunctionality(container);
}
}
for (CollaborationDispatcher dispatcher : dispatchers) {
dispatcher.dispose();
}
// TODO should remove the SharedEditorIndiciatorRsc
}

View file

@ -161,6 +161,7 @@ public class ParticipantEventController extends AbstractRoleEventController {
private void initializeResources(IDescriptor desc) {
CollaborationResourceData crd = new CollaborationResourceData();
crd.setSession(session);
ResourcePair rp = ResourcePair.constructSystemResourcePair(crd);
desc.getResourceList().add(rp);
desc.getResourceList().instantiateResources(desc, true);

View file

@ -26,6 +26,8 @@ import com.raytheon.uf.viz.collaboration.ui.Activator;
import com.raytheon.uf.viz.core.jobs.JobPool;
import com.raytheon.uf.viz.remote.graphics.AbstractRemoteGraphicsEvent;
import com.raytheon.uf.viz.remote.graphics.Dispatcher;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
import com.raytheon.uf.viz.remote.graphics.events.IRenderEvent;
/**
@ -47,14 +49,21 @@ import com.raytheon.uf.viz.remote.graphics.events.IRenderEvent;
public class CollaborationDispatcher extends Dispatcher {
private static JobPool persistPool = new JobPool("Persister", 4, true);
private static JobPool persistPool = new JobPool("Persister", 1, true);
private ISharedDisplaySession session;
public CollaborationDispatcher(ISharedDisplaySession session) {
private IObjectEventPersistance persistance;
public CollaborationDispatcher(ISharedDisplaySession session)
throws CollaborationException {
this.session = session;
this.persistance = CollaborationObjectEventStorage
.createPersistanceObject(session);
}
private static final boolean PERSISTENCE = false;
/*
* (non-Javadoc)
*
@ -63,22 +72,32 @@ public class CollaborationDispatcher extends Dispatcher {
* uf.viz.remote.graphics.AbstractRemoteGraphicsEvent)
*/
@Override
public void dispatch(final AbstractRemoteGraphicsEvent eventObject) {
if (eventObject instanceof IRenderEvent == false) {
final PersistedObjectEvent persist = HttpPersistedObjectEvent
.createNewObject(session.getSessionId());
public void dispatch(AbstractRemoteGraphicsEvent eventObject) {
// Set PERSISTENCE to true if testing persisting capabilities
if (PERSISTENCE
&& eventObject instanceof AbstractDispatchingObjectEvent
&& eventObject instanceof IRenderEvent == false) {
final AbstractDispatchingObjectEvent toPersist = (AbstractDispatchingObjectEvent) eventObject;
persistPool.schedule(new Runnable() {
@Override
public void run() {
try {
persist.store(eventObject);
send(persist);
IPersistedEvent event = persistance
.persistEvent(toPersist);
// Creation events are sent immediately to avoid false
// negatives
if (toPersist instanceof ICreationEvent == false) {
send(event);
}
} catch (CollaborationException e) {
Activator.statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
}
}
});
if (eventObject instanceof ICreationEvent) {
send(eventObject);
}
} else {
send(eventObject);
}
@ -92,4 +111,13 @@ public class CollaborationDispatcher extends Dispatcher {
e.getLocalizedMessage(), e);
}
}
public void dispose() {
try {
persistance.dispose();
} catch (CollaborationException e) {
Activator.statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
}
}
}

View file

@ -0,0 +1,282 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.role.event;
import java.net.URI;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ByteArrayEntity;
import com.raytheon.uf.common.comm.HttpClient;
import com.raytheon.uf.common.comm.HttpClient.HttpClientResponse;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SerializationUtil;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession;
import com.raytheon.uf.viz.collaboration.comm.provider.Tools;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
/**
* Class responsible for object event storage. Will persist/retrieve objects
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 20, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class CollaborationObjectEventStorage implements
IObjectEventPersistance, IObjectEventRetrieval {
private volatile long EVENT_ID_COUNTER = 0;
public static IObjectEventPersistance createPersistanceObject(
ISharedDisplaySession session) throws CollaborationException {
CollaborationObjectEventStorage persistance = new CollaborationObjectEventStorage(
session);
persistance.setupStorage();
return persistance;
}
public static IObjectEventRetrieval createRetrievalObject(
ISharedDisplaySession session) {
return new CollaborationObjectEventStorage(session);
}
private ISharedDisplaySession session;
// TODO: Get Collaboration server to build URL
private String baseUrl = "http://edexproxy:9582/collab/";
private HttpClient client;
private CollaborationObjectEventStorage(ISharedDisplaySession session) {
this.session = session;
this.client = HttpClient.getInstance();
}
private void setupStorage() throws CollaborationException {
createFolder(session.getSessionId());
// Successful creation of session folder, add to base url
baseUrl += session.getSessionId() + "/";
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventPersistance
* #persistEvent
* (com.raytheon.uf.viz.remote.graphics.AbstractRemoteGraphicsEvent)
*/
@Override
public IPersistedEvent persistEvent(AbstractDispatchingObjectEvent event)
throws CollaborationException {
if (event instanceof ICreationEvent) {
createFolder(String.valueOf(event.getObjectId()));
} else if (event instanceof DisposeObjectEvent) {
deleteResource(URI.create(baseUrl + event.getObjectId() + "/"));
CollaborationWrappedEvent wrapped = new CollaborationWrappedEvent();
wrapped.setEvent(event);
return wrapped;
}
try {
CollaborationHttpPersistedEvent wrapped = new CollaborationHttpPersistedEvent();
String eventObjectURL = baseUrl + event.getObjectId() + "/"
+ (++EVENT_ID_COUNTER) + ".obj";
HttpPut put = new HttpPut(eventObjectURL);
put.setEntity(new ByteArrayEntity(Tools.compress(SerializationUtil
.transformToThrift(event))));
HttpClientResponse response = executeRequest(put);
if (response.code != 201) {
throw new CollaborationException(
"Error uploading event object to server @ "
+ eventObjectURL + " : "
+ new String(response.data));
}
wrapped.setResourceURL(eventObjectURL);
return wrapped;
} catch (CollaborationException e) {
throw e;
} catch (Exception e) {
throw new CollaborationException(e);
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventPersistance
* #dispose()
*/
@Override
public void dispose() throws CollaborationException {
deleteResource(URI.create(baseUrl));
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval
* #retrieveEvent
* (com.raytheon.uf.viz.collaboration.ui.role.event.IPersistedEvent)
*/
@Override
public AbstractDispatchingObjectEvent retrieveEvent(IPersistedEvent event)
throws CollaborationException {
if (event instanceof CollaborationHttpPersistedEvent) {
String objectURL = ((CollaborationHttpPersistedEvent) event)
.getResourceURL();
HttpGet get = new HttpGet(objectURL);
HttpClientResponse response = executeRequest(get);
if (response.code == 200) {
try {
return (AbstractDispatchingObjectEvent) SerializationUtil
.transformFromThrift(Tools
.uncompress(response.data));
} catch (SerializationException e) {
throw new CollaborationException(e);
}
} else {
throw new CollaborationException(
"Error retrieving object from url " + objectURL + " : "
+ new String(response.data));
}
} else if (event instanceof CollaborationWrappedEvent) {
return ((CollaborationWrappedEvent) event).getEvent();
} else {
throw new CollaborationException(
"Unable to retreieve event for object: " + event);
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval
* #retrieveObjectEvents(int)
*/
@Override
public AbstractDispatchingObjectEvent[] retrieveObjectEvents(int objectId)
throws CollaborationException {
// TODO: Retrieve all events for the given objectId
throw new CollaborationException(
"Retrieving objects for creation is not supported yet!");
}
private void createFolder(String folderPath) throws CollaborationException {
HttpRequestBase mkcol = new HttpRequestBase() {
@Override
public String getMethod() {
return "MKCOL";
}
};
mkcol.setURI(URI.create(baseUrl + folderPath));
HttpClientResponse rsp = executeRequest(mkcol);
if (rsp.code != 201) {
throw new CollaborationException("Folder creation failed for "
+ folderPath + ": " + new String(rsp.data));
}
}
private void deleteResource(URI uri) throws CollaborationException {
HttpClientResponse rsp = executeRequest(new HttpDelete(uri));
// Valid DELETE return codes are 200, 202, and 204
if (rsp.code != 200 && rsp.code != 202 && rsp.code != 204) {
throw new CollaborationException("Folder creation failed for "
+ uri + ": " + new String(rsp.data));
}
}
private HttpClientResponse executeRequest(HttpUriRequest request)
throws CollaborationException {
try {
return client.executeRequest(request);
} catch (Exception e) {
throw new CollaborationException(e);
}
}
@DynamicSerialize
public static class CollaborationHttpPersistedEvent implements
IPersistedEvent {
@DynamicSerializeElement
private String resourceURL;
/**
* @return the resourceURL
*/
public String getResourceURL() {
return resourceURL;
}
/**
* @param resourceURL
* the resourceURL to set
*/
public void setResourceURL(String resourceURL) {
this.resourceURL = resourceURL;
}
}
@DynamicSerialize
public static class CollaborationWrappedEvent implements IPersistedEvent {
@DynamicSerializeElement
private AbstractDispatchingObjectEvent event;
/**
* @return the event
*/
public AbstractDispatchingObjectEvent getEvent() {
return event;
}
/**
* @param event
* the event to set
*/
public void setEvent(AbstractDispatchingObjectEvent event) {
this.event = event;
}
}
}

View file

@ -1,151 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.role.event;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.remote.graphics.AbstractRemoteGraphicsEvent;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 19, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
@DynamicSerialize
public class HttpPersistedObjectEvent extends PersistedObjectEvent {
private static long eventIdCounter = 0;
public static synchronized HttpPersistedObjectEvent createNewObject(
String sessionId) {
HttpPersistedObjectEvent event = new HttpPersistedObjectEvent();
event.sessionId = sessionId;
event.eventId = ++eventIdCounter;
return event;
}
@DynamicSerializeElement
private String sessionId;
@DynamicSerializeElement
private int objectId;
@DynamicSerializeElement
private long eventId;
@DynamicSerializeElement
private AbstractRemoteGraphicsEvent event;
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.ui.role.event.IPersistedObjectEvent
* #store(com.raytheon.uf.viz.remote.graphics.AbstractRemoteGraphicsEvent)
*/
@Override
public void store(AbstractRemoteGraphicsEvent event) {
this.event = event;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.ui.role.event.IPersistedObjectEvent
* #retrieve()
*/
@Override
public AbstractRemoteGraphicsEvent retrieve() {
return event;
}
/**
* @return the sessionId
*/
public String getSessionId() {
return sessionId;
}
/**
* @param sessionId
* the sessionId to set
*/
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
/**
* @return the objectId
*/
public int getObjectId() {
return objectId;
}
/**
* @param objectId
* the objectId to set
*/
public void setObjectId(int objectId) {
this.objectId = objectId;
}
/**
* @return the eventId
*/
public long getEventId() {
return eventId;
}
/**
* @param eventId
* the eventId to set
*/
public void setEventId(long eventId) {
this.eventId = eventId;
}
/**
* @return the event
*/
public AbstractRemoteGraphicsEvent getEvent() {
return event;
}
/**
* @param event
* the event to set
*/
public void setEvent(AbstractRemoteGraphicsEvent event) {
this.event = event;
}
}

View file

@ -0,0 +1,48 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.role.event;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
/**
* Interface for persisting remote object events
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 20, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public interface IObjectEventPersistance {
public IPersistedEvent persistEvent(AbstractDispatchingObjectEvent event)
throws CollaborationException;
public void dispose() throws CollaborationException;
}

View file

@ -19,14 +19,12 @@
**/
package com.raytheon.uf.viz.collaboration.ui.role.event;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.remote.graphics.AbstractRemoteGraphicsEvent;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
/**
* Interface for defining an object that can retrieve and store a single object.
* Implementing objects need to be serializable so they can be sent over to
* participants and retrieve their data
* Interface for retrieving IPersistedEvents and constructing an object from id
* based on previous events
*
* <pre>
*
@ -34,20 +32,20 @@ import com.raytheon.uf.viz.remote.graphics.AbstractRemoteGraphicsEvent;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 19, 2012 mschenke Initial creation
* Apr 20, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
@DynamicSerialize
public abstract class PersistedObjectEvent {
public abstract void store(AbstractRemoteGraphicsEvent event)
public interface IObjectEventRetrieval {
public AbstractDispatchingObjectEvent retrieveEvent(IPersistedEvent event)
throws CollaborationException;
public abstract AbstractRemoteGraphicsEvent retrieve()
public AbstractDispatchingObjectEvent[] retrieveObjectEvents(int objectId)
throws CollaborationException;
}

View file

@ -0,0 +1,42 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.role.event;
/**
* Interface for distinguishing events that are persisted and should be
* retrieved
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 20, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public interface IPersistedEvent {
}

View file

@ -30,7 +30,7 @@ import com.google.common.eventbus.Subscribe;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.collaboration.ui.Activator;
import com.raytheon.uf.viz.collaboration.ui.role.event.PersistedObjectEvent;
import com.raytheon.uf.viz.collaboration.ui.role.event.IPersistedEvent;
import com.raytheon.uf.viz.collaboration.ui.rsc.rendering.CollaborationRenderingDataManager;
import com.raytheon.uf.viz.collaboration.ui.rsc.rendering.CollaborationRenderingHandler;
import com.raytheon.uf.viz.core.IGraphicsTarget;
@ -69,7 +69,7 @@ public class CollaborationResource extends
AbstractVizResource<CollaborationResourceData, IDescriptor> implements
IContextMenuProvider {
private static JobPool retrievePool = new JobPool("Retriever", 4, true);
private static JobPool retrievePool = new JobPool("Retriever", 1, true);
/** List of objects rendered in paint */
private List<IRenderEvent> currentRenderables;
@ -134,7 +134,8 @@ public class CollaborationResource extends
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
renderingRouter = new EventBus();
dataManager = new CollaborationRenderingDataManager();
dataManager = new CollaborationRenderingDataManager(
resourceData.getSession());
for (CollaborationRenderingHandler handler : CollaborationRenderingDataManager
.createRenderingHandlers(dataManager)) {
renderingRouter.register(handler);
@ -142,12 +143,12 @@ public class CollaborationResource extends
}
@Subscribe
public void persitableArrived(final PersistedObjectEvent event) {
public void persitableArrived(final IPersistedEvent event) {
retrievePool.schedule(new Runnable() {
@Override
public void run() {
try {
renderableArrived(event.retrieve());
renderableArrived(dataManager.retrieveEvent(event));
} catch (CollaborationException e) {
Activator.statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);

View file

@ -19,10 +19,12 @@
**/
package com.raytheon.uf.viz.collaboration.ui.rsc;
import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
/**
@ -44,6 +46,8 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties;
public class CollaborationResourceData extends AbstractResourceData {
private ISharedDisplaySession session;
/*
* (non-Javadoc)
*
@ -67,21 +71,48 @@ public class CollaborationResourceData extends AbstractResourceData {
*/
@Override
public void update(Object updateData) {
// TODO Auto-generated method stub
fireChangeListeners(ChangeType.DATA_UPDATE, updateData);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.AbstractResourceData#equals(java.lang.Object
* )
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return 31;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return false;
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
return true;
}
/**
* @return the session
*/
public ISharedDisplaySession getSession() {
return session;
}
/**
* @param session
* the session to set
*/
public void setSession(ISharedDisplaySession session) {
this.session = session;
}
}

View file

@ -36,9 +36,15 @@ import org.eclipse.core.runtime.Platform;
import com.google.common.eventbus.EventBus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession;
import com.raytheon.uf.viz.collaboration.ui.Activator;
import com.raytheon.uf.viz.collaboration.ui.role.event.CollaborationObjectEventStorage;
import com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval;
import com.raytheon.uf.viz.collaboration.ui.role.event.IPersistedEvent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
/**
* Collaboration rendering data manager, manages render data and render handlers
@ -57,7 +63,7 @@ import com.raytheon.uf.viz.core.drawables.PaintProperties;
* @version 1.0
*/
public class CollaborationRenderingDataManager {
public class CollaborationRenderingDataManager implements IObjectEventRetrieval {
private static final String RENDERING_EXTENSION = "com.raytheon.uf.viz.collaboration.ui.renderingExtension";
@ -88,8 +94,12 @@ public class CollaborationRenderingDataManager {
private EventBus disposerRouter;
public CollaborationRenderingDataManager() {
private IObjectEventRetrieval retrieval;
public CollaborationRenderingDataManager(ISharedDisplaySession session) {
this.disposerRouter = new EventBus();
this.retrieval = CollaborationObjectEventStorage
.createRetrievalObject(session);
}
/**
@ -189,6 +199,33 @@ public class CollaborationRenderingDataManager {
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval
* #retrieveEvent
* (com.raytheon.uf.viz.collaboration.ui.role.event.IPersistedEvent)
*/
@Override
public AbstractDispatchingObjectEvent retrieveEvent(IPersistedEvent event)
throws CollaborationException {
return retrieval.retrieveEvent(event);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval
* #retrieveObjectEvents(int)
*/
@Override
public AbstractDispatchingObjectEvent[] retrieveObjectEvents(int objectId)
throws CollaborationException {
return retrieval.retrieveObjectEvents(objectId);
}
/**
* @param dataManager
* @return

View file

@ -510,7 +510,7 @@ public abstract class Tools {
return unMarshalledData;
}
private static byte[] compress(byte[] bytes) throws CollaborationException {
public static byte[] compress(byte[] bytes) throws CollaborationException {
ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length);
CompressionType cType = COMPRESSION_TYPE;
@ -550,8 +550,7 @@ public abstract class Tools {
return stream;
}
private static byte[] uncompress(byte[] bytes)
throws CollaborationException {
public static byte[] uncompress(byte[] bytes) throws CollaborationException {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
ByteArrayOutputStream out = new ByteArrayOutputStream();

View file

@ -6,7 +6,6 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.remote.graphics.Activator
Bundle-Vendor: RAYTHEON
Eclipse-RegisterBuddy: com.raytheon.uf.viz.core
Eclipse-BuddyPolicy: ext, global
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
com.raytheon.uf.viz.core;bundle-version="1.12.1174",

View file

@ -44,6 +44,6 @@ public interface DispatcherFactory {
*
* @return
*/
public Dispatcher createNewDispatcher();
public Dispatcher createNewDispatcher() throws InstantiationException;
}

View file

@ -154,15 +154,19 @@ public class DispatchingGraphicsFactory extends AbstractGraphicsFactoryAdapter {
public static void injectRemoteFunctionality(
IDisplayPaneContainer container, DispatcherFactory factory) {
for (IDisplayPane pane : container.getDisplayPanes()) {
Dispatcher dispatcher = factory.createNewDispatcher();
// Wrap view in dispatching view
IRenderableDisplay display = pane.getRenderableDisplay();
// Wrap the graphics adapter in dispatching one
display.setGraphicsAdapter(new DispatchingGraphicsFactory(display
.getGraphicsAdapter(), dispatcher));
refreshPane(pane);
try {
for (IDisplayPane pane : container.getDisplayPanes()) {
Dispatcher dispatcher = factory.createNewDispatcher();
// Wrap view in dispatching view
IRenderableDisplay display = pane.getRenderableDisplay();
// Wrap the graphics adapter in dispatching one
display.setGraphicsAdapter(new DispatchingGraphicsFactory(
display.getGraphicsAdapter(), dispatcher));
refreshPane(pane);
}
} catch (InstantiationException e) {
extractRemoteFunctionality(container);
throw new RuntimeException(e);
}
}

View file

@ -0,0 +1,41 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.remote.graphics.events;
/**
* Interface for object creation events
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 20, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public interface ICreationEvent {
}

View file

@ -22,6 +22,7 @@ package com.raytheon.uf.viz.remote.graphics.events.colormap;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
/**
* TODO Add Description
@ -40,7 +41,8 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
* @version 1.0
*/
@DynamicSerialize
public class CreateColormappedImageEvent extends AbstractDispatchingObjectEvent {
public class CreateColormappedImageEvent extends AbstractDispatchingObjectEvent
implements ICreationEvent {
@DynamicSerializeElement
private UpdateColorMapParametersEvent colorMapParameters;

View file

@ -23,6 +23,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.core.drawables.IFont.Style;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
/**
* Event for creating a font object
@ -41,7 +42,8 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
* @version 1.0
*/
@DynamicSerialize
public class CreateFontEvent extends AbstractDispatchingObjectEvent {
public class CreateFontEvent extends AbstractDispatchingObjectEvent implements
ICreationEvent {
@DynamicSerializeElement
private byte[] fontData;

View file

@ -21,6 +21,7 @@ package com.raytheon.uf.viz.remote.graphics.events.imagery;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
/**
* Event for creating an IImage object
@ -39,6 +40,7 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
* @version 1.0
*/
@DynamicSerialize
public class CreateIImageEvent extends AbstractDispatchingObjectEvent {
public class CreateIImageEvent extends AbstractDispatchingObjectEvent implements
ICreationEvent {
}

View file

@ -20,6 +20,7 @@
package com.raytheon.uf.viz.remote.graphics.events.imagery;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
/**
* TODO Add Description
@ -38,6 +39,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
* @version 1.0
*/
@DynamicSerialize
public class CreateSingleColorImage extends UpdateSingleColorImage {
public class CreateSingleColorImage extends UpdateSingleColorImage implements
ICreationEvent {
}

View file

@ -23,10 +23,8 @@ import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.media.jai.remote.SerializableRenderedImage;
import javax.imageio.ImageIO;
import com.raytheon.uf.common.serialization.IDeserializationContext;
import com.raytheon.uf.common.serialization.ISerializationContext;
@ -71,15 +69,10 @@ public class RenderedImageWrapper {
public void serialize(ISerializationContext serializer,
RenderedImageWrapper object) throws SerializationException {
RenderedImage image = object.getWrappedImage();
if (image instanceof SerializableRenderedImage == false) {
image = new SerializableRenderedImage(image);
}
// serialize rendered image into bytes
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bytes);
oos.writeObject(image);
oos.close();
ImageIO.write(image, "png", bytes);
serializer.writeBinary(bytes.toByteArray());
} catch (IOException e) {
throw new SerializationException(
@ -102,10 +95,8 @@ public class RenderedImageWrapper {
byte[] data = deserializer.readBinary();
// deserialize bytes into rendered image
try {
ObjectInputStream oin = new ObjectInputStream(
new ByteArrayInputStream(data));
wrapper.setWrappedImage((RenderedImage) oin.readObject());
oin.close();
wrapper.setWrappedImage(ImageIO.read(new ByteArrayInputStream(
data)));
} catch (Exception e) {
throw new SerializationException(
"Error deserializing rendered image: "

View file

@ -25,6 +25,7 @@ import org.geotools.coverage.grid.GridGeometry2D;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
/**
* TODO Add Description
@ -43,7 +44,8 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
* @version 1.0
*/
@DynamicSerialize
public class CreateMeshEvent extends AbstractDispatchingObjectEvent {
public class CreateMeshEvent extends AbstractDispatchingObjectEvent implements
ICreationEvent {
@DynamicSerializeElement
private GridGeometry2D imageGeometry;

View file

@ -22,6 +22,7 @@ package com.raytheon.uf.viz.remote.graphics.events.offscreen;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapParametersEvent;
/**
@ -41,7 +42,8 @@ import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapParamet
* @version 1.0
*/
@DynamicSerialize
public class CreateOffscreenImageEvent extends AbstractDispatchingObjectEvent {
public class CreateOffscreenImageEvent extends AbstractDispatchingObjectEvent
implements ICreationEvent {
@DynamicSerializeElement
private String bufferType;

View file

@ -26,6 +26,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.PixelExtent;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent;
/**
* Event to create a new wireframe shape object
@ -44,7 +45,8 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
* @version 1.0
*/
@DynamicSerialize
public class CreateWireframeShapeEvent extends AbstractDispatchingObjectEvent {
public class CreateWireframeShapeEvent extends AbstractDispatchingObjectEvent
implements ICreationEvent {
@DynamicSerializeElement
private GeneralGridGeometry gridGeometry;

View file

@ -34,6 +34,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.client.entity.GzipDecompressingEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.AbstractHttpClient;
@ -70,6 +71,17 @@ import com.raytheon.uf.common.util.ByteArrayOutputStreamPool.ByteArrayOutputStre
*/
public class HttpClient {
public static class HttpClientResponse {
public final int code;
public final byte[] data;
private HttpClientResponse(int code, byte[] data) {
this.code = code;
this.data = data != null ? data : new byte[0];
}
}
private static final int SUCCESS_CODE = 200;
private final org.apache.http.client.HttpClient client;
@ -216,6 +228,18 @@ public class HttpClient {
private byte[] executePostMethod(HttpPost put) throws IOException,
HttpException, CommunicationException {
HttpClientResponse response = executeRequest(put);
if (response.code != SUCCESS_CODE) {
throw new CommunicationException(
"Error reading server response. Got error message: "
+ response.data != null ? new String(response.data)
: null);
}
return response.data;
}
public HttpClientResponse executeRequest(HttpUriRequest request)
throws IOException, HttpException, CommunicationException {
int tries = 0;
boolean retry = true;
// long ts = System.currentTimeMillis();
@ -225,14 +249,10 @@ public class HttpClient {
tries++;
try {
HttpResponse resp = client.execute(put);
HttpResponse resp = client.execute(request);
int code = resp.getStatusLine().getStatusCode();
if (code != SUCCESS_CODE) {
throw new CommunicationException(
"Error reading server response. Got error message: "
+ EntityUtils.toString(resp.getEntity()));
} else if (previousConnectionFailed) {
if (previousConnectionFailed) {
previousConnectionFailed = false;
statusHandler.handle(Priority.INFO,
"Connection with server reestablished.");
@ -244,70 +264,77 @@ public class HttpClient {
try {
// long t0 = System.currentTimeMillis();
HttpEntity entity = resp.getEntity();
// TODO: print error if entity larger than int, won't be
// able to deserialize
int size = (int) entity.getContentLength();
is = entity.getContent();
byte[] rval = null;
if (size > 0) {
rval = new byte[size];
int read = 0;
int index = 0;
// int count = 0;
do {
read = is.read(rval, index, rval.length - index);
if (entity != null) {
// TODO: print error if entity larger than int, won't be
// able to deserialize
int size = (int) entity.getContentLength();
is = entity.getContent();
if (read > 0) {
index += read;
// count++;
}
} while (read > 0 && index != rval.length);
// long t2 = System.currentTimeMillis();
// System.out.println("ContentLength: Read " +
// rval.length
// + " bytes in " + count + " reads, took"
// + (t2 - t0) + "ms, total round trip "
// + (t2 - ts));
} else {
// grabbing an instance of the pool to use the
// underlying array so as to not create a tmp buffer all
// the time
// TODO: Update edex/jetty to set chunked=false so that
// it sends content length, currently broken as jetty is
// scrambling -128 to 63...
baos = ByteArrayOutputStreamPool.getInstance()
.getStream();
byte[] underlyingArray = baos.getUnderlyingArray();
int read = 0;
int index = 0;
// int count = 0;
do {
read = is.read(underlyingArray, index,
underlyingArray.length - index);
if (size > 0) {
rval = new byte[size];
int read = 0;
int index = 0;
// int count = 0;
do {
read = is
.read(rval, index, rval.length - index);
if (read > 0) {
index += read;
// count++;
if (index == underlyingArray.length) {
baos.setCapacity(underlyingArray.length << 1);
underlyingArray = baos.getUnderlyingArray();
if (read > 0) {
index += read;
// count++;
}
}
} while (read > 0);
} while (read > 0 && index != rval.length);
// long t2 = System.currentTimeMillis();
// System.out.println("ContentLength: Read " +
// rval.length
// + " bytes in " + count + " reads, took"
// + (t2 - t0) + "ms, total round trip "
// + (t2 - ts));
} else {
// grabbing an instance of the pool to use the
// underlying array so as to not create a tmp buffer
// all
// the time
// TODO: Update edex/jetty to set chunked=false so
// that
// it sends content length, currently broken as
// jetty is
// scrambling -128 to 63...
baos = ByteArrayOutputStreamPool.getInstance()
.getStream();
byte[] underlyingArray = baos.getUnderlyingArray();
int read = 0;
int index = 0;
// int count = 0;
do {
read = is.read(underlyingArray, index,
underlyingArray.length - index);
baos.setCount(index);
rval = new byte[index];
System.arraycopy(underlyingArray, 0, rval, 0, index);
// long t2 = System.currentTimeMillis();
// System.out.println("Read " + rval.length +
// " bytes in "
// + count + " reads, took" + (t2 - t0)
// + "ms, total round trip " + (t2 - ts));
if (read > 0) {
index += read;
// count++;
if (index == underlyingArray.length) {
baos.setCapacity(underlyingArray.length << 1);
underlyingArray = baos
.getUnderlyingArray();
}
}
} while (read > 0);
baos.setCount(index);
rval = new byte[index];
System.arraycopy(underlyingArray, 0, rval, 0, index);
// long t2 = System.currentTimeMillis();
// System.out.println("Read " + rval.length +
// " bytes in "
// + count + " reads, took" + (t2 - t0)
// + "ms, total round trip " + (t2 - ts));
}
}
return rval;
return new HttpClientResponse(code, rval);
} finally {
if (baos != null) {
try {
@ -358,8 +385,8 @@ public class HttpClient {
previousConnectionFailed = true;
// close/abort connection
if (put != null) {
put.abort();
if (request != null) {
request.abort();
}
statusHandler.handle(Priority.EVENTA,
"IO error in HttpClient, aborting connection.", e);