001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Aleksei V. Ivaschenko
019: * @version $Revision: 1.2 $
020: */package org.apache.harmony.x.print;
021:
022: import java.io.IOException;
023: import java.io.PipedInputStream;
024: import java.io.PipedOutputStream;
025:
026: import javax.print.Doc;
027: import javax.print.DocFlavor;
028: import javax.print.DocPrintJob;
029: import javax.print.PrintException;
030: import javax.print.PrintService;
031: import javax.print.SimpleDoc;
032: import javax.print.StreamPrintService;
033: import javax.print.StreamPrintServiceFactory;
034: import javax.print.attribute.AttributeSetUtilities;
035: import javax.print.attribute.HashPrintJobAttributeSet;
036: import javax.print.attribute.PrintJobAttributeSet;
037: import javax.print.attribute.PrintRequestAttributeSet;
038: import javax.print.event.PrintJobAttributeListener;
039: import javax.print.event.PrintJobListener;
040:
041: public class DefaultPrintJob implements DocPrintJob {
042: DefaultPrintService printService;
043: PrintClient printClient;
044: PrintJobAttributeSet printJobAS;
045: boolean busyFlag;
046:
047: public DefaultPrintJob(DefaultPrintService printservice) {
048: if (printservice == null) {
049: throw new NullPointerException("Argument is null");
050: }
051: this .printService = printservice;
052: this .printClient = printService.getPrintClient();
053: printJobAS = new HashPrintJobAttributeSet();
054: busyFlag = false;
055: }
056:
057: public PrintService getPrintService() {
058: return printService;
059: }
060:
061: public PrintJobAttributeSet getAttributes() {
062: return AttributeSetUtilities.unmodifiableView(printJobAS);
063: }
064:
065: //=======================================================================//
066: public void print(Doc userDoc,
067: PrintRequestAttributeSet printRequestAS)
068: throws PrintException {
069:
070: synchronized (this ) {
071: if (busyFlag) {
072: throw new PrintException(
073: "Already printed. Need to create new DocPrintJob.");
074: }
075: busyFlag = true;
076: }
077:
078: DocFlavor userDocDF = userDoc.getDocFlavor();
079:
080: /*
081: * Checking if doc.DocFlavor is supported by the current
082: * PrintService
083: */
084: if (!printService.isDocFlavorSupported(userDocDF)) {
085: throw new PrintException("Doc flavor \'" + userDocDF
086: + "\' is not supported");
087: }
088:
089: /*
090: * Checking if doc.DocFlavor is supported directly by osClent. If it
091: * is not: - get StereamPrintServiceFactory for doc.DocFlavor -
092: * instantiate StreamPrintService - get PrintJob from it - run this
093: * PrintJob in separate thread
094: */
095: printClient = printService.getPrintClient();
096: if (printService.isDocFlavorSupportedByClient(userDocDF)) {
097: printClient.print(userDoc, printRequestAS);
098: } else {
099: try {
100: Doc clientDoc = userDoc;
101: PipedOutputStream spsOutStream = new PipedOutputStream();
102: PipedInputStream clientInputStream = new PipedInputStream(
103: spsOutStream);
104:
105: DocFlavor newFlavor = null;
106: StreamPrintServiceFactory spsf = null;
107: DocFlavor clientFlavors[] = printClient
108: .getSupportedDocFlavors();
109:
110: for (int i = 0; i < clientFlavors.length; i++) {
111: StreamPrintServiceFactory[] factories = StreamPrintServiceFactory
112: .lookupStreamPrintServiceFactories(
113: userDocDF, clientFlavors[i]
114: .getMimeType());
115: if (factories.length > 0
116: && Class
117: .forName(
118: clientFlavors[i]
119: .getRepresentationClassName())
120: .isInstance(clientInputStream)) {
121: spsf = factories[0];
122: newFlavor = clientFlavors[i];
123: break;
124: }
125: }
126:
127: if (spsf != null) {
128: StreamPrintService sps = spsf
129: .getPrintService(spsOutStream);
130:
131: /*
132: * Constructing new Doc object for client: - connecting
133: * InputStream of client with OutputStream of
134: * StreamPrintSrevice - constructing DocFlavor for
135: * StreamPrintSrevice output - creating new SimpleDoc
136: * for client
137: */
138: clientDoc = new SimpleDoc(clientInputStream,
139: newFlavor, userDoc.getAttributes());
140:
141: PrintJobThread printThread = new PrintJobThread(
142: this , userDoc, printRequestAS, sps);
143: printThread.start();
144: printClient.print(clientDoc, printRequestAS);
145:
146: if (printThread.exceptionOccured()) {
147: throw new PrintException(printThread
148: .getPrintException());
149: }
150: } else {
151: throw new PrintException("Doc flavor "
152: + userDocDF.getRepresentationClassName()
153: + " is not supported");
154: }
155: } catch (ClassNotFoundException e) {
156: throw new PrintException(e);
157: } catch (IOException e) {
158: throw new PrintException(e);
159: } catch (PrintException e) {
160: throw e;
161: }
162: }
163: }
164:
165: //=======================================================================//
166: public void addPrintJobAttributeListener(
167: PrintJobAttributeListener listener,
168: PrintJobAttributeSet attributes) {
169: synchronized (this ) {
170: // TODO - add print job attribute listener
171: }
172: }
173:
174: public void addPrintJobListener(PrintJobListener listener) {
175: synchronized (this ) {
176: // TODO - add print job listener
177: }
178: }
179:
180: public void removePrintJobAttributeListener(
181: PrintJobAttributeListener listener) {
182: synchronized (this ) {
183: // TODO - remove print job attribute listener
184: }
185: }
186:
187: public void removePrintJobListener(PrintJobListener listener) {
188: synchronized (this ) {
189: // TODO - remove print job listener
190: }
191: }
192:
193: class PrintJobThread extends Thread {
194: DefaultPrintJob printJob;
195: Doc printDoc;
196: PrintRequestAttributeSet printAttributeSet;
197: Exception exception;
198: boolean exceptionisnotnull;
199: StreamPrintService streamservice;
200:
201: /**
202: * job - parent DefaultPrintJob doc - doc to print attributeset -
203: * attributes set spsDocPrintJob - stream print service's print job
204: */
205: PrintJobThread(DefaultPrintJob job, Doc doc,
206: PrintRequestAttributeSet attributeset,
207: StreamPrintService sps) {
208: this .printJob = job;
209: this .printDoc = doc;
210: this .printAttributeSet = attributeset;
211: this .streamservice = sps;
212: this .exception = null;
213: this .exceptionisnotnull = false;
214: }
215:
216: public void run() {
217: try {
218: DocPrintJob spsDocPrintJob = streamservice
219: .createPrintJob();
220: spsDocPrintJob.print(printDoc, printAttributeSet);
221: } catch (Exception e) {
222: exception = e;
223: exceptionisnotnull = true;
224: try {
225: streamservice.getOutputStream().close();
226: } catch (IOException ioe) {
227: // ignoring
228: }
229: }
230: }
231:
232: boolean exceptionOccured() {
233: return exceptionisnotnull;
234: }
235:
236: Exception getPrintException() {
237: return exception;
238: }
239: }
240: }
|