diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/javax/print/ipp/DocPrintJobImpl.java | |
download | cbb-gcc-4.6.4-upstream.tar.bz2 cbb-gcc-4.6.4-upstream.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/javax/print/ipp/DocPrintJobImpl.java')
-rw-r--r-- | libjava/classpath/gnu/javax/print/ipp/DocPrintJobImpl.java | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/javax/print/ipp/DocPrintJobImpl.java b/libjava/classpath/gnu/javax/print/ipp/DocPrintJobImpl.java new file mode 100644 index 000000000..8cfd6880d --- /dev/null +++ b/libjava/classpath/gnu/javax/print/ipp/DocPrintJobImpl.java @@ -0,0 +1,471 @@ +/* DocPrintJobImpl.java -- Implementation of DocPrintJob. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.javax.print.ipp; + +import gnu.javax.print.PrintFlavorException; +import gnu.javax.print.ipp.attribute.job.JobId; +import gnu.javax.print.ipp.attribute.job.JobUri; +import gnu.javax.print.ipp.attribute.printer.DocumentFormat; +import gnu.javax.print.ipp.attribute.supported.OperationsSupported; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.print.CancelablePrintJob; +import javax.print.Doc; +import javax.print.DocFlavor; +import javax.print.DocPrintJob; +import javax.print.PrintException; +import javax.print.PrintService; +import javax.print.attribute.AttributeSetUtilities; +import javax.print.attribute.DocAttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.HashPrintJobAttributeSet; +import javax.print.attribute.PrintJobAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.JobName; +import javax.print.attribute.standard.PrinterURI; +import javax.print.attribute.standard.RequestingUserName; +import javax.print.event.PrintJobAttributeListener; +import javax.print.event.PrintJobEvent; +import javax.print.event.PrintJobListener; + +/** + * Implementation of the DocPrintJob interface. Implementation is + * specific to the <code>IppPrintService</code> implementation. + * + * @author Wolfgang Baer (WBaer@gmx.de) + */ +public class DocPrintJobImpl implements CancelablePrintJob +{ + /** The print service this job is bound to. */ + private IppPrintService service; + + /** The set of print job listeners. */ + private HashSet printJobListener = new HashSet(); + + /** The print job attributes listeners. */ + private ArrayList attributesListener = new ArrayList(); + /** The print job attributes listeners associated attribute set. */ + private ArrayList attributesListenerAttributes = new ArrayList(); + + /** The username. */ + private String username; + /** The password of the user. */ + private String password; + + /** Returned job uri. */ + private JobUri jobUri = null; + /** Returned job id. */ + private JobId jobId = null; + + /** The requesting-username for later canceling */ + private RequestingUserName requestingUser; + + /** The print job sets. */ + private PrintJobAttributeSet oldSet = new HashPrintJobAttributeSet(); + private PrintJobAttributeSet currentSet = new HashPrintJobAttributeSet(); + + /** + * State variable if we already started printing. + */ + private boolean printing = false; + + // TODO Implement complete PrintJobListener notification + // TODO Implement PrintJobAttributeListener notification + + /** + * Constructs a DocPrintJobImpl instance bound to the given print service. + * + * @param service the print service instance. + * @param user the user of this print service. + * @param passwd the password of the user. + */ + public DocPrintJobImpl(IppPrintService service, String user, String passwd) + { + this.service = service; + username = user; + password = passwd; + } + + /** + * @see DocPrintJob#addPrintJobAttributeListener(PrintJobAttributeListener, PrintJobAttributeSet) + */ + public void addPrintJobAttributeListener(PrintJobAttributeListener listener, + PrintJobAttributeSet attributes) + { + if (listener == null) + return; + + attributesListener.add(listener); + attributesListenerAttributes.add(attributes); + } + + /** + * @see DocPrintJob#addPrintJobListener(PrintJobListener) + */ + public void addPrintJobListener(PrintJobListener listener) + { + if (listener == null) + return; + + printJobListener.add(listener); + } + + /** + * @see javax.print.DocPrintJob#getAttributes() + */ + public PrintJobAttributeSet getAttributes() + { + return AttributeSetUtilities.unmodifiableView(currentSet); + } + + /** + * @see javax.print.DocPrintJob#getPrintService() + */ + public PrintService getPrintService() + { + return service; + } + + /** + * @see DocPrintJob#print(Doc, PrintRequestAttributeSet) + */ + public void print(Doc doc, PrintRequestAttributeSet attributes) + throws PrintException + { + if (printing) + throw new PrintException("already printing"); + + printing = true; + + DocAttributeSet docAtts = doc.getAttributes(); + DocFlavor flavor = doc.getDocFlavor(); + + if (flavor == null || (!service.isDocFlavorSupported(flavor))) + { + notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED)); + throw new PrintFlavorException("Invalid flavor", new DocFlavor[] {flavor}); + } + + // merge attributes as doc attributes take precendence + // over the print request attributes + HashAttributeSet mergedAtts = new HashAttributeSet(); + + if (attributes != null) + mergedAtts.addAll(attributes); + if (docAtts != null) + mergedAtts.addAll(docAtts); + + // check for requesting-user-name -add the + // executing username if no other is specified + // save user name so we can make a cancel operation under same user + if (! mergedAtts.containsKey(RequestingUserName.class)) + { + mergedAtts.add(IppPrintService.REQUESTING_USER_NAME); + requestingUser = IppPrintService.REQUESTING_USER_NAME; + } + else + { + requestingUser = (RequestingUserName) + mergedAtts.get(RequestingUserName.class); + } + + // same for job-name + if (! mergedAtts.containsKey(JobName.class)) + mergedAtts.add(IppPrintService.JOB_NAME); + + IppResponse response = null; + + try + { + PrinterURI printerUri = service.getPrinterURI(); + String printerUriStr = "http" + printerUri.toString().substring(3); + + URI uri = null; + try + { + uri = new URI(printerUriStr); + } + catch (URISyntaxException e) + { + // does not happen + } + + IppRequest request = + new IppRequest(uri, username, password); + + request.setOperationID( (short) OperationsSupported.PRINT_JOB.getValue()); + request.setOperationAttributeDefaults(); + request.addOperationAttribute(printerUri); + + if (mergedAtts != null) + { + request.addAndFilterJobOperationAttributes(mergedAtts); + request.addAndFilterJobTemplateAttributes(mergedAtts); + } + + // DocFlavor getMimeType returns charset quoted + DocumentFormat format = DocumentFormat.createDocumentFormat(flavor); + request.addOperationAttribute(format); + + // Get and set the printdata based on the + // representation classname + String className = flavor.getRepresentationClassName(); + + if (className.equals("[B")) + { + request.setData((byte[]) doc.getPrintData()); + response = request.send(); + } + else if (className.equals("java.io.InputStream")) + { + InputStream stream = (InputStream) doc.getPrintData(); + request.setData(stream); + response = request.send(); + stream.close(); + } + else if (className.equals("[C")) + { + try + { + // CUPS only supports UTF-8 currently so we convert + // We also assume that char[] is always utf-16 - correct ? + String str = new String((char[]) doc.getPrintData()); + request.setData(str.getBytes("utf-16")); + response = request.send(); + } + catch (UnsupportedEncodingException e) + { + notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED)); + throw new PrintFlavorException("Invalid charset of flavor", e, new DocFlavor[] {flavor}); + } + } + else if (className.equals("java.io.Reader")) + { + try + { + // FIXME Implement + // Convert a Reader into a InputStream properly encoded + response = request.send(); + throw new UnsupportedEncodingException("not supported yet"); + } + catch (UnsupportedEncodingException e) + { + notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED)); + throw new PrintFlavorException("Invalid charset of flavor", e, new DocFlavor[] {flavor}); + } + } + else if (className.equals("java.lang.String")) + { + try + { + // CUPS only supports UTF-8 currently so we convert + // We also assume that String is always utf-16 - correct ? + String str = (String) doc.getPrintData(); + request.setData(str.getBytes("utf-16")); + response = request.send(); + } + catch (UnsupportedEncodingException e) + { + notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED)); + throw new PrintFlavorException("Invalid charset of flavor", e, new DocFlavor[] {flavor}); + } + } + else if (className.equals("java.net.URL")) + { + URL url = (URL) doc.getPrintData(); + InputStream stream = url.openStream(); + request.setData(stream); + response = request.send(); + stream.close(); + } + else if (className.equals("java.awt.image.renderable.RenderableImage") + || className.equals("java.awt.print.Printable") + || className.equals("java.awt.print.Pageable")) + { + // For the future :-) + throw new PrintException("Not yet supported."); + } + else + { + // should not happen - however + notifyPrintJobListeners(new PrintJobEvent(this, PrintJobEvent.JOB_FAILED)); + throw new PrintFlavorException("Invalid flavor", new DocFlavor[] {flavor}); + } + + // at this point the data is transfered + notifyPrintJobListeners(new PrintJobEvent( + this, PrintJobEvent.DATA_TRANSFER_COMPLETE)); + } + catch (IOException e) + { + throw new PrintException("IOException occured.", e); + } + + int status = response.getStatusCode(); + if (! (status == IppStatusCode.SUCCESSFUL_OK + || status == IppStatusCode.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUED_ATTRIBUTES + || status == IppStatusCode.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) ) + { + notifyPrintJobListeners(new PrintJobEvent( + this, PrintJobEvent.JOB_FAILED)); + throw new PrintException("Printing failed - received statuscode " + Integer.toHexString(status)); + + // TODO maybe specific status codes may require to throw a specific + // detailed attribute exception + } + else + { + // start print job progress monitoring thread + // FIXME Implement + + // for now we just notify as finished + notifyPrintJobListeners( + new PrintJobEvent(this, PrintJobEvent.JOB_COMPLETE)); + } + + List jobAtts = response.getJobAttributes(); + + // extract the uri and id of job for canceling and further monitoring + Map jobAttributes = (Map) jobAtts.get(0); + jobUri = (JobUri) ((HashSet)jobAttributes.get(JobUri.class)).toArray()[0]; + jobId = (JobId) ((HashSet)jobAttributes.get(JobId.class)).toArray()[0]; + } + + /** + * @see DocPrintJob#removePrintJobAttributeListener(PrintJobAttributeListener) + */ + public void removePrintJobAttributeListener(PrintJobAttributeListener listener) + { + if (listener == null) + return; + + int index = attributesListener.indexOf(listener); + if (index != -1) + { + attributesListener.remove(index); + attributesListenerAttributes.remove(index); + } + } + + /** + * @see DocPrintJob#removePrintJobListener(PrintJobListener) + */ + public void removePrintJobListener(PrintJobListener listener) + { + if (listener == null) + return; + + printJobListener.remove(listener); + } + + /** + * @see CancelablePrintJob#cancel() + */ + public void cancel() throws PrintException + { + if (jobUri == null) + { + throw new PrintException("print job is not yet send"); + } + + IppResponse response = null; + + try + { + IppRequest request = new IppRequest(jobUri.getURI(), username, password); + request.setOperationID( (short) OperationsSupported.CANCEL_JOB.getValue()); + request.setOperationAttributeDefaults(); + request.addOperationAttribute(jobUri); + request.addOperationAttribute(requestingUser); + response = request.send(); + } + catch (IOException e) + { + throw new IppException("IOException occured during cancel request.", e); + } + + int status = response.getStatusCode(); + if (! (status == IppStatusCode.SUCCESSFUL_OK + || status == IppStatusCode.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUED_ATTRIBUTES + || status == IppStatusCode.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) ) + { + notifyPrintJobListeners(new PrintJobEvent( + this, PrintJobEvent.JOB_FAILED)); + throw new PrintException("Canceling failed - received statuscode " + Integer.toHexString(status)); + } + else + { + notifyPrintJobListeners(new PrintJobEvent( + this, PrintJobEvent.JOB_CANCELED)); + } + } + + private void notifyPrintJobListeners(PrintJobEvent e) + { + Iterator it = printJobListener.iterator(); + while (it.hasNext()) + { + PrintJobListener l = (PrintJobListener) it.next(); + if (e.getPrintEventType() == PrintJobEvent.DATA_TRANSFER_COMPLETE) + l.printDataTransferCompleted(e); + else if (e.getPrintEventType() == PrintJobEvent.JOB_CANCELED) + l.printJobCanceled(e); + else if (e.getPrintEventType() == PrintJobEvent.JOB_COMPLETE) + l.printJobCompleted(e); + else if (e.getPrintEventType() == PrintJobEvent.JOB_FAILED) + l.printJobFailed(e); + else if (e.getPrintEventType() == PrintJobEvent.NO_MORE_EVENTS) + l.printJobNoMoreEvents(e); + else + l.printJobRequiresAttention(e); + } + } + +} |