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.ByteArrayOutputStream;
023: import java.io.IOException;
024: import java.util.ArrayList;
025:
026: import javax.print.DocFlavor;
027: import javax.print.DocPrintJob;
028: import javax.print.PrintService;
029: import javax.print.ServiceUIFactory;
030: import javax.print.StreamPrintService;
031: import javax.print.StreamPrintServiceFactory;
032: import javax.print.attribute.Attribute;
033: import javax.print.attribute.AttributeSet;
034: import javax.print.attribute.AttributeSetUtilities;
035: import javax.print.attribute.HashAttributeSet;
036: import javax.print.attribute.PrintServiceAttribute;
037: import javax.print.attribute.PrintServiceAttributeSet;
038: import javax.print.event.PrintServiceAttributeListener;
039:
040: public class DefaultPrintService implements PrintService {
041:
042: //= Fields ===============================================================//
043:
044: private PrintClient client = null;
045: private EventNotifier notifier = null;
046: private String serviceName = null;
047:
048: //= Constructors =========================================================//
049:
050: public DefaultPrintService(String servicename,
051: PrintClient printclient) {
052: if (printclient == null || servicename == null) {
053: throw new NullPointerException("Argument is null");
054: }
055:
056: this .client = printclient;
057: this .serviceName = servicename;
058: notifier = EventNotifier.getNotifier();
059: }
060:
061: //= Basic methods ======================================================//
062:
063: PrintClient getPrintClient() {
064: return client;
065: }
066:
067: public String getName() {
068: return serviceName;
069: }
070:
071: public boolean equals(Object obj) {
072: if (obj instanceof DefaultPrintService) {
073: DefaultPrintService service = (DefaultPrintService) obj;
074: if (service.getName().equals(serviceName)) {
075: return true;
076: }
077: }
078: return false;
079: }
080:
081: public int hashCode() {
082: return serviceName.hashCode();
083: }
084:
085: public String toString() {
086: return "Printer : " + serviceName;
087: }
088:
089: //= Print service attributes ===========================================//
090:
091: public PrintServiceAttribute getAttribute(Class category) {
092: if (!PrintServiceAttribute.class.isAssignableFrom(category)) {
093: throw new IllegalArgumentException();
094: }
095: PrintServiceAttributeSet attributes = getAttributes();
096: if (attributes.containsKey(category)) {
097: PrintServiceAttribute attribute = (PrintServiceAttribute) attributes
098: .get(category);
099: return attribute;
100: }
101: return null;
102: }
103:
104: public PrintServiceAttributeSet getAttributes() {
105: return AttributeSetUtilities.unmodifiableView(client
106: .getAttributes());
107: }
108:
109: //= Print request attributes =============================================//
110:
111: public Class[] getSupportedAttributeCategories() {
112: return client.getSupportedAttributeCategories();
113: }
114:
115: public boolean isAttributeCategorySupported(Class category) {
116: if (category == null) {
117: throw new NullPointerException(
118: "Argument 'category' is null");
119: }
120: if (!(Attribute.class.isAssignableFrom(category))) {
121: throw new IllegalArgumentException(
122: "Argument 'category' must implement interface Attribute");
123: }
124:
125: Class[] categories = getSupportedAttributeCategories();
126: for (int i = 0; i < categories.length; i++) {
127: if (categories[i].equals(category)) {
128: return true;
129: }
130: }
131: return false;
132: }
133:
134: public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
135: AttributeSet attributes) {
136: if (attributes == null) {
137: return null;
138: }
139: if (flavor != null && !isDocFlavorSupported(flavor)) {
140: throw new IllegalArgumentException("Flavor "
141: + flavor.getMimeType()
142: + " is not supported by print service");
143: }
144:
145: Attribute[] attrs = attributes.toArray();
146: HashAttributeSet unsupported = new HashAttributeSet();
147: for (int i = 0; i < attrs.length; i++) {
148: if (!isAttributeValueSupported(attrs[i], flavor, attributes)) {
149: unsupported.add(attrs[i]);
150: }
151: }
152: if (unsupported.size() > 0) {
153: return unsupported;
154: }
155: return null;
156: }
157:
158: public Object getDefaultAttributeValue(Class category) {
159: if (category == null) {
160: throw new NullPointerException(
161: "Argument 'category' is null");
162: }
163: if (!(Attribute.class.isAssignableFrom(category))) {
164: throw new IllegalArgumentException(
165: "Argument 'category' must implement interface Attribute");
166: }
167:
168: return client.getDefaultAttributeValue(category);
169: }
170:
171: public Object getSupportedAttributeValues(Class category,
172: DocFlavor flavor, AttributeSet attributes) {
173: if (category == null) {
174: throw new NullPointerException("Argument is null");
175: }
176: if (!(Attribute.class.isAssignableFrom(category))) {
177: throw new IllegalArgumentException(
178: "Argument must implement interface Attribute");
179: }
180: if (flavor == null) {
181: return client.getSupportedAttributeValues(category, flavor,
182: attributes);
183: }
184:
185: DocFlavor clientFlavors[] = client.getSupportedDocFlavors();
186: if (isDocFlavorSupportedByClient(flavor, clientFlavors)) {
187: return client.getSupportedAttributeValues(category, flavor,
188: attributes);
189: }
190: /*
191: * Searching stream print service factories, which
192: * able to convert print data to flavor supported by
193: * PrintClient (both user and internal). And then,
194: * return supported attributes by created stream print
195: * service
196: */
197: for (int i = 0; i < clientFlavors.length; i++) {
198: StreamPrintServiceFactory[] factories = StreamPrintServiceFactory
199: .lookupStreamPrintServiceFactories(flavor,
200: clientFlavors[i].getMimeType());
201: for (int j = 0; j < factories.length; j++) {
202: StreamPrintService sps = factories[j]
203: .getPrintService(new ByteArrayOutputStream());
204: if (sps != null) {
205: try {
206: sps.getOutputStream().close();
207: } catch (IOException e) {
208: // just ignore
209: }
210: sps.dispose();
211: //return sps.getSupportedAttributeValues(category,
212: // flavor, attributes);
213: return client.getSupportedAttributeValues(category,
214: clientFlavors[i], attributes);
215: }
216: }
217: }
218:
219: throw new IllegalArgumentException("DocFlavor '" + flavor
220: + "' is not supported by the print service");
221: }
222:
223: public boolean isAttributeValueSupported(Attribute attrval,
224: DocFlavor flavor, AttributeSet attributes) {
225: if (attrval == null) {
226: throw new NullPointerException("Argument is null");
227: }
228:
229: if (flavor == null) {
230: return client.isAttributeValueSupported(attrval, flavor,
231: attributes);
232: }
233:
234: DocFlavor clientFlavors[] = client.getSupportedDocFlavors();
235: if (isDocFlavorSupportedByClient(flavor, clientFlavors)) {
236: return client.isAttributeValueSupported(attrval, flavor,
237: attributes);
238: }
239:
240: /*
241: * Searching stream print service factories, which
242: * able to convert print data to flavor supported by
243: * PrintClient (both user and internal). And then,
244: * return supported attributes by created stream print
245: * service
246: */
247: for (int i = 0; i < clientFlavors.length; i++) {
248: StreamPrintServiceFactory[] factories = StreamPrintServiceFactory
249: .lookupStreamPrintServiceFactories(flavor,
250: clientFlavors[i].getMimeType());
251: for (int j = 0; j < factories.length; j++) {
252: StreamPrintService sps = factories[j]
253: .getPrintService(new ByteArrayOutputStream());
254: if (sps != null) {
255: try {
256: sps.getOutputStream().close();
257: } catch (IOException e) {
258: // just ignore
259: }
260: sps.dispose();
261: //return sps.isAttributeValueSupported(attrval, flavor, attributes);
262: return client.isAttributeValueSupported(attrval,
263: clientFlavors[i], attributes);
264: }
265: }
266: }
267:
268: throw new IllegalArgumentException("DocFlavor '" + flavor
269: + "' is not supported by the print service");
270:
271: }
272:
273: //= Listeners ============================================================//
274:
275: public void addPrintServiceAttributeListener(
276: PrintServiceAttributeListener listener) {
277: notifier.addListener(this , listener);
278: }
279:
280: public void removePrintServiceAttributeListener(
281: PrintServiceAttributeListener listener) {
282: notifier.removeListener(this , listener);
283: }
284:
285: //= DocFlavors ===========================================================//
286:
287: /*
288: * Returns two categories of DocFlavors:
289: * 1) DocFlavors supported by PrintClient
290: * 2) DocFlavors that can be converted by StreamPrintServices to
291: * PrintClient's DocFlavors
292: *
293: * If there is a DocFlavor that supported by PrintClient and by
294: * StreamPrintService, the method returns PrintClient's one only.
295: */
296:
297: public DocFlavor[] getSupportedDocFlavors() {
298: DocFlavor clientFlavors[] = client.getSupportedDocFlavors();
299: ArrayList flavors = new ArrayList();
300:
301: /*
302: * Putting all PrintClient's supported flavors (except
303: * internal flavors) into list of flavors supported by
304: * this print service.
305: */
306: for (int i = 0; i < clientFlavors.length; i++) {
307: if (!isInternalDocFlavor(clientFlavors[i])) {
308: flavors.add(clientFlavors[i]);
309: }
310: }
311:
312: /*
313: * Searching stream print service factories, which
314: * able to convert print data to flavor supported by
315: * PrintClient (both user and internal). And then,
316: * gathering all flavors supported by those factories
317: * and putting them into list of flavors supported
318: * by this print service.
319: */
320: for (int i = 0; i < clientFlavors.length; i++) {
321: StreamPrintServiceFactory[] factories = StreamPrintServiceFactory
322: .lookupStreamPrintServiceFactories(null,
323: clientFlavors[i].getMimeType());
324: for (int j = 0; j < factories.length; j++) {
325: DocFlavor[] factoryFlavors = factories[j]
326: .getSupportedDocFlavors();
327: for (int k = 0; k < factoryFlavors.length; k++) {
328: if (!flavors.contains(factoryFlavors[k])) {
329: flavors.add(factoryFlavors[k]);
330: }
331: }
332: }
333: }
334: return (DocFlavor[]) flavors.toArray(new DocFlavor[0]);
335: }
336:
337: public boolean isDocFlavorSupported(DocFlavor flavor) {
338: if (flavor == null) {
339: throw new NullPointerException("DocFlavor flavor is null");
340: }
341:
342: DocFlavor[] flavors = getSupportedDocFlavors();
343: for (int i = 0; i < flavors.length; i++) {
344: if (flavors[i].equals(flavor)) {
345: return true;
346: }
347: }
348: return false;
349: }
350:
351: /*
352: * Checks, whether specified falvor is internal or not.
353: */
354: private boolean isInternalDocFlavor(DocFlavor flavor) {
355: if (flavor.getMimeType().toLowerCase().indexOf("internal") != -1) {
356: return true;
357: }
358: return false;
359: }
360:
361: /*
362: * Checks, whether specified falvor is supported by
363: * PrintClient or not.
364: */
365: boolean isDocFlavorSupportedByClient(DocFlavor flavor) {
366: DocFlavor clientFlavors[] = client.getSupportedDocFlavors();
367: for (int i = 0; i < clientFlavors.length; i++) {
368: if (clientFlavors[i].equals(flavor)) {
369: return true;
370: }
371: }
372: return false;
373: }
374:
375: boolean isDocFlavorSupportedByClient(DocFlavor flavor,
376: DocFlavor[] clientFlavors) {
377: for (int i = 0; i < clientFlavors.length; i++) {
378: if (clientFlavors[i].equals(flavor)) {
379: return true;
380: }
381: }
382: return false;
383: }
384:
385: //= Service user interface factory =======================================//
386:
387: public ServiceUIFactory getServiceUIFactory() {
388: // We have not service user interface factory
389: return null;
390: }
391:
392: //= DocPrintJob ==========================================================//
393:
394: public DocPrintJob createPrintJob() {
395: return new DefaultPrintJob(this);
396: }
397: }
|