package org.jacorb.demo.notification.office;
/**
*
*/
import org.omg.CosNotification.*;
import org.omg.CosNotifyComm.*;
import org.omg.CosNotifyChannelAdmin.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.Any;
import org.omg.CORBA.ORB;
import org.omg.PortableServer.*;
import java.util.Hashtable;
import org.jacorb.demo.notification.office.PrinterPackage.*;
class PrinterImpl
extends PrinterPOA
implements StructuredPushSupplierOperations
{
private EventChannel channel;
private SupplierAdmin supplierAdmin ;
private StructuredProxyPushConsumer pushConsumer;
private ORB orb;
private POA poa;
private Hashtable queue;
private int jobId;
private int printIdx;
private int eventId;
private boolean offline;
private boolean disconnected;
private PrintThread printThread;
static class JobInfo
{
public int jobId;
public String userId;
public String text;
public JobInfo(int jobId, String userId, String text)
{
this.jobId = jobId;
this.userId = userId;
this.text = text;
}
}
public int getEventId()
{
return eventId++;
}
/** Inner class PrintThread ( member class)
simulates the actual "printing" in a separate thread
*/
class PrintThread extends Thread
{
public PrintThread()
{
start();
}
/**
* convenience method that does the synchronization
*/
public synchronized void tell()
{
super.notify();
}
public void run()
{
while( true )
{
// wait until there are jobs waiting
while( printIdx >= jobId || offline )
{
try
{
synchronized( this )
{
this.wait();
}
}
catch( InterruptedException ie )
{}
}
// "print"
JobInfo job = (JobInfo)queue.remove( new Integer( printIdx ));
if( job != null && generateEvents() )
{
System.out.println("--Printing Job # " + job.jobId + " --\n" + job.text + "\n--END JOB---");
// create a structured event
StructuredEvent printedEvent = new StructuredEvent();
// set the event type and name
EventType type = new EventType("Office", "Printed");
FixedEventHeader fixed = new FixedEventHeader(type, "" + getEventId() );
// complete header date
Property variable[] = new Property[0];
printedEvent.header = new EventHeader(fixed, variable);
// set filterable event body data
printedEvent.filterable_data = new Property[3];
Any jobAny = orb.create_any();
jobAny.insert_long( job.jobId );
printedEvent.filterable_data[0] = new Property("job_id", jobAny );
Any userAny = orb.create_any();
userAny.insert_string( job.userId );
printedEvent.filterable_data[1] = new Property("user_id", userAny );
Any urgentAny = orb.create_any();
urgentAny.insert_boolean( false );
printedEvent.filterable_data[2] = new Property( "urgent", urgentAny );
// no further even data
printedEvent.remainder_of_body = orb.create_any();
try
{
boolean exist = false;
try
{
exist = ! pushConsumer._non_existent();
}
catch( org.omg.CORBA.SystemException e )
{
// exist remains false
}
if( exist )
pushConsumer.push_structured_event(printedEvent);
else
System.err.println("Object " + pushConsumer + " not existent");
}
catch( org.omg.CosEventComm.Disconnected d )
{
// ignore
}
}
// update internal printing position
printIdx++;
try
{
Thread.sleep(5000);
}
catch( Exception e )
{
// ignore
}
}
}
}
public PrinterImpl(EventChannel e, ORB orb, POA poa)
{
// set the ORb and event channel
this.orb = orb;
this.poa = poa;
channel = e;
}
public void connect()
{
StructuredPushSupplierPOATie thisTie = new StructuredPushSupplierPOATie( this );
// get admin interface and proxy consumer
supplierAdmin = channel.default_supplier_admin();
ClientType ctype = ClientType.STRUCTURED_EVENT;
org.omg.CORBA.IntHolder proxyIdHolder = new org.omg.CORBA.IntHolder();
try
{
pushConsumer =
StructuredProxyPushConsumerHelper.narrow(
supplierAdmin.obtain_notification_push_consumer(ctype, proxyIdHolder));
}
catch (AdminLimitExceeded ex)
{
System.err.println("Could not get consumer proxy, maximum number of proxies exceeded!");
System.exit(1);
}
// connect the push supplier
try
{
pushConsumer.connect_structured_push_supplier( StructuredPushSupplierHelper.narrow( poa.servant_to_reference( thisTie )));
}
catch( Exception e )
{
e.printStackTrace();
}
// initialize "queue" and start printer thread
queue = new Hashtable();
printThread = new PrintThread();
}
/**
* Enter a job in the printer queue
*/
public synchronized int print( String text, String uid)
throws OffLine
{
if( offline )
throw new OffLine();
queue.put( new Integer(jobId), new JobInfo( jobId, uid, text ));
printThread.tell();
return jobId++;
}
/**
* Remove a job in the printer queue
*/
public void cancel(int id, String uid )
throws UnknownJobID, AlreadyPrinted
{
if( id > jobId || id < 0)
throw new UnknownJobID();
if( id < printIdx )
throw new AlreadyPrinted();
JobInfo job = (JobInfo)queue.get( new Integer( id ));
if( job != null )
{
if( !job.userId.equals( uid ))
throw new org.omg.CORBA.NO_PERMISSION();
queue.remove( new Integer( id ));
System.out.println("--CANCELLED JOB #" + id + "--");
if( generateEvents() )
{
// create a structured event
StructuredEvent cancelEvent = new StructuredEvent();
// set the event type and name
EventType type = new EventType("Office", "Canceled");
FixedEventHeader fixed = new FixedEventHeader(type, "" + getEventId() );
// complete header date
Property variable[] = new Property[0];
cancelEvent.header = new EventHeader(fixed, variable);
// set filterable event body data
cancelEvent.filterable_data = new Property[3];
Any jobAny = orb.create_any();
jobAny.insert_long( job.jobId );
cancelEvent.filterable_data[0] = new Property("job_id ", jobAny );
Any userAny = orb.create_any();
userAny.insert_string( job.userId );
cancelEvent.filterable_data[1] = new Property("user_id ", userAny );
Any urgentAny = orb.create_any();
urgentAny.insert_boolean( true );
cancelEvent.filterable_data[2] = new Property( "urgent", urgentAny );
cancelEvent.remainder_of_body = orb.create_any();
try
{
pushConsumer.push_structured_event( cancelEvent );
}
catch( org.omg.CosEventComm.Disconnected d )
{
// ignore
}
}
}
}
/**
* Sets the printer online/offline
*/
public void setOffLine(boolean flag)
{
offline = flag;
if( !offline )
printThread.tell();
if( generateEvents() )
{
// create a structured event
StructuredEvent lineEvent = new StructuredEvent();
String typeSuffix = ( offline ? "offline" : "online" );
// set the event type and name
EventType type = new EventType("Office", "Printer" + typeSuffix);
FixedEventHeader fixed = new FixedEventHeader(type, "" + getEventId() );
// complete header date
// Any priorityAny = orb.create_any();
// priorityAny.insert_short( (short)4 );
Property variable[] = new Property[0];
lineEvent.header = new EventHeader(fixed, variable);
// set filterable event body data
lineEvent.filterable_data = new Property[1];
Any urgentAny = orb.create_any();
urgentAny.insert_boolean( false );
lineEvent.filterable_data[0] = new Property( "urgent", urgentAny );
lineEvent.remainder_of_body = orb.create_any();
try
{
pushConsumer.push_structured_event( lineEvent );
}
catch( org.omg.CosEventComm.Disconnected d )
{
// ignore
}
}
}
boolean generateEvents()
{
return !disconnected;
}
/**
* Potentially release resources,
* from CosNotifyComm.NotifySubscribe
*/
public void disconnect_structured_push_supplier()
{
disconnected = true;
System.out.println("Disconnected!");
}
/**
* from CosNotifyComm.NotifySubscribe
*/
public void subscription_change(EventType added[], EventType removed[])
{
// react somehow;
}
}