package org.mobicents.slee.runtime.activity; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import javax.slee.SLEEException; import javax.slee.ServiceID; import javax.slee.resource.ActivityHandle; import javax.slee.resource.Marshaler; import org.mobicents.slee.container.SleeContainer; import org.mobicents.slee.container.management.ResourceManagement; import org.mobicents.slee.container.service.ServiceActivityHandle; import org.mobicents.slee.resource.ResourceAdaptorEntity; import org.mobicents.slee.runtime.facilities.nullactivity.NullActivityHandle; import org.mobicents.slee.runtime.facilities.nullactivity.NullActivityImpl; import org.mobicents.slee.runtime.facilities.profile.ProfileTableActivityHandle; import org.mobicents.slee.runtime.facilities.profile.ProfileTableActivityImpl; /** * The handle for an {@link ActivityContext}. Useful to understand what is the * source or the type of the related activity, or even get that activity object. * * @author martins * */ public class ActivityContextHandle implements Serializable { /** * */ private static final long serialVersionUID = 1L; private static transient ResourceManagement _resourceManagement; private static ResourceManagement getResourceManagement() { if (_resourceManagement == null) { _resourceManagement = SleeContainer.lookupFromJndi().getResourceManagement(); } return _resourceManagement; } //in case of RA, this wont be serializable, and even if it is, we must use RA.Marshaler ? private transient ActivityHandle activityHandle; private String activitySource; private ActivityType activityType; private transient int hashcode = 0; private transient String toString = null; protected ActivityContextHandle(ActivityType activityType, String activitySource, ActivityHandle activityHandle) { this.activityHandle = activityHandle; this.activitySource = activitySource; this.activityType = activityType; } public ActivityHandle getActivityHandle() { return activityHandle; } public String getActivitySource() { return activitySource; } public ActivityType getActivityType() { return activityType; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (obj.getClass() == this.getClass()) { final ActivityContextHandle other = (ActivityContextHandle) obj; if (other.activityHandle.equals(this.activityHandle) && other.activityType == this.activityType) { // only compare the source if the activity type is external if (this.activityType == ActivityType.RA) { return other.activitySource.equals(this.activitySource); } else { return true; } } else { return false; } } else { return false; } } @Override public int hashCode() { if (hashcode == 0) { final int prime = 31; int result = activityHandle.hashCode(); result = prime * result + activitySource.hashCode(); result = prime * result + activityType.hashCode(); hashcode = result; } return hashcode; } public Object getActivity() { Object activity = null; switch (activityType) { case RA: try { activity = getResourceManagement().getResourceAdaptorEntity( activitySource).getResourceAdaptorObject().getActivity( getActivityHandle()); } catch (Exception e) { throw new SLEEException(e.getMessage(), e); } break; case NULL: activity = new NullActivityImpl((NullActivityHandle) activityHandle); break; case PTABLE: activity = new ProfileTableActivityImpl( (ProfileTableActivityHandle) getActivityHandle()); break; case SERVICE: final ServiceID serviceID = ((ServiceActivityHandle)activityHandle).getServiceID(); activity = SleeContainer.lookupFromJndi().getServiceActivityFactory().getActivity(serviceID); break; default: throw new SLEEException("Unknown activity type " + activityType); } return activity; } @Override public String toString() { if (toString == null) { toString = "ACH=" + activityType + ">"+ activitySource + ">" + activityHandle; } return toString; } private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); if(activityType == ActivityType.RA) { ResourceAdaptorEntity entity = getResourceManagement().getResourceAdaptorEntity(activitySource); if(entity == null || entity.getMarshaler() == null) { throw new IOException("Either Entity for source: "+this.activitySource+" does not exist or entity does not provide marshaler!"); } Marshaler marshaler = entity.getMarshaler(); //FIXME: Here we possibly should use some optimized buffers, but for now its enough. DataOutputStream dos = new DataOutputStream(stream); marshaler.marshalHandle(this.activityHandle, dos); }else { stream.writeObject(this.activityHandle); } } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); if(activityType == ActivityType.RA) { ResourceAdaptorEntity entity = getResourceManagement().getResourceAdaptorEntity(activitySource); if(entity == null || entity.getMarshaler() == null) { throw new IOException("Either Entity for source: "+this.activitySource+" does nto exist or entity does not provide marshaler!"); } Marshaler marshaler = entity.getMarshaler(); DataInputStream dis = new DataInputStream(stream); this.activityHandle=marshaler.unmarshalHandle(dis); }else { this.activityHandle=(ActivityHandle) stream.readObject(); } } }