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; } }