1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58:
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77:
78:
84: public class DocPrintJobImpl implements CancelablePrintJob
85: {
86:
87: private IppPrintService service;
88:
89:
90: private HashSet printJobListener = new HashSet();
91:
92:
93: private ArrayList attributesListener = new ArrayList();
94:
95: private ArrayList attributesListenerAttributes = new ArrayList();
96:
97:
98: private String username;
99:
100: private String password;
101:
102:
103: private JobUri jobUri = null;
104:
105: private JobId jobId = null;
106:
107:
108: private RequestingUserName requestingUser;
109:
110:
111: private PrintJobAttributeSet oldSet = new HashPrintJobAttributeSet();
112: private PrintJobAttributeSet currentSet = new HashPrintJobAttributeSet();
113:
114:
117: private boolean printing = false;
118:
119:
120:
121:
122:
129: public DocPrintJobImpl(IppPrintService service, String user, String passwd)
130: {
131: this.service = service;
132: username = user;
133: password = passwd;
134: }
135:
136:
139: public void addPrintJobAttributeListener(PrintJobAttributeListener listener,
140: PrintJobAttributeSet attributes)
141: {
142: if (listener == null)
143: return;
144:
145: attributesListener.add(listener);
146: attributesListenerAttributes.add(attributes);
147: }
148:
149:
152: public void addPrintJobListener(PrintJobListener listener)
153: {
154: if (listener == null)
155: return;
156:
157: printJobListener.add(listener);
158: }
159:
160:
163: public PrintJobAttributeSet getAttributes()
164: {
165: return AttributeSetUtilities.unmodifiableView(currentSet);
166: }
167:
168:
171: public PrintService getPrintService()
172: {
173: return service;
174: }
175:
176:
179: public void print(Doc doc, PrintRequestAttributeSet attributes)
180: throws PrintException
181: {
182: if (printing)
183: throw new PrintException("already printing");
184:
185: printing = true;
186:
187: DocAttributeSet docAtts = doc.getAttributes();
188: DocFlavor flavor = doc.getDocFlavor();
189:
190: if (flavor == null || (!service.isDocFlavorSupported(flavor)))
191: {
192: notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED));
193: throw new PrintFlavorException("Invalid flavor", new DocFlavor[] {flavor});
194: }
195:
196:
197:
198: HashAttributeSet mergedAtts = new HashAttributeSet();
199:
200: if (attributes != null)
201: mergedAtts.addAll(attributes);
202: if (docAtts != null)
203: mergedAtts.addAll(docAtts);
204:
205:
206:
207:
208: if (! mergedAtts.containsKey(RequestingUserName.class))
209: {
210: mergedAtts.add(IppPrintService.REQUESTING_USER_NAME);
211: requestingUser = IppPrintService.REQUESTING_USER_NAME;
212: }
213: else
214: {
215: requestingUser = (RequestingUserName)
216: mergedAtts.get(RequestingUserName.class);
217: }
218:
219:
220: if (! mergedAtts.containsKey(JobName.class))
221: mergedAtts.add(IppPrintService.JOB_NAME);
222:
223: IppResponse response = null;
224:
225: try
226: {
227: PrinterURI printerUri = service.getPrinterURI();
228: String printerUriStr = "http" + printerUri.toString().substring(3);
229:
230: URI uri = null;
231: try
232: {
233: uri = new URI(printerUriStr);
234: }
235: catch (URISyntaxException e)
236: {
237:
238: }
239:
240: IppRequest request =
241: new IppRequest(uri, username, password);
242:
243: request.setOperationID( (short) OperationsSupported.PRINT_JOB.getValue());
244: request.setOperationAttributeDefaults();
245: request.addOperationAttribute(printerUri);
246:
247: if (mergedAtts != null)
248: {
249: request.addAndFilterJobOperationAttributes(mergedAtts);
250: request.addAndFilterJobTemplateAttributes(mergedAtts);
251: }
252:
253:
254: DocumentFormat format = DocumentFormat.createDocumentFormat(flavor);
255: request.addOperationAttribute(format);
256:
257:
258:
259: String className = flavor.getRepresentationClassName();
260:
261: if (className.equals("[B"))
262: {
263: request.setData((byte[]) doc.getPrintData());
264: response = request.send();
265: }
266: else if (className.equals("java.io.InputStream"))
267: {
268: InputStream stream = (InputStream) doc.getPrintData();
269: request.setData(stream);
270: response = request.send();
271: stream.close();
272: }
273: else if (className.equals("[C"))
274: {
275: try
276: {
277:
278:
279: String str = new String((char[]) doc.getPrintData());
280: request.setData(str.getBytes("utf-16"));
281: response = request.send();
282: }
283: catch (UnsupportedEncodingException e)
284: {
285: notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED));
286: throw new PrintFlavorException("Invalid charset of flavor", e, new DocFlavor[] {flavor});
287: }
288: }
289: else if (className.equals("java.io.Reader"))
290: {
291: try
292: {
293:
294:
295: response = request.send();
296: throw new UnsupportedEncodingException("not supported yet");
297: }
298: catch (UnsupportedEncodingException e)
299: {
300: notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED));
301: throw new PrintFlavorException("Invalid charset of flavor", e, new DocFlavor[] {flavor});
302: }
303: }
304: else if (className.equals("java.lang.String"))
305: {
306: try
307: {
308:
309:
310: String str = (String) doc.getPrintData();
311: request.setData(str.getBytes("utf-16"));
312: response = request.send();
313: }
314: catch (UnsupportedEncodingException e)
315: {
316: notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED));
317: throw new PrintFlavorException("Invalid charset of flavor", e, new DocFlavor[] {flavor});
318: }
319: }
320: else if (className.equals("java.net.URL"))
321: {
322: URL url = (URL) doc.getPrintData();
323: InputStream stream = url.openStream();
324: request.setData(stream);
325: response = request.send();
326: stream.close();
327: }
328: else if (className.equals("java.awt.image.renderable.RenderableImage")
329: || className.equals("java.awt.print.Printable")
330: || className.equals("java.awt.print.Pageable"))
331: {
332:
333: throw new PrintException("Not yet supported.");
334: }
335: else
336: {
337:
338: notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED));
339: throw new PrintFlavorException("Invalid flavor", new DocFlavor[] {flavor});
340: }
341:
342:
343: notifyPrintJobListeners(new PrintJobEvent(
344: this, PrintJobEvent.DATA_TRANSFER_COMPLETE));
345: }
346: catch (IOException e)
347: {
348: throw new PrintException("IOException occured.", e);
349: }
350:
351: int status = response.getStatusCode();
352: if (! (status == IppStatusCode.SUCCESSFUL_OK
353: || status == IppStatusCode.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUED_ATTRIBUTES
354: || status == IppStatusCode.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) )
355: {
356: notifyPrintJobListeners(new PrintJobEvent(
357: this, PrintJobEvent.JOB_FAILED));
358: throw new PrintException("Printing failed - received statuscode " + Integer.toHexString(status));
359:
360:
361:
362: }
363: else
364: {
365:
366:
367:
368:
369: notifyPrintJobListeners(
370: new PrintJobEvent(this, PrintJobEvent.JOB_COMPLETE));
371: }
372:
373: List jobAtts = response.getJobAttributes();
374:
375:
376: Map jobAttributes = (Map) jobAtts.get(0);
377: jobUri = (JobUri) ((HashSet)jobAttributes.get(JobUri.class)).toArray()[0];
378: jobId = (JobId) ((HashSet)jobAttributes.get(JobId.class)).toArray()[0];
379: }
380:
381:
384: public void removePrintJobAttributeListener(PrintJobAttributeListener listener)
385: {
386: if (listener == null)
387: return;
388:
389: int index = attributesListener.indexOf(listener);
390: if (index != -1)
391: {
392: attributesListener.remove(index);
393: attributesListenerAttributes.remove(index);
394: }
395: }
396:
397:
400: public void removePrintJobListener(PrintJobListener listener)
401: {
402: if (listener == null)
403: return;
404:
405: printJobListener.remove(listener);
406: }
407:
408:
411: public void cancel() throws PrintException
412: {
413: if (jobUri == null)
414: {
415: throw new PrintException("print job is not yet send");
416: }
417:
418: IppResponse response = null;
419:
420: try
421: {
422: IppRequest request = new IppRequest(jobUri.getURI(), username, password);
423: request.setOperationID( (short) OperationsSupported.CANCEL_JOB.getValue());
424: request.setOperationAttributeDefaults();
425: request.addOperationAttribute(jobUri);
426: request.addOperationAttribute(requestingUser);
427: response = request.send();
428: }
429: catch (IOException e)
430: {
431: throw new IppException("IOException occured during cancel request.", e);
432: }
433:
434: int status = response.getStatusCode();
435: if (! (status == IppStatusCode.SUCCESSFUL_OK
436: || status == IppStatusCode.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUED_ATTRIBUTES
437: || status == IppStatusCode.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) )
438: {
439: notifyPrintJobListeners(new PrintJobEvent(
440: this, PrintJobEvent.JOB_FAILED));
441: throw new PrintException("Canceling failed - received statuscode " + Integer.toHexString(status));
442: }
443: else
444: {
445: notifyPrintJobListeners(new PrintJobEvent(
446: this, PrintJobEvent.JOB_CANCELED));
447: }
448: }
449:
450: private void notifyPrintJobListeners(PrintJobEvent e)
451: {
452: Iterator it = printJobListener.iterator();
453: while (it.hasNext())
454: {
455: PrintJobListener l = (PrintJobListener) it.next();
456: if (e.getPrintEventType() == PrintJobEvent.DATA_TRANSFER_COMPLETE)
457: l.printDataTransferCompleted(e);
458: else if (e.getPrintEventType() == PrintJobEvent.JOB_CANCELED)
459: l.printJobCanceled(e);
460: else if (e.getPrintEventType() == PrintJobEvent.JOB_COMPLETE)
461: l.printJobCompleted(e);
462: else if (e.getPrintEventType() == PrintJobEvent.JOB_FAILED)
463: l.printJobFailed(e);
464: else if (e.getPrintEventType() == PrintJobEvent.NO_MORE_EVENTS)
465: l.printJobNoMoreEvents(e);
466: else
467: l.printJobRequiresAttention(e);
468: }
469: }
470:
471: }