package org.jacorb.demo.notification.whiteboard;
import java.util.Hashtable;
import java.util.Map;
import org.omg.CORBA.IntHolder;
import org.omg.CORBA.ORB;
import org.omg.CosEventChannelAdmin.AlreadyConnected;
import org.omg.CosEventComm.Disconnected;
import org.omg.CosNotification.EventHeader;
import org.omg.CosNotification.EventType;
import org.omg.CosNotification.FixedEventHeader;
import org.omg.CosNotification.Property;
import org.omg.CosNotification.StructuredEvent;
import org.omg.CosNotifyChannelAdmin.AdminLimitExceeded;
import org.omg.CosNotifyChannelAdmin.AdminNotFound;
import org.omg.CosNotifyChannelAdmin.ClientType;
import org.omg.CosNotifyChannelAdmin.ConsumerAdmin;
import org.omg.CosNotifyChannelAdmin.EventChannel;
import org.omg.CosNotifyChannelAdmin.InterFilterGroupOperator;
import org.omg.CosNotifyChannelAdmin.StructuredProxyPushConsumer;
import org.omg.CosNotifyChannelAdmin.StructuredProxyPushConsumerHelper;
import org.omg.CosNotifyChannelAdmin.SupplierAdmin;
import org.omg.CosNotifyComm.InvalidEventType;
import org.omg.CosNotifyComm.StructuredPushSupplierOperations;
import org.omg.CosNotifyComm.StructuredPushSupplierPOATie;
import org.omg.CosNotifyFilter.ConstraintExp;
import org.omg.CosNotifyFilter.Filter;
import org.omg.CosNotifyFilter.FilterFactory;
import org.omg.CosNotifyFilter.InvalidConstraint;
import org.omg.CosNotifyFilter.InvalidGrammar;
/**
* @author Alphonse Bendt
*/
public class WhiteBoard
extends IWhiteBoardPOA
implements IWhiteBoardOperations, WhiteboardVars {
// zur Erzeugung einer eindeutigen Id
static int COUNT = 0;
EventChannel channel_;
FilterFactory filterFactory_;
// alle angemeldeten Workgroups
protected Map workgroups_;
Map registrationInfo_ = new Hashtable();
// bisher gesammelte Updates
// Queue updates_;
// Dispatcher Thread
Dispatcher disp;
// prima"rkopie
BrushSizePixelImage image;
public WhiteBoard(ORB orb, EventChannel channel) throws AdminLimitExceeded {
this(orb, channel, 400, 400);
}
public WhiteBoard(ORB orb,
EventChannel channel,
int xsize,
int ysize) throws AdminLimitExceeded {
System.out.println("WhiteBoard.init()");
_this(orb);
workgroups_ = new Hashtable();
clear();
image = new ExtendedPixelImage(xsize,ysize);
disp = new Dispatcher(orb, this, channel.default_supplier_admin());
// disp.start();
System.out.println("done");
filterFactory_ = channel.default_filter_factory();
channel_ = channel;
}
public int[] getCurrentImage() {
return image.getPixelBuffer();
}
// Workgroup an Whiteboard anmelden
// Id zur Kommunikation mit dem Whiteboard zuru"ck
public IRegistrationInfo join(IWorkgroup group) {
System.out.println("Workgroup joins the Whiteboard ");
Integer _id = new Integer(COUNT++);
System.out.println("workgroups: " + workgroups_ + ".put(" + _id + ", " + group);
workgroups_.put(_id, group);
IRegistrationInfo _registrationInfo = new IRegistrationInfo();
_registrationInfo.workgroup_identifier = _id.intValue();
IntHolder
_supplierAdminId = new IntHolder(),
_consumerAdminId = new IntHolder();
Filter _filter = null;
try {
_filter = filterFactory_.create_filter("EXTENDED_TCL");
ConstraintExp[] _constraints = new ConstraintExp[1];
_constraints[0] = new ConstraintExp();
_constraints[0].event_types = new EventType[] {new EventType(EVENT_DOMAIN, "*")};
_constraints[0].constraint_expr = "$.header.variable_header(" + WORKGROUP_ID + ") != " + _id.intValue();
_filter.add_constraints(_constraints);
SupplierAdmin _supplierAdmin =
channel_.new_for_suppliers(InterFilterGroupOperator.AND_OP, _supplierAdminId);
ConsumerAdmin _consumerAdmin =
channel_.new_for_consumers(InterFilterGroupOperator.AND_OP, _consumerAdminId);
_consumerAdmin.add_filter(_filter);
_registrationInfo.supplier_admin = _supplierAdmin;
_registrationInfo.consumer_admin = _consumerAdmin;
_registrationInfo.filter_factory = filterFactory_;
LocalRegistrationInfo _localInfo = new LocalRegistrationInfo();
_localInfo.consumerAdmin_ = _consumerAdminId.value;
_localInfo.supplierAdmin_ = _supplierAdminId.value;
registrationInfo_.put(_id, _localInfo);
return _registrationInfo;
} catch (InvalidGrammar ig) {
ig.printStackTrace();
} catch (InvalidConstraint ic) {
ic.printStackTrace();
}
throw new RuntimeException();
}
public boolean leave(int workgroup) {
System.out.println("Bye");
Integer _id = new Integer(workgroup);
LocalRegistrationInfo _info =
(LocalRegistrationInfo)registrationInfo_.get(_id);
try {
channel_.get_consumeradmin(_info.consumerAdmin_).destroy();
channel_.get_supplieradmin(_info.supplierAdmin_).destroy();
} catch (AdminNotFound anf) {
}
return (workgroups_.remove(_id) != null);
}
// Whiteboard lo"schen
public void clear() {
// updates_ = new Queue();
}
} // WhiteBoard
class Dispatcher
extends Thread
implements WhiteboardVars, StructuredPushSupplierOperations {
boolean connected_ = false;
boolean active_ = true;
WhiteBoard master_;
StructuredProxyPushConsumer myConsumer_;
ORB orb_;
IntHolder myConsumerId_ = new IntHolder();
static long SLEEP = 10000L;
public Dispatcher(ORB orb,
WhiteBoard master,
SupplierAdmin supplierAdmin) throws AdminLimitExceeded {
master_ = master;
orb_ = orb;
myConsumer_ =
StructuredProxyPushConsumerHelper.narrow(supplierAdmin.obtain_notification_push_consumer(ClientType.STRUCTURED_EVENT, myConsumerId_));
connected_ = tryConnect();
}
boolean tryConnect() {
long BACKOFF = 100L;
for (int x=0; x<3; ++x) {
try {
myConsumer_.connect_structured_push_supplier(new StructuredPushSupplierPOATie(this)._this(orb_));
connected_ = true;
return true;
} catch (AlreadyConnected ac) {
}
try {
Thread.sleep(BACKOFF^(x+1));
} catch (InterruptedException ie) {
}
}
return false;
}
public void shutdown() {
active_ = false;
interrupt();
}
public void run() {
StructuredEvent _event = new StructuredEvent();
_event.header = new EventHeader();
_event.header.fixed_header = new FixedEventHeader();
_event.header.fixed_header.event_type = new EventType();
_event.header.fixed_header.event_type.domain_name = EVENT_DOMAIN;
_event.header.fixed_header.event_type.type_name = "UPDATE";
_event.header.fixed_header.event_name = "";
_event.header.variable_header = new Property[0];
_event.filterable_data = new Property[0];
while (active_) {
try {
Thread.sleep(SLEEP);
} catch (InterruptedException ie) {
if (!active_) {
return;
}
}
if (!connected_) {
connected_ = tryConnect();
if (!connected_) {
System.out.println("Giving Up");
return;
}
}
try {
WhiteboardUpdate _update = new WhiteboardUpdate();
_update.image(master_.getCurrentImage());
_event.remainder_of_body = orb_.create_any();
WhiteboardUpdateHelper.insert(_event.remainder_of_body, _update);
myConsumer_.push_structured_event(_event);
} catch (Disconnected d) {
connected_ = false;
}
}
}
public void disconnect_structured_push_supplier() {
connected_ = false;
}
public void subscription_change(EventType[] t1, EventType[] t2) throws InvalidEventType {
}
}
class LocalRegistrationInfo {
int consumerAdmin_;
int supplierAdmin_;
}