All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendof.datatransfer.snapshot.SnapshotProvider Maven / Gradle / Ivy

Go to download

The Java Data Transfer Snapshot Library provides an API for developers to send and receive snapshots of data using OpenDOF protocols.

The newest version!
package org.opendof.datatransfer.snapshot;

import java.util.ArrayList;
import java.util.Hashtable;

import org.opendof.core.oal.DOF;
import org.opendof.core.oal.DOFApplicationErrorException;
import org.opendof.core.oal.DOFException;
import org.opendof.core.oal.DOFInterface;
import org.opendof.core.oal.DOFInterfaceID;
import org.opendof.core.oal.DOFObject;
import org.opendof.core.oal.DOFObjectID;
import org.opendof.core.oal.DOFOperation;
import org.opendof.core.oal.DOFRequest;
import org.opendof.core.oal.DOFSystem;
import org.opendof.core.oal.DOFValue;
import org.opendof.core.oal.value.DOFBlob;
import org.opendof.datatransfer.ValueSet;
import org.opendof.datatransfer.internal.AttributeUtil;
import org.opendof.datatransfer.internal.DataSinkInterface;
import org.opendof.datatransfer.internal.DataSnapshotInterface;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class allows an application to become a provider of snapshot information for objects.
 * 

* The SLF4J library is used for all non-OpenDOF logging. If logging of the OpenDOF OAL library is desired, a logger must * be added to the OAL by calling {@link DOF.Log#addListener}. */ public class SnapshotProvider { private final DOFSystem system; private final SnapshotActivateListener activateListener; private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final ArrayList snapshotInterestListeners = new ArrayList(); private final ArrayList currentActivates = new ArrayList(); private final Hashtable snapshotProviders = new Hashtable(); private boolean isShutdown = false; /** * Terminate and close this instance. */ public void close() { if(isShutdown) return; isShutdown = true; system.removeActivateInterestListener(activateListener); synchronized(snapshotProviders){ for(DataSnapshotInterfaceProvider snapshotProvider : snapshotProviders.values()){ snapshotProvider.close(); } snapshotProviders.clear(); } synchronized(snapshotInterestListeners){ for(SnapshotInterestListener listener : snapshotInterestListeners){ try{ listener.removed(this); } catch (Throwable t){ logger.debug("Exception thrown in callback method SnapshotInterestListener.removed(): " + t, t); } } snapshotInterestListeners.clear(); } synchronized(currentActivates){ currentActivates.clear(); } } /** * Construct a new SnapshotProvider. * @param system The DOFSystem instance allowing this class to use OpenDOF to facilitate network communications. Must not be null. */ public SnapshotProvider(DOFSystem system) { if(system == null) throw new IllegalArgumentException("system == null"); this.system = system; this.activateListener = new SnapshotActivateListener(); system.addActivateInterestListener(activateListener); } /** * Updates the snapshot for a specified object and interface. * This will cause a provide to be started for the snapshot if one does not already exist. * @param objectID The object to which the snapshot applies. Must not be null. * @param interfaceID The interface to which the snapshot applies. Must not be null. * @param snapshot The current snapshot to be sent. This also indicates the definition of the snapshot. Must not be null. * The definition must match any previous definition used for the same object and interface combination. * * @throws Exception Thrown if the provider is unable to send the snapshot update. */ public void send(DOFObjectID objectID, DOFInterfaceID interfaceID, ValueSet.Row snapshot) throws Exception { if(objectID == null) throw new IllegalArgumentException("oid == null"); if(interfaceID == null) throw new IllegalArgumentException("interfaceID == null"); if(isShutdown) throw new IllegalStateException("SnapshotProvider has been terminated."); DOFObjectID providerID = AttributeUtil.getIDWithInterfaceAttribute(objectID, interfaceID); DOFValue value = snapshot.getSnapshot(DataSnapshotInterface.InterfaceID); DataSnapshotInterfaceProvider snapshotProvider = null; synchronized (snapshotProviders) { if(!snapshotProviders.containsKey(providerID)){ snapshotProviders.put(providerID, new DataSnapshotInterfaceProvider(this, system, providerID, snapshot.getDefinition(), value)); return; } snapshotProvider = snapshotProviders.get(providerID); } snapshotProvider.updateValue(value); } // /** // * Updates the snapshot for a specified object. // * This will cause a provide to be started for the snapshot if one does not already exist. // * @param oid The object to which the snapshot applies. The object must contain a session attribute. Must not be null. // * @param snapshot The current snapshot to be sent. This also indicates the definition of the snapshot. Must not be null. // * The definition must match any previous definition used for the same object. // */ // public void send(DOFObjectID oid, ValueSet.Row snapshot) throws DuplicateProvideException { // } /** * Stops the snapshot provider for the specified object and interface. * @param objectID The object for which the snapshot will be stopped. Must not be null. * @param interfaceID The interface for which the snapshot will be stopped. Must not be null. */ public void stop(DOFObjectID objectID, DOFInterfaceID interfaceID) { if(objectID == null) throw new IllegalArgumentException("oid == null"); if(interfaceID == null) throw new IllegalArgumentException("interfaceID == null"); if(isShutdown) throw new IllegalStateException("SnapshotProvider has been terminated."); DOFObjectID providerID = AttributeUtil.getIDWithInterfaceAttribute(objectID, interfaceID); DataSnapshotInterfaceProvider snapshotProvider = null; synchronized(snapshotProviders){ if(!snapshotProviders.containsKey(providerID)){ return; } snapshotProvider = snapshotProviders.remove(providerID); } snapshotProvider.close(); } // /** // * Stops the snapshot provider for the specified object and definition. // * @param oid The object for which the snapshot will be stopped. The object must contain a session attribute. Must not be null. // */ // public void stop(DOFObjectID oid) { // // } /** * Adds a listener, which will receive notifications that there is interest added for a snapshot. * The current set of snapshots with interest will be delivered to the listener when added, and updated over time until removed. * @param listener The listener to be added. Must not be null. */ public void addInterestListener(SnapshotInterestListener listener) { if(listener == null) throw new IllegalArgumentException("listener == null"); synchronized(snapshotInterestListeners){ snapshotInterestListeners.add(listener); } synchronized (currentActivates) { for(DOFObjectID oid : currentActivates){ DOFInterfaceID interfaceID = AttributeUtil.getIIDFromObjectAttribute(oid); DOFObjectID objectID = AttributeUtil.getIDWithoutInterfaceAttribute(oid); try{ listener.snapshotInterestAdded(this, objectID, interfaceID); } catch (Throwable t){ logger.debug("Exception thrown in callback method snapshotInterestAdded(): " + t, t); } } } } /** * Removes a previously added listener. * @param listener The listener to be removed. Must not be null. */ public void removeInterestListener(SnapshotInterestListener listener) { if(listener == null) throw new IllegalArgumentException("listener == null"); synchronized(snapshotInterestListeners){ snapshotInterestListeners.remove(listener); } try{ listener.removed(this); } catch (Throwable t){ logger.debug("Exception thrown in callback method SnapshotInterestListener.removed(): " + t, t); } } private void activateAdded(DOFObjectID objectID){ logger.trace("activateAdded: " + objectID); synchronized (currentActivates) { currentActivates.add(objectID); } DOFInterfaceID interfaceID = AttributeUtil.getIIDFromObjectAttribute(objectID); DOFObjectID oid = AttributeUtil.getIDWithoutInterfaceAttribute(objectID); synchronized(snapshotInterestListeners){ for(SnapshotInterestListener listener : snapshotInterestListeners){ try{ listener.snapshotInterestAdded(this, oid, interfaceID); } catch (Throwable t){ logger.debug("Exception thrown in callback method snapshotInterestAdded(): " + t, t); } } } } private void activateRemoved(DOFObjectID objectID){ logger.trace("activateRemoved: " + objectID); synchronized (currentActivates){ currentActivates.remove(objectID); } DOFInterfaceID interfaceID = AttributeUtil.getIIDFromObjectAttribute(objectID); DOFObjectID oid = AttributeUtil.getIDWithoutInterfaceAttribute(objectID); synchronized(snapshotInterestListeners){ for(SnapshotInterestListener listener : snapshotInterestListeners){ try{ listener.snapshotInterestRemoved(this, oid, interfaceID); } catch (Throwable t){ logger.debug("Exception thrown in callback method snapshotInterestRemoved(): " + t, t); } } } } private class SnapshotActivateListener implements DOFSystem.ActivateInterestListener{ @Override public void activate(DOFSystem system, DOFRequest request, DOFObjectID objectID, DOFInterfaceID interfaceID) { if(!interfaceID.equals(DataSnapshotInterface.InterfaceID)) return; activateAdded(objectID); } @Override public void cancelActivate(DOFSystem system, DOFRequest request, DOFObjectID objectID, DOFInterfaceID interfaceID) { if(!interfaceID.equals(DataSnapshotInterface.InterfaceID)) return; activateRemoved(objectID); } @Override public void removed(DOFSystem system, DOFException exception) { //TODO ? } } private static class DataSnapshotInterfaceProvider extends DOFObject.DefaultProvider { private final SnapshotProvider snapshotProvider; private DOFValue currentValue; private DOFBlob definitionBlob; private DOFObject provider; private DOFOperation.Provide provideOp; public DataSnapshotInterfaceProvider(SnapshotProvider snapshotProvider, DOFSystem system, DOFObjectID objectID, ValueSet.Definition definition, DOFValue startValue) { this.snapshotProvider = snapshotProvider; this.currentValue = startValue; this.definitionBlob = new DOFBlob(definition.getTransferBytes(DataSinkInterface.InterfaceID)); provider = system.createObject(objectID); provideOp = provider.beginProvide(DataSnapshotInterface.DEF, DOF.TIMEOUT_NEVER, this, null); } public void updateValue(DOFValue newValue){ this.currentValue = newValue; provider.changed(DataSnapshotInterface.DEF.getProperty(DataSnapshotInterface.SnapshotItem)); } @Override public void get(DOFOperation.Provide operation, DOFRequest.Get request, DOFInterface.Property property) { try{ if(property.getInterfaceID().equals(DataSnapshotInterface.InterfaceID)){ switch(property.getItemID()){ case DataSnapshotInterface.DefinitionItem: request.respond(definitionBlob); break; case DataSnapshotInterface.SnapshotItem: request.respond(currentValue); } } }catch(Exception e){ request.respond(new DOFApplicationErrorException()); snapshotProvider.logger.warn("Exception in SnapshotProvider get callback method: " + e, e); } } @Override public void subscribe(DOFOperation.Provide operation, DOFRequest.Subscribe request, DOFInterface.Property property, int minPeriod) { try{ snapshotProvider.logger.warn("Subscribe(): {} - {} - {}", operation.getInterface().getInterfaceID(), operation.getObject().getObjectID(), property); request.respond(); }catch(Exception e){ request.respond(new DOFApplicationErrorException()); snapshotProvider.logger.warn("Exception in SnapshotProvider subscribe callback method: " + e, e); } } /** * Terminate and close this instance. */ public void close() { if(provideOp != null) provideOp.cancel(); if(provider != null) provider.destroy(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy