blob: 3fe4bbfb3803d30925039e9d7660376d056f8938 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.print;
27
28import java.io.OutputStream;
29import java.util.Iterator;
30import java.util.Locale;
31
32import javax.print.DocFlavor;
33import javax.print.DocPrintJob;
34import javax.print.StreamPrintService;
35import javax.print.StreamPrintServiceFactory;
36import javax.print.ServiceUIFactory;
37import javax.print.attribute.Attribute;
38import javax.print.attribute.AttributeSet;
39import javax.print.attribute.AttributeSetUtilities;
40import javax.print.attribute.HashAttributeSet;
41import javax.print.attribute.HashPrintServiceAttributeSet;
42import javax.print.attribute.PrintServiceAttribute;
43import javax.print.attribute.PrintServiceAttributeSet;
44import javax.print.attribute.Size2DSyntax;
45import javax.print.event.PrintServiceAttributeListener;
46import javax.print.attribute.standard.JobName;
47import javax.print.attribute.standard.RequestingUserName;
48import javax.print.attribute.standard.Chromaticity;
49import javax.print.attribute.standard.ColorSupported;
50import javax.print.attribute.standard.Copies;
51import javax.print.attribute.standard.CopiesSupported;
52import javax.print.attribute.standard.Fidelity;
53import javax.print.attribute.standard.Media;
54import javax.print.attribute.standard.MediaPrintableArea;
55import javax.print.attribute.standard.MediaSize;
56import javax.print.attribute.standard.MediaSizeName;
57import javax.print.attribute.standard.OrientationRequested;
58import javax.print.attribute.standard.PageRanges;
59import javax.print.attribute.standard.SheetCollate;
60import javax.print.attribute.standard.Sides;
61
62public class PSStreamPrintService extends StreamPrintService
63 implements SunPrinterJobService {
64
65 private static final Class[] suppAttrCats = {
66 Chromaticity.class,
67 Copies.class,
68 Fidelity.class,
69 JobName.class,
70 Media.class,
71 MediaPrintableArea.class,
72 OrientationRequested.class,
73 PageRanges.class,
74 RequestingUserName.class,
75 SheetCollate.class,
76 Sides.class,
77 };
78
79 private static int MAXCOPIES = 1000;
80
81 private static final MediaSizeName mediaSizes[] = {
82 MediaSizeName.NA_LETTER,
83 MediaSizeName.TABLOID,
84 MediaSizeName.LEDGER,
85 MediaSizeName.NA_LEGAL,
86 MediaSizeName.EXECUTIVE,
87 MediaSizeName.ISO_A3,
88 MediaSizeName.ISO_A4,
89 MediaSizeName.ISO_A5,
90 MediaSizeName.ISO_B4,
91 MediaSizeName.ISO_B5,
92 };
93
94 public PSStreamPrintService(OutputStream out) {
95 super(out);
96 }
97
98 public String getOutputFormat() {
99 return PSStreamPrinterFactory.psMimeType;
100 }
101
102
103 public DocFlavor[] getSupportedDocFlavors() {
104 return PSStreamPrinterFactory.getFlavors();
105 }
106
107 public DocPrintJob createPrintJob() {
108 return new PSStreamPrintJob(this);
109 }
110
111 public boolean usesClass(Class c) {
112 return (c == sun.print.PSPrinterJob.class);
113 }
114
115 public String getName() {
116 return "Postscript output";
117 }
118
119 public void addPrintServiceAttributeListener(
120 PrintServiceAttributeListener listener) {
121 return;
122 }
123
124 public void removePrintServiceAttributeListener(
125 PrintServiceAttributeListener listener) {
126 return;
127 }
128
129
130 public <T extends PrintServiceAttribute>
131 T getAttribute(Class<T> category)
132 {
133 if (category == null) {
134 throw new NullPointerException("category");
135 }
136 if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {
137 throw new IllegalArgumentException("Not a PrintServiceAttribute");
138 }
139 if (category == ColorSupported.class) {
140 return (T)ColorSupported.SUPPORTED;
141 } else {
142 return null;
143 }
144 }
145 public PrintServiceAttributeSet getAttributes() {
146 PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
147 attrs.add(ColorSupported.SUPPORTED);
148
149 return AttributeSetUtilities.unmodifiableView(attrs);
150 }
151
152 public boolean isDocFlavorSupported(DocFlavor flavor) {
153 DocFlavor [] flavors = getSupportedDocFlavors();
154 for (int f=0; f<flavors.length; f++) {
155 if (flavor.equals(flavors[f])) {
156 return true;
157 }
158 }
159 return false;
160 }
161
162
163 public Class<?>[] getSupportedAttributeCategories() {
164 Class []cats = new Class[suppAttrCats.length];
165 System.arraycopy(suppAttrCats, 0, cats, 0, cats.length);
166 return cats;
167 }
168
169 public boolean
170 isAttributeCategorySupported(Class<? extends Attribute> category)
171 {
172 if (category == null) {
173 throw new NullPointerException("null category");
174 }
175 if (!(Attribute.class.isAssignableFrom(category))) {
176 throw new IllegalArgumentException(category +
177 " is not an Attribute");
178 }
179
180 for (int i=0;i<suppAttrCats.length;i++) {
181 if (category == suppAttrCats[i]) {
182 return true;
183 }
184 }
185 return false;
186 }
187
188
189 public Object
190 getDefaultAttributeValue(Class<? extends Attribute> category)
191 {
192 if (category == null) {
193 throw new NullPointerException("null category");
194 }
195 if (!Attribute.class.isAssignableFrom(category)) {
196 throw new IllegalArgumentException(category +
197 " is not an Attribute");
198 }
199
200 if (!isAttributeCategorySupported(category)) {
201 return null;
202 }
203
204 if (category == Copies.class) {
205 return new Copies(1);
206 } else if (category == Chromaticity.class) {
207 return Chromaticity.COLOR;
208 } else if (category == Fidelity.class) {
209 return Fidelity.FIDELITY_FALSE;
210 } else if (category == Media.class) {
211 String defaultCountry = Locale.getDefault().getCountry();
212 if (defaultCountry != null &&
213 (defaultCountry.equals("") ||
214 defaultCountry.equals(Locale.US.getCountry()) ||
215 defaultCountry.equals(Locale.CANADA.getCountry()))) {
216 return MediaSizeName.NA_LETTER;
217 } else {
218 return MediaSizeName.ISO_A4;
219 }
220 } else if (category == MediaPrintableArea.class) {
221 String defaultCountry = Locale.getDefault().getCountry();
222 float iw, ih;
223 float margin = 0.5f; // both these papers > 5" in all dimensions
224 if (defaultCountry != null &&
225 (defaultCountry.equals("") ||
226 defaultCountry.equals(Locale.US.getCountry()) ||
227 defaultCountry.equals(Locale.CANADA.getCountry()))) {
228 iw = MediaSize.NA.LETTER.getX(Size2DSyntax.INCH) - 2*margin;
229 ih = MediaSize.NA.LETTER.getY(Size2DSyntax.INCH) - 2*margin;
230 } else {
231 iw = MediaSize.ISO.A4.getX(Size2DSyntax.INCH) - 2*margin;
232 ih = MediaSize.ISO.A4.getY(Size2DSyntax.INCH) - 2*margin;
233 }
234 return new MediaPrintableArea(margin, margin, iw, ih,
235 MediaPrintableArea.INCH);
236 } else if (category == OrientationRequested.class) {
237 return OrientationRequested.PORTRAIT;
238 } else if (category == PageRanges.class) {
239 return new PageRanges(1, Integer.MAX_VALUE);
240 } else if (category == SheetCollate.class) {
241 return SheetCollate.UNCOLLATED;
242 } else if (category == Sides.class) {
243 return Sides.ONE_SIDED;
244
245 } else
246 return null;
247 }
248
249
250 public Object
251 getSupportedAttributeValues(Class<? extends Attribute> category,
252 DocFlavor flavor,
253 AttributeSet attributes)
254 {
255
256 if (category == null) {
257 throw new NullPointerException("null category");
258 }
259 if (!Attribute.class.isAssignableFrom(category)) {
260 throw new IllegalArgumentException(category +
261 " does not implement Attribute");
262 }
263 if (flavor != null && !isDocFlavorSupported(flavor)) {
264 throw new IllegalArgumentException(flavor +
265 " is an unsupported flavor");
266 }
267
268 if (!isAttributeCategorySupported(category)) {
269 return null;
270 }
271
272 if (category == Chromaticity.class) {
273 Chromaticity[]arr = new Chromaticity[1];
274 arr[0] = Chromaticity.COLOR;
275 //arr[1] = Chromaticity.MONOCHROME;
276 return (arr);
277 } else if (category == JobName.class) {
278 return new JobName("", null);
279 } else if (category == RequestingUserName.class) {
280 return new RequestingUserName("", null);
281 } else if (category == OrientationRequested.class) {
282 if (flavor == null ||
283 flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
284 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
285 OrientationRequested []arr = new OrientationRequested[3];
286 arr[0] = OrientationRequested.PORTRAIT;
287 arr[1] = OrientationRequested.LANDSCAPE;
288 arr[2] = OrientationRequested.REVERSE_LANDSCAPE;
289 return arr;
290 } else {
291 return null;
292 }
293 } else if ((category == Copies.class) ||
294 (category == CopiesSupported.class)) {
295 return new CopiesSupported(1, MAXCOPIES);
296 } else if (category == Media.class) {
297 Media []arr = new Media[mediaSizes.length];
298 System.arraycopy(mediaSizes, 0, arr, 0, mediaSizes.length);
299 return arr;
300 } else if (category == Fidelity.class) {
301 Fidelity []arr = new Fidelity[2];
302 arr[0] = Fidelity.FIDELITY_FALSE;
303 arr[1] = Fidelity.FIDELITY_TRUE;
304 return arr;
305 } else if (category == MediaPrintableArea.class) {
306 if (attributes == null) {
307 return null;
308 }
309 MediaSize mediaSize = (MediaSize)attributes.get(MediaSize.class);
310 if (mediaSize == null) {
311 Media media = (Media)attributes.get(Media.class);
312 if (media != null && media instanceof MediaSizeName) {
313 MediaSizeName msn = (MediaSizeName)media;
314 mediaSize = MediaSize.getMediaSizeForName(msn);
315 }
316 }
317 if (mediaSize == null) {
318 return null;
319 } else {
320 MediaPrintableArea []arr = new MediaPrintableArea[1];
321 float w = mediaSize.getX(MediaSize.INCH);
322 float h = mediaSize.getY(MediaSize.INCH);
323 /* For dimensions >= 5 inches use 0.5 inch margins.
324 * For smaller dimensions, use 10% margins.
325 */
326 float xmargin = 0.5f;
327 float ymargin = 0.5f;
328 if (w < 5f) {
329 xmargin = w/10;
330 }
331 if (h < 5f) {
332 ymargin = h/10;
333 }
334 arr[0] = new MediaPrintableArea(xmargin, ymargin,
335 w - 2*xmargin,
336 h - 2*ymargin,
337 MediaSize.INCH);
338 return arr;
339 }
340 } else if (category == PageRanges.class) {
341 if (flavor == null ||
342 flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
343 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
344 PageRanges []arr = new PageRanges[1];
345 arr[0] = new PageRanges(1, Integer.MAX_VALUE);
346 return arr;
347 } else {
348 return null;
349 }
350 } else if (category == SheetCollate.class) {
351 if (flavor == null ||
352 flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
353 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
354 SheetCollate []arr = new SheetCollate[2];
355 arr[0] = SheetCollate.UNCOLLATED;
356 arr[1] = SheetCollate.COLLATED;
357 return arr;
358 } else {
359 SheetCollate []arr = new SheetCollate[1];
360 arr[0] = SheetCollate.UNCOLLATED;
361 return arr;
362 }
363 } else if (category == Sides.class) {
364 if (flavor == null ||
365 flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
366 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
367 Sides []arr = new Sides[3];
368 arr[0] = Sides.ONE_SIDED;
369 arr[1] = Sides.TWO_SIDED_LONG_EDGE;
370 arr[2] = Sides.TWO_SIDED_SHORT_EDGE;
371 return arr;
372 } else {
373 return null;
374 }
375 } else {
376 return null;
377 }
378 }
379
380 private boolean isSupportedCopies(Copies copies) {
381 int numCopies = copies.getValue();
382 return (numCopies > 0 && numCopies < MAXCOPIES);
383 }
384
385 private boolean isSupportedMedia(MediaSizeName msn) {
386 for (int i=0; i<mediaSizes.length; i++) {
387 if (msn.equals(mediaSizes[i])) {
388 return true;
389 }
390 }
391 return false;
392 }
393
394 public boolean isAttributeValueSupported(Attribute attr,
395 DocFlavor flavor,
396 AttributeSet attributes) {
397 if (attr == null) {
398 throw new NullPointerException("null attribute");
399 }
400 if (flavor != null && !isDocFlavorSupported(flavor)) {
401 throw new IllegalArgumentException(flavor +
402 " is an unsupported flavor");
403 }
404 Class category = attr.getCategory();
405 if (!isAttributeCategorySupported(category)) {
406 return false;
407 }
408 else if (attr.getCategory() == Chromaticity.class) {
409 return attr == Chromaticity.COLOR;
410 }
411 else if (attr.getCategory() == Copies.class) {
412 return isSupportedCopies((Copies)attr);
413 } else if (attr.getCategory() == Media.class &&
414 attr instanceof MediaSizeName) {
415 return isSupportedMedia((MediaSizeName)attr);
416 } else if (attr.getCategory() == OrientationRequested.class) {
417 if (attr == OrientationRequested.REVERSE_PORTRAIT ||
418 (flavor != null) &&
419 !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
420 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
421 return false;
422 }
423 } else if (attr.getCategory() == PageRanges.class) {
424 if (flavor != null &&
425 !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
426 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
427 return false;
428 }
429 } else if (attr.getCategory() == SheetCollate.class) {
430 if (flavor != null &&
431 !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
432 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
433 return false;
434 }
435 } else if (attr.getCategory() == Sides.class) {
436 if (flavor != null &&
437 !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
438 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
439 return false;
440 }
441 }
442 return true;
443 }
444
445 public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
446 AttributeSet attributes) {
447
448 if (flavor != null && !isDocFlavorSupported(flavor)) {
449 throw new IllegalArgumentException("flavor " + flavor +
450 "is not supported");
451 }
452
453 if (attributes == null) {
454 return null;
455 }
456
457 Attribute attr;
458 AttributeSet unsupp = new HashAttributeSet();
459 Attribute[] attrs = attributes.toArray();
460 for (int i=0; i<attrs.length; i++) {
461 try {
462 attr = attrs[i];
463 if (!isAttributeCategorySupported(attr.getCategory())) {
464 unsupp.add(attr);
465 } else if (!isAttributeValueSupported(attr, flavor,
466 attributes)) {
467 unsupp.add(attr);
468 }
469 } catch (ClassCastException e) {
470 }
471 }
472 if (unsupp.isEmpty()) {
473 return null;
474 } else {
475 return unsupp;
476 }
477 }
478
479 public ServiceUIFactory getServiceUIFactory() {
480 return null;
481 }
482
483 public String toString() {
484 return "PSStreamPrintService: " + getName();
485 }
486
487 /* Stream services have an output stream which cannot be shared,
488 * so two services are equal only if they are the same object.
489 */
490 public boolean equals(Object obj) {
491 return (obj == this ||
492 (obj instanceof PSStreamPrintService &&
493 ((PSStreamPrintService)obj).getName().equals(getName())));
494 }
495
496 public int hashCode() {
497 return this.getClass().hashCode()+getName().hashCode();
498 }
499
500}