package org.openxdm.xcap.server.slee.resource.datasource; import java.io.Serializable; import java.util.concurrent.ConcurrentHashMap; import javax.slee.Address; import javax.slee.resource.BootstrapContext; import javax.slee.resource.FailureReason; import javax.slee.resource.Marshaler; import javax.slee.resource.ResourceAdaptorTypeID; import javax.slee.resource.ResourceException; import javax.slee.resource.SleeEndpoint; import org.apache.log4j.Logger; import org.mobicents.slee.container.SleeContainer; import org.mobicents.slee.resource.ResourceAdaptorActivityContextInterfaceFactory; import org.mobicents.slee.resource.ResourceAdaptorEntity; import org.mobicents.slee.resource.ResourceAdaptorState; import org.openxdm.xcap.common.datasource.DataSource; import org.openxdm.xcap.common.uri.DocumentSelector; public abstract class AbstractDataSourceResourceAdaptor implements DataSourceResourceAdaptor, Serializable { private static final long serialVersionUID = 1L; private ResourceAdaptorState state; private transient ConcurrentHashMap<ActivityHandle,ActivityObject> activities = new ConcurrentHashMap<ActivityHandle,ActivityObject>(); private transient SleeEndpoint sleeEndpoint; private transient BootstrapContext bootstrapContext; private transient DataSourceSbbInterface sbbInterface; private transient DataSourceActivityContextInterfaceFactory acif; private transient int documentUpdatedEventId; private transient int elementUpdatedEventId; private transient int attributeUpdatedEventId; // SLEE 1.1 RA METHODS public void activityEnded(javax.slee.resource.ActivityHandle ah) { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("activityEnded(ActivityHandle="+ah+")"); } // just remove the handle activities.remove(ah); } public void activityUnreferenced(javax.slee.resource.ActivityHandle ah) { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("activityUnreferenced"); } // no need to keep activities that have no entities attached endActivity((ActivityHandle)ah); } @SuppressWarnings({"deprecation", "unchecked"}) public void entityActivated() throws ResourceException { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("entityActivated"); } if (this.state != ResourceAdaptorState.UNCONFIGURED) { String msg = "Cannot configure RA wrong state: " + this.state; logger.warn(msg); throw new ResourceException(msg); } try { SleeContainer container = SleeContainer.lookupFromJndi(); ResourceAdaptorEntity resourceAdaptorEntity = ((ResourceAdaptorEntity) container .getResourceAdaptorEntity(this.bootstrapContext.getEntityName())); ResourceAdaptorTypeID raTypeId = resourceAdaptorEntity .getInstalledResourceAdaptor().getRaType().getResourceAdaptorTypeID(); this.acif = new DataSourceActivityContextInterfaceFactoryImpl( resourceAdaptorEntity.getServiceContainer(), this.bootstrapContext.getEntityName()); resourceAdaptorEntity.getServiceContainer().getActivityContextInterfaceFactories().put(raTypeId, (ResourceAdaptorActivityContextInterfaceFactory)this.acif); if (this.acif != null) { String jndiName = ((ResourceAdaptorActivityContextInterfaceFactory) this.acif) .getJndiName(); int begind = jndiName.indexOf(':'); int toind = jndiName.lastIndexOf('/'); String prefix = jndiName.substring(begind + 1, toind); String name = jndiName.substring(toind + 1); if (logger.isDebugEnabled()) { logger.debug("jndiName prefix =" + prefix + "; jndiName = " + name); } SleeContainer.registerWithJndi(prefix, name, this.acif); } // init sbb interface interceptor sbbInterface = new DataSourceSbbInterface(this); } catch (Exception ex) { logger.error("entityActivated() failed",ex); throw new ResourceException(ex.getMessage()); } state = ResourceAdaptorState.ACTIVE; } public void entityCreated(BootstrapContext bootstrapContext) throws ResourceException { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("entityCreated"); } this.bootstrapContext = bootstrapContext; this.sleeEndpoint = bootstrapContext.getSleeEndpoint(); try { documentUpdatedEventId = bootstrapContext.getEventLookupFacility().getEventID(DocumentUpdatedEvent.EVENT_NAME,DocumentUpdatedEvent.EVENT_VENDOR,DocumentUpdatedEvent.EVENT_VERSION); elementUpdatedEventId = bootstrapContext.getEventLookupFacility().getEventID(ElementUpdatedEvent.EVENT_NAME,ElementUpdatedEvent.EVENT_VENDOR,ElementUpdatedEvent.EVENT_VERSION); attributeUpdatedEventId = bootstrapContext.getEventLookupFacility().getEventID(AttributeUpdatedEvent.EVENT_NAME,AttributeUpdatedEvent.EVENT_VENDOR,AttributeUpdatedEvent.EVENT_VERSION); } catch (Exception e) { throw new ResourceException(e.getMessage()); } state = ResourceAdaptorState.UNCONFIGURED; } public void entityDeactivated() { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("entityDeactivated"); } if(state != ResourceAdaptorState.UNCONFIGURED) { // end all activities synchronized(activities) { for(ActivityHandle activityHandle: activities.keySet()) { endActivity(activityHandle); } } if (logger.isDebugEnabled()) { logger.debug("All activities ended."); } try { if (this.acif != null) { String jndiName = ((ResourceAdaptorActivityContextInterfaceFactory) this.acif).getJndiName(); //remove "java:" prefix int begind = jndiName.indexOf(':'); String javaJNDIName = jndiName.substring(begind + 1); SleeContainer.unregisterWithJndi(javaJNDIName); } } catch (Exception e) { logger.error("Can't unbind naming context",e); } sbbInterface = null; state = ResourceAdaptorState.UNCONFIGURED; } if (logger.isDebugEnabled()) { logger.debug("Resource Adaptor stopped."); } } public void entityDeactivating() { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("entityDeactivating"); } state = ResourceAdaptorState.STOPPING; } public void entityRemoved() { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("entityRemoved"); } } public void eventProcessingFailed(javax.slee.resource.ActivityHandle arg0, Object arg1, int arg2, Address arg3, int arg4, FailureReason arg5) { getLogger().warn("eventProcessingFailed(ActivityHandle="+arg0+")"); } public void eventProcessingSuccessful(javax.slee.resource.ActivityHandle arg0, Object arg1, int arg2, Address arg3, int arg4) { Logger logger = getLogger(); if(logger.isDebugEnabled()) { getLogger().debug("eventProcessingSuccessful(ActivityHandle="+arg0+")"); } } public Object getActivity(javax.slee.resource.ActivityHandle handle) { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("getActivity(handle="+handle+")"); } return activities.get((ActivityHandle)handle); } public javax.slee.resource.ActivityHandle getActivityHandle(Object activity) { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("getActivity(activity="+activity+")"); } ActivityObject activityObject = (ActivityObject) activity; ActivityHandle activityHandle = new ActivityHandle(activityObject.id); if (activities.containsKey(activityHandle)) { return activityHandle; } else { return null; } } public Marshaler getMarshaler() { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("getMarshaler"); } return null; } public Object getSBBResourceAdaptorInterface(String arg0) { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("getSBBResourceAdaptorInterface"); } return this.sbbInterface; } public void queryLiveness(javax.slee.resource.ActivityHandle ah) { Logger logger = getLogger(); if (logger.isDebugEnabled()) { logger.debug("queryLiveness"); } // ignore, datasource activities can live for long } public void serviceActivated(String arg0) { // DO NOTHING } public void serviceDeactivated(String arg0) { // DO NOTHING } public void serviceInstalled(String arg0, int[] arg1, String[] arg2) { // DO NOTHING } public void serviceUninstalled(String arg0) { // DO NOTHING } // ABSTRACT METHODS public abstract DataSource getDataSource(); public abstract Logger getLogger(); // THIS RA LOGIC public void postDocumentUpdatedEvent(DocumentUpdatedEvent event) { postEvent(event, documentUpdatedEventId,event.getDocumentSelector()); } public void postElementUpdatedEvent(ElementUpdatedEvent event) { postEvent(event, elementUpdatedEventId,event.getDocumentSelector()); } public void postAttributeUpdatedEvent(AttributeUpdatedEvent event) { postEvent(event, attributeUpdatedEventId,event.getDocumentSelector()); } private void postEvent(Object event, int eventId, DocumentSelector documentSelector) { if (getLogger().isDebugEnabled()) { getLogger().debug("postEvent(documentSelector="+documentSelector.toString()+")"); } // try to fire event on document selector and auid activities fireEvent(event, eventId, new ActivityHandle(documentSelector.toString())); fireEvent(event, eventId, new ActivityHandle(documentSelector.getAUID())); } private void fireEvent(Object event, int eventId, ActivityHandle handle) { if (getActivity(handle) != null) { // fire event try { this.sleeEndpoint.fireEvent(handle, event, eventId, null); } catch (Exception e) { getLogger().error("failed to post event for "+handle.toString(), e); } } } public void endActivity(ActivityHandle handle) { // check it has activity if(activities.containsKey(handle)) { // tell slee to end the activity context try { this.sleeEndpoint.activityEnding(handle); } catch (Exception e) { getLogger().error("unable to end activity: ",e); } } } /** * creates a new activity, if does not exists, otherwise signal another "virtual" creation was done */ public AppUsageActivity createAppUsageActivity(String auid) { ActivityHandle activityHandle = new ActivityHandle(auid); AppUsageActivity activity = (AppUsageActivity) activities.get(activityHandle); if (activity == null) { activity = new AppUsageActivity(auid,this); AppUsageActivity anotherActivity = (AppUsageActivity) activities.putIfAbsent(activityHandle, activity); if (anotherActivity != null) { activity = anotherActivity; activity.created(); } } else { activity.created(); } return activity; } /** * creates a new activity, if does not exists, otherwise signal another "virtual" creation was done */ public DocumentActivity createDocumentActivity( DocumentSelector documentSelector) { ActivityHandle activityHandle = new ActivityHandle(documentSelector.toString()); DocumentActivity activity = (DocumentActivity) activities.get(activityHandle); if (activity == null) { activity = new DocumentActivity(documentSelector,this); DocumentActivity anotherActivity = (DocumentActivity) activities.putIfAbsent(activityHandle, activity); if (anotherActivity != null) { activity = anotherActivity; activity.created(); } } else { activity.created(); } return activity; } }