package context.arch.subscriber;
import context.arch.storage.Attributes;
import context.arch.comm.DataObject;
import context.arch.comm.DataObjects;
import context.arch.discoverer.query.AbstractQueryItem;
/**
* This class implements a server or widget side subscriber object, encapsulating the information
* needed to talk to a widget's subscriber.
*
* @see context.arch.subscriber.Subscribers
* @see context.arch.subscriber.ClientSideSubscriber
*/
public class Subscriber extends AbstractSubscriber {
public static final String GENERAL_TYPE = "widgetSubscriber";
/**
* These fields are specific to Susbcriber (conditions for the callback
* and attributes
*/
private AbstractQueryItem<?,?> condition;
private Attributes attributes;
/**
* Basic constructor that creates a subscriber object.
*
* @param id ID of the component
* @param hostname Name of the subscriber's host computer
* @param port Port number to send information to
* @param callback Callback the subscriber will implement
* @param tag Widget callback the subscriber is subscribing to
* @param condition A query that conditions the type of widget data returned
* @param attributes Attributes to return to subscriber
*/
public Subscriber(String subBaseObjectId, String subHostname,int subPort,String subCallback,
AbstractQueryItem<?,?> condition ,Attributes attributes) {
super(Subscriber.GENERAL_TYPE);
// setSubscriptionId(subBaseObjectId); // wrong --Brian
setBaseObjectId(subBaseObjectId);
setSubscriberHostname(subHostname);
setSubscriberPort(subPort);
setSubscriptionCallback(subCallback);
this.condition = condition;
this.attributes = attributes;
resetErrors();
}
/**
* Basic constructor that creates a subscriber object.
*
* @param id ID of the subscriber
* @param hostname Name of the subscriber's host computer
* @param port Port number to send information to
* @param callback Callback the subscriber will implement
* @param tag Widget callback the subscriber is subscribing to
* @param condition A query that conditions the type of widget data returned
* @param attributes Attributes to return to subscriber
*/
public Subscriber(String subBaseObjectId, String subHostname,String subPort,String subCallback,
AbstractQueryItem<?,?> condition, Attributes attributes) {
this(subBaseObjectId, subHostname,new Integer(subPort).intValue(),subCallback,condition,attributes);
}
/**
* Basic constructor that creates a subscriber object from a DataObject.
* The DataObject must contain a <SUBSCRIBER> tag
*
* @param data DataObject containing the subscriber info
*/
public Subscriber(DataObject data) {
super(data);
DataObject sub = data.getDataObject(SUBSCRIBER);
DataObject aqi = sub.getDataObject(AbstractQueryItem.ABSTRACT_QUERY_ITEM);
if (aqi != null) {
condition = AbstractQueryItem.fromDataObject((DataObject)aqi.getChildren().firstElement());
}
attributes = Attributes.fromDataObject(sub);
}
/**
* This method converts the subscriber info to a DataObject
*
* @return Subscriber object converted to a <SUBSCRIBER> DataObject
*/
public DataObject toDataObject() {
DataObjects v = (super.toDataObject()).getChildren();
if (condition != null) {
DataObjects c = new DataObjects();
c.add(condition.toDataObject());
v.addElement(new DataObject(AbstractQueryItem.ABSTRACT_QUERY_ITEM, c));
}
v.addElement(attributes.toDataObject());
return new DataObject(SUBSCRIBER, v);
}
/**
* Sets the subscription conditions, under which the subscriber will be notified
*
* @param conditions Subscription conditions used for notification
*/
public void setCondition(AbstractQueryItem<?,?> condition) {
this.condition = condition;
}
/**
* Returns the subscription conditions, under which the subscriber will be notified
*
* @return subscription conditions used for notification
*/
public AbstractQueryItem<?,?> getCondition() {
return condition;
}
/**
* Sets the attributes to return to the subscriber
*
* @param attributes Attributes to return to the subscriber
*/
public void setAttributes(Attributes attributes) {
this.attributes = attributes;
}
/**
* Returns the subscription attributes to be returned
*
* @return subscription attributes to return to subscriber
*/
public Attributes getAttributes() {
return attributes;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Subscriber)) { return false; }
Subscriber other = (Subscriber) o;
// if (this.subscriptionUniqueId == null) {
// System.out.println("subscriptionUniqueId == null & this.class = " + this.getClass());
// }
// subscriptionUniqueId may be null if never added to a collection of Subscribers
if (this.subscriptionUniqueId == null && other.subscriptionUniqueId != null) {
return false;
}
return this.subscriptionUniqueId.equals(other.subscriptionUniqueId) &&
this.subscriberHostname.equals(other.subscriberHostname) &&
this.subscriberPort == other.subscriberPort &&
this.subscriptionCallback.equals(other.subscriptionCallback) && //TODO: repair this, not sure if QueryItems can be so easily compared --alann
this.attributes.equals(other.attributes);
}
@Override
public int hashCode() {
return super.hashCode();
// TODO: could be made more efficient if this object is used as an index in a HashMap, but at the moment, there are no plans for such usage --Brian
}
}