001: package demo.notification.office;
002:
003: /**
004: *
005: */
006:
007: import org.omg.CosNotification.*;
008: import org.omg.CosNotifyComm.*;
009: import org.omg.CosNotifyChannelAdmin.*;
010:
011: import org.omg.CosNaming.*;
012: import org.omg.CosNaming.NamingContextPackage.*;
013: import org.omg.CORBA.Any;
014: import org.omg.CORBA.ORB;
015: import org.omg.PortableServer.*;
016:
017: import java.util.Hashtable;
018: import demo.notification.office.PrinterPackage.*;
019:
020: class PrinterImpl extends PrinterPOA implements
021: StructuredPushSupplierOperations {
022: private EventChannel channel;
023: private SupplierAdmin supplierAdmin;
024: private StructuredProxyPushConsumer pushConsumer;
025: private ORB orb;
026: private POA poa;
027:
028: private Hashtable queue;
029: private int jobId;
030: private int printIdx;
031: private int eventId;
032: private boolean offline;
033: private boolean disconnected;
034: private PrintThread printThread;
035:
036: static class JobInfo {
037: public int jobId;
038: public String userId;
039: public String text;
040:
041: public JobInfo(int jobId, String userId, String text) {
042: this .jobId = jobId;
043: this .userId = userId;
044: this .text = text;
045: }
046: }
047:
048: public int getEventId() {
049: return eventId++;
050: }
051:
052: /** Inner class PrintThread ( member class)
053: simulates the actual "printing" in a separate thread
054: */
055:
056: class PrintThread extends Thread {
057: public PrintThread() {
058: start();
059: }
060:
061: /**
062: * convenience method that does the synchronization
063: */
064:
065: public synchronized void tell() {
066: super .notify();
067: }
068:
069: public void run() {
070: while (true) {
071: // wait until there are jobs waiting
072: while (printIdx >= jobId || offline) {
073: try {
074: synchronized (this ) {
075: this .wait();
076: }
077: } catch (InterruptedException ie) {
078: }
079: }
080:
081: // "print"
082: JobInfo job = (JobInfo) queue.remove(new Integer(
083: printIdx));
084: if (job != null && generateEvents()) {
085: System.out.println("--Printing Job # " + job.jobId
086: + " --\n" + job.text + "\n--END JOB---");
087: // create a structured event
088: StructuredEvent printedEvent = new StructuredEvent();
089:
090: // set the event type and name
091: EventType type = new EventType("Office", "Printed");
092: FixedEventHeader fixed = new FixedEventHeader(type,
093: "" + getEventId());
094:
095: // complete header date
096: Property variable[] = new Property[0];
097:
098: printedEvent.header = new EventHeader(fixed,
099: variable);
100:
101: // set filterable event body data
102: printedEvent.filterable_data = new Property[3];
103:
104: Any jobAny = orb.create_any();
105: jobAny.insert_long(job.jobId);
106: printedEvent.filterable_data[0] = new Property(
107: "job_id", jobAny);
108:
109: Any userAny = orb.create_any();
110: userAny.insert_string(job.userId);
111: printedEvent.filterable_data[1] = new Property(
112: "user_id", userAny);
113:
114: Any urgentAny = orb.create_any();
115: urgentAny.insert_boolean(false);
116: printedEvent.filterable_data[2] = new Property(
117: "urgent", urgentAny);
118:
119: // no further even data
120: printedEvent.remainder_of_body = orb.create_any();
121:
122: try {
123: boolean exist = false;
124: try {
125: exist = !pushConsumer._non_existent();
126: } catch (org.omg.CORBA.SystemException e) {
127: // exist remains false
128: }
129:
130: if (exist)
131: pushConsumer
132: .push_structured_event(printedEvent);
133: else
134: System.err.println("Object " + pushConsumer
135: + " not existent");
136: } catch (org.omg.CosEventComm.Disconnected d) {
137: // ignore
138: }
139: }
140: // update internal printing position
141: printIdx++;
142: try {
143: Thread.sleep(5000);
144: } catch (Exception e) {
145: // ignore
146: }
147: }
148: }
149: }
150:
151: public PrinterImpl(EventChannel e, ORB orb, POA poa) {
152: // set the ORb and event channel
153: this .orb = orb;
154: this .poa = poa;
155: channel = e;
156: }
157:
158: public void connect() {
159: StructuredPushSupplierPOATie this Tie = new StructuredPushSupplierPOATie(
160: this );
161:
162: // get admin interface and proxy consumer
163: supplierAdmin = channel.default_supplier_admin();
164:
165: ClientType ctype = ClientType.STRUCTURED_EVENT;
166: org.omg.CORBA.IntHolder proxyIdHolder = new org.omg.CORBA.IntHolder();
167:
168: try {
169: pushConsumer = StructuredProxyPushConsumerHelper
170: .narrow(supplierAdmin
171: .obtain_notification_push_consumer(ctype,
172: proxyIdHolder));
173: } catch (AdminLimitExceeded ex) {
174: System.err
175: .println("Could not get consumer proxy, maximum number of proxies exceeded!");
176: System.exit(1);
177: }
178:
179: // connect the push supplier
180: try {
181: pushConsumer
182: .connect_structured_push_supplier(StructuredPushSupplierHelper
183: .narrow(poa.servant_to_reference(this Tie)));
184: } catch (Exception e) {
185: e.printStackTrace();
186: }
187: // initialize "queue" and start printer thread
188: queue = new Hashtable();
189: printThread = new PrintThread();
190: }
191:
192: /**
193: * Enter a job in the printer queue
194: */
195:
196: public synchronized int print(String text, String uid)
197: throws OffLine {
198: if (offline)
199: throw new OffLine();
200:
201: queue.put(new Integer(jobId), new JobInfo(jobId, uid, text));
202: printThread.tell();
203: return jobId++;
204: }
205:
206: /**
207: * Remove a job in the printer queue
208: */
209:
210: public void cancel(int id, String uid) throws UnknownJobID,
211: AlreadyPrinted {
212:
213: if (id > jobId || id < 0)
214: throw new UnknownJobID();
215:
216: if (id < printIdx)
217: throw new AlreadyPrinted();
218:
219: JobInfo job = (JobInfo) queue.get(new Integer(id));
220: if (job != null) {
221: if (!job.userId.equals(uid))
222: throw new org.omg.CORBA.NO_PERMISSION();
223:
224: queue.remove(new Integer(id));
225:
226: System.out.println("--CANCELLED JOB #" + id + "--");
227:
228: if (generateEvents()) {
229: // create a structured event
230: StructuredEvent cancelEvent = new StructuredEvent();
231:
232: // set the event type and name
233: EventType type = new EventType("Office", "Canceled");
234: FixedEventHeader fixed = new FixedEventHeader(type, ""
235: + getEventId());
236:
237: // complete header date
238: Property variable[] = new Property[0];
239: cancelEvent.header = new EventHeader(fixed, variable);
240:
241: // set filterable event body data
242: cancelEvent.filterable_data = new Property[3];
243:
244: Any jobAny = orb.create_any();
245: jobAny.insert_long(job.jobId);
246: cancelEvent.filterable_data[0] = new Property(
247: "job_id ", jobAny);
248:
249: Any userAny = orb.create_any();
250: userAny.insert_string(job.userId);
251: cancelEvent.filterable_data[1] = new Property(
252: "user_id ", userAny);
253:
254: Any urgentAny = orb.create_any();
255: urgentAny.insert_boolean(true);
256: cancelEvent.filterable_data[2] = new Property("urgent",
257: urgentAny);
258:
259: cancelEvent.remainder_of_body = orb.create_any();
260:
261: try {
262: pushConsumer.push_structured_event(cancelEvent);
263: } catch (org.omg.CosEventComm.Disconnected d) {
264: // ignore
265: }
266: }
267: }
268: }
269:
270: /**
271: * Sets the printer online/offline
272: */
273:
274: public void setOffLine(boolean flag) {
275: offline = flag;
276: if (!offline)
277: printThread.tell();
278:
279: if (generateEvents()) {
280: // create a structured event
281: StructuredEvent lineEvent = new StructuredEvent();
282:
283: String typeSuffix = (offline ? "offline" : "online");
284:
285: // set the event type and name
286: EventType type = new EventType("Office", "Printer"
287: + typeSuffix);
288: FixedEventHeader fixed = new FixedEventHeader(type, ""
289: + getEventId());
290:
291: // complete header date
292: // Any priorityAny = orb.create_any();
293: // priorityAny.insert_short( (short)4 );
294:
295: Property variable[] = new Property[0];
296: lineEvent.header = new EventHeader(fixed, variable);
297:
298: // set filterable event body data
299: lineEvent.filterable_data = new Property[1];
300:
301: Any urgentAny = orb.create_any();
302: urgentAny.insert_boolean(false);
303: lineEvent.filterable_data[0] = new Property("urgent",
304: urgentAny);
305:
306: lineEvent.remainder_of_body = orb.create_any();
307: try {
308: pushConsumer.push_structured_event(lineEvent);
309: } catch (org.omg.CosEventComm.Disconnected d) {
310: // ignore
311: }
312: }
313: }
314:
315: boolean generateEvents() {
316: return !disconnected;
317: }
318:
319: /**
320: * Potentially release resources,
321: * from CosNotifyComm.NotifySubscribe
322: */
323:
324: public void disconnect_structured_push_supplier() {
325: disconnected = true;
326: System.out.println("Disconnected!");
327: }
328:
329: /**
330: * from CosNotifyComm.NotifySubscribe
331: */
332:
333: public void subscription_change(EventType added[],
334: EventType removed[]) {
335: // react somehow;
336: }
337:
338: }
|