Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/unix/classes/sun/print/UnixPrintService.java
41152 views
1
/*
2
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.print;
27
28
import java.io.File;
29
import java.net.URI;
30
import java.net.URISyntaxException;
31
import java.util.ArrayList;
32
import java.util.Locale;
33
34
import java.awt.GraphicsEnvironment;
35
import java.awt.Toolkit;
36
import javax.print.DocFlavor;
37
import javax.print.DocPrintJob;
38
import javax.print.PrintService;
39
import javax.print.ServiceUIFactory;
40
import javax.print.attribute.Attribute;
41
import javax.print.attribute.AttributeSet;
42
import javax.print.attribute.AttributeSetUtilities;
43
import javax.print.attribute.HashAttributeSet;
44
import javax.print.attribute.PrintServiceAttribute;
45
import javax.print.attribute.PrintServiceAttributeSet;
46
import javax.print.attribute.HashPrintServiceAttributeSet;
47
import javax.print.attribute.Size2DSyntax;
48
import javax.print.attribute.standard.PrinterName;
49
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
50
import javax.print.attribute.standard.QueuedJobCount;
51
import javax.print.attribute.standard.JobName;
52
import javax.print.attribute.standard.JobSheets;
53
import javax.print.attribute.standard.RequestingUserName;
54
import javax.print.attribute.standard.Chromaticity;
55
import javax.print.attribute.standard.ColorSupported;
56
import javax.print.attribute.standard.Copies;
57
import javax.print.attribute.standard.CopiesSupported;
58
import javax.print.attribute.standard.Destination;
59
import javax.print.attribute.standard.DialogOwner;
60
import javax.print.attribute.standard.DialogTypeSelection;
61
import javax.print.attribute.standard.Fidelity;
62
import javax.print.attribute.standard.Media;
63
import javax.print.attribute.standard.MediaPrintableArea;
64
import javax.print.attribute.standard.MediaSize;
65
import javax.print.attribute.standard.MediaSizeName;
66
import javax.print.attribute.standard.OrientationRequested;
67
import javax.print.attribute.standard.PageRanges;
68
import javax.print.attribute.standard.PrinterState;
69
import javax.print.attribute.standard.PrinterStateReason;
70
import javax.print.attribute.standard.PrinterStateReasons;
71
import javax.print.attribute.standard.Severity;
72
import javax.print.attribute.standard.SheetCollate;
73
import javax.print.attribute.standard.Sides;
74
import javax.print.event.PrintServiceAttributeListener;
75
76
77
@SuppressWarnings("removal")
78
public class UnixPrintService implements PrintService, AttributeUpdater,
79
SunPrinterJobService {
80
81
/* define doc flavors for text types in the default encoding of
82
* this platform since we can always read those.
83
*/
84
private static String encoding = "ISO8859_1";
85
private static DocFlavor textByteFlavor;
86
87
private static DocFlavor[] supportedDocFlavors = null;
88
private static final DocFlavor[] supportedDocFlavorsInit = {
89
DocFlavor.BYTE_ARRAY.POSTSCRIPT,
90
DocFlavor.INPUT_STREAM.POSTSCRIPT,
91
DocFlavor.URL.POSTSCRIPT,
92
DocFlavor.BYTE_ARRAY.GIF,
93
DocFlavor.INPUT_STREAM.GIF,
94
DocFlavor.URL.GIF,
95
DocFlavor.BYTE_ARRAY.JPEG,
96
DocFlavor.INPUT_STREAM.JPEG,
97
DocFlavor.URL.JPEG,
98
DocFlavor.BYTE_ARRAY.PNG,
99
DocFlavor.INPUT_STREAM.PNG,
100
DocFlavor.URL.PNG,
101
102
DocFlavor.CHAR_ARRAY.TEXT_PLAIN,
103
DocFlavor.READER.TEXT_PLAIN,
104
DocFlavor.STRING.TEXT_PLAIN,
105
106
DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_8,
107
DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16,
108
DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16BE,
109
DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16LE,
110
DocFlavor.BYTE_ARRAY.TEXT_PLAIN_US_ASCII,
111
112
113
DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_8,
114
DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16,
115
DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16BE,
116
DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16LE,
117
DocFlavor.INPUT_STREAM.TEXT_PLAIN_US_ASCII,
118
119
120
DocFlavor.URL.TEXT_PLAIN_UTF_8,
121
DocFlavor.URL.TEXT_PLAIN_UTF_16,
122
DocFlavor.URL.TEXT_PLAIN_UTF_16BE,
123
DocFlavor.URL.TEXT_PLAIN_UTF_16LE,
124
DocFlavor.URL.TEXT_PLAIN_US_ASCII,
125
126
DocFlavor.SERVICE_FORMATTED.PAGEABLE,
127
DocFlavor.SERVICE_FORMATTED.PRINTABLE,
128
129
DocFlavor.BYTE_ARRAY.AUTOSENSE,
130
DocFlavor.URL.AUTOSENSE,
131
DocFlavor.INPUT_STREAM.AUTOSENSE
132
};
133
134
private static final DocFlavor[] supportedHostDocFlavors = {
135
DocFlavor.BYTE_ARRAY.TEXT_PLAIN_HOST,
136
DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST,
137
DocFlavor.URL.TEXT_PLAIN_HOST
138
};
139
140
String[] lpcStatusCom = {
141
"",
142
"| grep -E '^[ 0-9a-zA-Z_-]*@' | awk '{print $2, $3}'"
143
};
144
145
String[] lpcQueueCom = {
146
"",
147
"| grep -E '^[ 0-9a-zA-Z_-]*@' | awk '{print $4}'"
148
};
149
150
static {
151
encoding = java.security.AccessController.doPrivileged(
152
new sun.security.action.GetPropertyAction("file.encoding"));
153
}
154
155
/* let's try to support a few of these */
156
private static final Class<?>[] serviceAttrCats = {
157
PrinterName.class,
158
PrinterIsAcceptingJobs.class,
159
QueuedJobCount.class,
160
};
161
162
/* it turns out to be inconvenient to store the other categories
163
* separately because many attributes are in multiple categories.
164
*/
165
private static final Class<?>[] otherAttrCats = {
166
Chromaticity.class,
167
Copies.class,
168
Destination.class,
169
Fidelity.class,
170
JobName.class,
171
JobSheets.class,
172
Media.class, /* have to support this somehow ... */
173
MediaPrintableArea.class,
174
OrientationRequested.class,
175
PageRanges.class,
176
RequestingUserName.class,
177
SheetCollate.class,
178
Sides.class,
179
};
180
181
private static int MAXCOPIES = 1000;
182
183
private static final MediaSizeName[] mediaSizes = {
184
MediaSizeName.NA_LETTER,
185
MediaSizeName.TABLOID,
186
MediaSizeName.LEDGER,
187
MediaSizeName.NA_LEGAL,
188
MediaSizeName.EXECUTIVE,
189
MediaSizeName.ISO_A3,
190
MediaSizeName.ISO_A4,
191
MediaSizeName.ISO_A5,
192
MediaSizeName.ISO_B4,
193
MediaSizeName.ISO_B5,
194
};
195
196
private String printer;
197
private PrinterName name;
198
private boolean isInvalid;
199
200
private transient PrintServiceAttributeSet lastSet;
201
private transient ServiceNotifier notifier = null;
202
203
UnixPrintService(String name) {
204
if (name == null) {
205
throw new IllegalArgumentException("null printer name");
206
}
207
printer = name;
208
isInvalid = false;
209
}
210
211
public void invalidateService() {
212
isInvalid = true;
213
}
214
215
public String getName() {
216
return printer;
217
}
218
219
private PrinterName getPrinterName() {
220
if (name == null) {
221
name = new PrinterName(printer, null);
222
}
223
return name;
224
}
225
226
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsBSD() {
227
if (PrintServiceLookupProvider.cmdIndex ==
228
PrintServiceLookupProvider.UNINITIALIZED) {
229
230
PrintServiceLookupProvider.cmdIndex =
231
PrintServiceLookupProvider.getBSDCommandIndex();
232
}
233
234
String command = "/usr/sbin/lpc status " + printer
235
+ lpcStatusCom[PrintServiceLookupProvider.cmdIndex];
236
String[] results= PrintServiceLookupProvider.execCmd(command);
237
238
if (results != null && results.length > 0) {
239
if (PrintServiceLookupProvider.cmdIndex ==
240
PrintServiceLookupProvider.BSD_LPD_NG) {
241
if (results[0].startsWith("enabled enabled")) {
242
return PrinterIsAcceptingJobs.ACCEPTING_JOBS ;
243
}
244
} else {
245
if ((results[1].trim().startsWith("queuing is enabled") &&
246
results[2].trim().startsWith("printing is enabled")) ||
247
(results.length >= 4 &&
248
results[2].trim().startsWith("queuing is enabled") &&
249
results[3].trim().startsWith("printing is enabled"))) {
250
return PrinterIsAcceptingJobs.ACCEPTING_JOBS ;
251
}
252
}
253
}
254
return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS ;
255
}
256
257
// Filter the list of possible AIX Printers and remove header lines
258
// and extra lines which have been added for remote printers.
259
// 'protected' because this method is also used from PrintServiceLookupProvider.
260
protected static String[] filterPrinterNamesAIX(String[] posPrinters) {
261
ArrayList<String> printers = new ArrayList<>();
262
String [] splitPart;
263
264
for(int i = 0; i < posPrinters.length; i++) {
265
// Remove the header lines
266
if (posPrinters[i].startsWith("---") ||
267
posPrinters[i].startsWith("Queue") ||
268
posPrinters[i].isEmpty()) continue;
269
270
// Check if there is a ":" in the end of the first colomn.
271
// This means that it is not a valid printer definition.
272
splitPart = posPrinters[i].split(" ");
273
if(splitPart.length >= 1 && !splitPart[0].trim().endsWith(":")) {
274
printers.add(posPrinters[i]);
275
}
276
}
277
278
return printers.toArray(new String[printers.size()]);
279
}
280
281
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsAIX() {
282
// On AIX there should not be a blank after '-a'.
283
String command = "/usr/bin/lpstat -a" + printer;
284
String[] results= PrintServiceLookupProvider.execCmd(command);
285
286
// Remove headers and bogus entries added by remote printers.
287
results = filterPrinterNamesAIX(results);
288
289
if (results != null && results.length > 0) {
290
for (int i = 0; i < results.length; i++) {
291
if (results[i].contains("READY") ||
292
results[i].contains("RUNNING")) {
293
return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
294
}
295
}
296
}
297
298
return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
299
300
}
301
302
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
303
if (PrintServiceLookupProvider.isBSD()) {
304
return getPrinterIsAcceptingJobsBSD();
305
} else if (PrintServiceLookupProvider.isAIX()) {
306
return getPrinterIsAcceptingJobsAIX();
307
} else {
308
return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
309
}
310
}
311
312
private PrinterState getPrinterState() {
313
if (isInvalid) {
314
return PrinterState.STOPPED;
315
} else {
316
return null;
317
}
318
}
319
320
private PrinterStateReasons getPrinterStateReasons() {
321
if (isInvalid) {
322
PrinterStateReasons psr = new PrinterStateReasons();
323
psr.put(PrinterStateReason.SHUTDOWN, Severity.ERROR);
324
return psr;
325
} else {
326
return null;
327
}
328
}
329
330
private QueuedJobCount getQueuedJobCountBSD() {
331
if (PrintServiceLookupProvider.cmdIndex ==
332
PrintServiceLookupProvider.UNINITIALIZED) {
333
334
PrintServiceLookupProvider.cmdIndex =
335
PrintServiceLookupProvider.getBSDCommandIndex();
336
}
337
338
int qlen = 0;
339
String command = "/usr/sbin/lpc status " + printer
340
+ lpcQueueCom[PrintServiceLookupProvider.cmdIndex];
341
String[] results = PrintServiceLookupProvider.execCmd(command);
342
343
if (results != null && results.length > 0) {
344
String queued;
345
if (PrintServiceLookupProvider.cmdIndex ==
346
PrintServiceLookupProvider.BSD_LPD_NG) {
347
queued = results[0];
348
} else {
349
queued = results[3].trim();
350
if (queued.startsWith("no")) {
351
return new QueuedJobCount(0);
352
} else {
353
queued = queued.substring(0, queued.indexOf(' '));
354
}
355
}
356
357
try {
358
qlen = Integer.parseInt(queued);
359
} catch (NumberFormatException e) {
360
}
361
}
362
363
return new QueuedJobCount(qlen);
364
}
365
366
private QueuedJobCount getQueuedJobCountAIX() {
367
// On AIX there should not be a blank after '-a'.
368
String command = "/usr/bin/lpstat -a" + printer;
369
String[] results= PrintServiceLookupProvider.execCmd(command);
370
371
// Remove headers and bogus entries added by remote printers.
372
results = filterPrinterNamesAIX(results);
373
374
int qlen = 0;
375
if (results != null && results.length > 0){
376
for (int i = 0; i < results.length; i++) {
377
if (results[i].contains("QUEUED")){
378
qlen ++;
379
}
380
}
381
}
382
return new QueuedJobCount(qlen);
383
}
384
385
private QueuedJobCount getQueuedJobCount() {
386
if (PrintServiceLookupProvider.isBSD()) {
387
return getQueuedJobCountBSD();
388
} else if (PrintServiceLookupProvider.isAIX()) {
389
return getQueuedJobCountAIX();
390
} else {
391
return new QueuedJobCount(0);
392
}
393
}
394
395
private PrintServiceAttributeSet getBSDServiceAttributes() {
396
PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
397
attrs.add(getQueuedJobCountBSD());
398
attrs.add(getPrinterIsAcceptingJobsBSD());
399
return attrs;
400
}
401
402
private PrintServiceAttributeSet getAIXServiceAttributes() {
403
PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
404
attrs.add(getQueuedJobCountAIX());
405
attrs.add(getPrinterIsAcceptingJobsAIX());
406
return attrs;
407
}
408
409
private boolean isSupportedCopies(Copies copies) {
410
int numCopies = copies.getValue();
411
return (numCopies > 0 && numCopies < MAXCOPIES);
412
}
413
414
private boolean isSupportedMedia(MediaSizeName msn) {
415
for (int i=0; i<mediaSizes.length; i++) {
416
if (msn.equals(mediaSizes[i])) {
417
return true;
418
}
419
}
420
return false;
421
}
422
423
public DocPrintJob createPrintJob() {
424
SecurityManager security = System.getSecurityManager();
425
if (security != null) {
426
security.checkPrintJobAccess();
427
}
428
return new UnixPrintJob(this);
429
}
430
431
private PrintServiceAttributeSet getDynamicAttributes() {
432
if (PrintServiceLookupProvider.isAIX()) {
433
return getAIXServiceAttributes();
434
} else {
435
return getBSDServiceAttributes();
436
}
437
}
438
439
public PrintServiceAttributeSet getUpdatedAttributes() {
440
PrintServiceAttributeSet currSet = getDynamicAttributes();
441
if (lastSet == null) {
442
lastSet = currSet;
443
return AttributeSetUtilities.unmodifiableView(currSet);
444
} else {
445
PrintServiceAttributeSet updates =
446
new HashPrintServiceAttributeSet();
447
Attribute []attrs = currSet.toArray();
448
Attribute attr;
449
for (int i=0; i<attrs.length; i++) {
450
attr = attrs[i];
451
if (!lastSet.containsValue(attr)) {
452
updates.add(attr);
453
}
454
}
455
lastSet = currSet;
456
return AttributeSetUtilities.unmodifiableView(updates);
457
}
458
}
459
460
public void wakeNotifier() {
461
synchronized (this) {
462
if (notifier != null) {
463
notifier.wake();
464
}
465
}
466
}
467
468
public void addPrintServiceAttributeListener(
469
PrintServiceAttributeListener listener) {
470
synchronized (this) {
471
if (listener == null) {
472
return;
473
}
474
if (notifier == null) {
475
notifier = new ServiceNotifier(this);
476
}
477
notifier.addListener(listener);
478
}
479
}
480
481
public void removePrintServiceAttributeListener(
482
PrintServiceAttributeListener listener) {
483
synchronized (this) {
484
if (listener == null || notifier == null ) {
485
return;
486
}
487
notifier.removeListener(listener);
488
if (notifier.isEmpty()) {
489
notifier.stopNotifier();
490
notifier = null;
491
}
492
}
493
}
494
495
@SuppressWarnings("unchecked")
496
public <T extends PrintServiceAttribute>
497
T getAttribute(Class<T> category)
498
{
499
if (category == null) {
500
throw new NullPointerException("category");
501
}
502
if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {
503
throw new IllegalArgumentException("Not a PrintServiceAttribute");
504
}
505
506
if (category == PrinterName.class) {
507
return (T)getPrinterName();
508
} else if (category == PrinterState.class) {
509
return (T)getPrinterState();
510
} else if (category == PrinterStateReasons.class) {
511
return (T)getPrinterStateReasons();
512
} else if (category == QueuedJobCount.class) {
513
return (T)getQueuedJobCount();
514
} else if (category == PrinterIsAcceptingJobs.class) {
515
return (T)getPrinterIsAcceptingJobs();
516
} else {
517
return null;
518
}
519
}
520
521
public PrintServiceAttributeSet getAttributes() {
522
PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
523
attrs.add(getPrinterName());
524
attrs.add(getPrinterIsAcceptingJobs());
525
PrinterState prnState = getPrinterState();
526
if (prnState != null) {
527
attrs.add(prnState);
528
}
529
PrinterStateReasons prnStateReasons = getPrinterStateReasons();
530
if (prnStateReasons != null) {
531
attrs.add(prnStateReasons);
532
}
533
attrs.add(getQueuedJobCount());
534
return AttributeSetUtilities.unmodifiableView(attrs);
535
}
536
537
private void initSupportedDocFlavors() {
538
String hostEnc = DocFlavor.hostEncoding.toLowerCase(Locale.ENGLISH);
539
if (!hostEnc.equals("utf-8") && !hostEnc.equals("utf-16") &&
540
!hostEnc.equals("utf-16be") && !hostEnc.equals("utf-16le") &&
541
!hostEnc.equals("us-ascii")) {
542
543
int len = supportedDocFlavorsInit.length;
544
DocFlavor[] flavors =
545
new DocFlavor[len + supportedHostDocFlavors.length];
546
// copy host encoding flavors
547
System.arraycopy(supportedHostDocFlavors, 0, flavors,
548
len, supportedHostDocFlavors.length);
549
System.arraycopy(supportedDocFlavorsInit, 0, flavors, 0, len);
550
551
supportedDocFlavors = flavors;
552
} else {
553
supportedDocFlavors = supportedDocFlavorsInit;
554
}
555
}
556
557
public DocFlavor[] getSupportedDocFlavors() {
558
if (supportedDocFlavors == null) {
559
initSupportedDocFlavors();
560
}
561
int len = supportedDocFlavors.length;
562
DocFlavor[] flavors = new DocFlavor[len];
563
System.arraycopy(supportedDocFlavors, 0, flavors, 0, len);
564
565
return flavors;
566
}
567
568
public boolean isDocFlavorSupported(DocFlavor flavor) {
569
if (supportedDocFlavors == null) {
570
initSupportedDocFlavors();
571
}
572
for (int f=0; f<supportedDocFlavors.length; f++) {
573
if (flavor.equals(supportedDocFlavors[f])) {
574
return true;
575
}
576
}
577
return false;
578
}
579
580
public Class<?>[] getSupportedAttributeCategories() {
581
ArrayList<Class<?>> categList = new ArrayList<>(otherAttrCats.length);
582
for (Class<?> c : otherAttrCats) {
583
categList.add(c);
584
}
585
if (GraphicsEnvironment.isHeadless() == false) {
586
categList.add(DialogOwner.class);
587
categList.add(DialogTypeSelection.class);
588
}
589
return categList.toArray(new Class<?>[categList.size()]);
590
}
591
592
public boolean
593
isAttributeCategorySupported(Class<? extends Attribute> category)
594
{
595
if (category == null) {
596
throw new NullPointerException("null category");
597
}
598
if (!(Attribute.class.isAssignableFrom(category))) {
599
throw new IllegalArgumentException(category +
600
" is not an Attribute");
601
}
602
603
for (int i=0;i<otherAttrCats.length;i++) {
604
if (category == otherAttrCats[i]) {
605
return true;
606
}
607
}
608
return false;
609
}
610
611
/* return defaults for all attributes for which there is a default
612
* value
613
*/
614
public Object
615
getDefaultAttributeValue(Class<? extends Attribute> category)
616
{
617
if (category == null) {
618
throw new NullPointerException("null category");
619
}
620
if (!Attribute.class.isAssignableFrom(category)) {
621
throw new IllegalArgumentException(category +
622
" is not an Attribute");
623
}
624
625
if (!isAttributeCategorySupported(category)) {
626
return null;
627
}
628
629
if (category == Copies.class) {
630
return new Copies(1);
631
} else if (category == Chromaticity.class) {
632
return Chromaticity.COLOR;
633
} else if (category == Destination.class) {
634
try {
635
return new Destination((new File("out.ps")).toURI());
636
} catch (SecurityException se) {
637
try {
638
return new Destination(new URI("file:out.ps"));
639
} catch (URISyntaxException e) {
640
return null;
641
}
642
}
643
} else if (category == Fidelity.class) {
644
return Fidelity.FIDELITY_FALSE;
645
} else if (category == JobName.class) {
646
return new JobName("Java Printing", null);
647
} else if (category == JobSheets.class) {
648
return JobSheets.STANDARD;
649
} else if (category == Media.class) {
650
String defaultCountry = Locale.getDefault().getCountry();
651
if (defaultCountry != null &&
652
(defaultCountry.isEmpty() ||
653
defaultCountry.equals(Locale.US.getCountry()) ||
654
defaultCountry.equals(Locale.CANADA.getCountry()))) {
655
return MediaSizeName.NA_LETTER;
656
} else {
657
return MediaSizeName.ISO_A4;
658
}
659
} else if (category == MediaPrintableArea.class) {
660
String defaultCountry = Locale.getDefault().getCountry();
661
float iw, ih;
662
if (defaultCountry != null &&
663
(defaultCountry.isEmpty() ||
664
defaultCountry.equals(Locale.US.getCountry()) ||
665
defaultCountry.equals(Locale.CANADA.getCountry()))) {
666
iw = MediaSize.NA.LETTER.getX(Size2DSyntax.INCH) - 0.5f;
667
ih = MediaSize.NA.LETTER.getY(Size2DSyntax.INCH) - 0.5f;
668
} else {
669
iw = MediaSize.ISO.A4.getX(Size2DSyntax.INCH) - 0.5f;
670
ih = MediaSize.ISO.A4.getY(Size2DSyntax.INCH) - 0.5f;
671
}
672
return new MediaPrintableArea(0.25f, 0.25f, iw, ih,
673
MediaPrintableArea.INCH);
674
} else if (category == OrientationRequested.class) {
675
return OrientationRequested.PORTRAIT;
676
} else if (category == PageRanges.class) {
677
return new PageRanges(1, Integer.MAX_VALUE);
678
} else if (category == RequestingUserName.class) {
679
String userName = "";
680
try {
681
userName = System.getProperty("user.name", "");
682
} catch (SecurityException se) {
683
}
684
return new RequestingUserName(userName, null);
685
} else if (category == SheetCollate.class) {
686
return SheetCollate.UNCOLLATED;
687
} else if (category == Sides.class) {
688
return Sides.ONE_SIDED;
689
} else
690
return null;
691
}
692
693
694
private boolean isAutoSense(DocFlavor flavor) {
695
if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE) ||
696
flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE) ||
697
flavor.equals(DocFlavor.URL.AUTOSENSE)) {
698
return true;
699
}
700
else {
701
return false;
702
}
703
}
704
705
public Object
706
getSupportedAttributeValues(Class<? extends Attribute> category,
707
DocFlavor flavor,
708
AttributeSet attributes)
709
{
710
711
if (category == null) {
712
throw new NullPointerException("null category");
713
}
714
if (!Attribute.class.isAssignableFrom(category)) {
715
throw new IllegalArgumentException(category +
716
" does not implement Attribute");
717
}
718
if (flavor != null) {
719
if (!isDocFlavorSupported(flavor)) {
720
throw new IllegalArgumentException(flavor +
721
" is an unsupported flavor");
722
} else if (isAutoSense(flavor)) {
723
return null;
724
}
725
}
726
727
if (!isAttributeCategorySupported(category)) {
728
return null;
729
}
730
731
if (category == Chromaticity.class) {
732
if (flavor == null || isServiceFormattedFlavor(flavor)) {
733
Chromaticity[]arr = new Chromaticity[1];
734
arr[0] = Chromaticity.COLOR;
735
return (arr);
736
} else {
737
return null;
738
}
739
} else if (category == Destination.class) {
740
try {
741
return new Destination((new File("out.ps")).toURI());
742
} catch (SecurityException se) {
743
try {
744
return new Destination(new URI("file:out.ps"));
745
} catch (URISyntaxException e) {
746
return null;
747
}
748
}
749
} else if (category == JobName.class) {
750
return new JobName("Java Printing", null);
751
} else if (category == JobSheets.class) {
752
JobSheets[] arr = new JobSheets[2];
753
arr[0] = JobSheets.NONE;
754
arr[1] = JobSheets.STANDARD;
755
return arr;
756
} else if (category == RequestingUserName.class) {
757
String userName = "";
758
try {
759
userName = System.getProperty("user.name", "");
760
} catch (SecurityException se) {
761
}
762
return new RequestingUserName(userName, null);
763
} else if (category == OrientationRequested.class) {
764
if (flavor == null || isServiceFormattedFlavor(flavor)) {
765
OrientationRequested []arr = new OrientationRequested[3];
766
arr[0] = OrientationRequested.PORTRAIT;
767
arr[1] = OrientationRequested.LANDSCAPE;
768
arr[2] = OrientationRequested.REVERSE_LANDSCAPE;
769
return arr;
770
} else {
771
return null;
772
}
773
} else if ((category == Copies.class) ||
774
(category == CopiesSupported.class)) {
775
if (flavor == null ||
776
!(flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) ||
777
flavor.equals(DocFlavor.URL.POSTSCRIPT) ||
778
flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT))) {
779
return new CopiesSupported(1, MAXCOPIES);
780
} else {
781
return null;
782
}
783
} else if (category == Media.class) {
784
Media []arr = new Media[mediaSizes.length];
785
System.arraycopy(mediaSizes, 0, arr, 0, mediaSizes.length);
786
return arr;
787
} else if (category == Fidelity.class) {
788
Fidelity []arr = new Fidelity[2];
789
arr[0] = Fidelity.FIDELITY_FALSE;
790
arr[1] = Fidelity.FIDELITY_TRUE;
791
return arr;
792
} else if (category == MediaPrintableArea.class) {
793
/* The code below implements the behaviour that if no Media or
794
* MediaSize attribute is specified, return an array of
795
* MediaPrintableArea, one for each supported Media.
796
* If a MediaSize is specified, return a MPA consistent for that,
797
* and if a Media is specified locate its MediaSize and return
798
* its MPA, and if none is found, return an MPA for the default
799
* Media for this service.
800
*/
801
if (attributes == null) {
802
return getAllPrintableAreas();
803
}
804
MediaSize mediaSize = (MediaSize)attributes.get(MediaSize.class);
805
Media media = (Media)attributes.get(Media.class);
806
MediaPrintableArea []arr = new MediaPrintableArea[1];
807
if (mediaSize == null) {
808
if (media instanceof MediaSizeName) {
809
MediaSizeName msn = (MediaSizeName)media;
810
mediaSize = MediaSize.getMediaSizeForName(msn);
811
if (mediaSize == null) {
812
/* try to get a size from the default media */
813
media = (Media)getDefaultAttributeValue(Media.class);
814
if (media instanceof MediaSizeName) {
815
msn = (MediaSizeName)media;
816
mediaSize = MediaSize.getMediaSizeForName(msn);
817
}
818
if (mediaSize == null) {
819
/* shouldn't happen, return a default */
820
arr[0] = new MediaPrintableArea(0.25f, 0.25f,
821
8f, 10.5f,
822
MediaSize.INCH);
823
return arr;
824
}
825
}
826
} else {
827
return getAllPrintableAreas();
828
}
829
}
830
/* If reach here MediaSize is non-null */
831
assert mediaSize != null;
832
arr[0] = new MediaPrintableArea(0.25f, 0.25f,
833
mediaSize.getX(MediaSize.INCH)-0.5f,
834
mediaSize.getY(MediaSize.INCH)-0.5f,
835
MediaSize.INCH);
836
return arr;
837
} else if (category == PageRanges.class) {
838
if (flavor == null ||
839
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
840
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
841
PageRanges []arr = new PageRanges[1];
842
arr[0] = new PageRanges(1, Integer.MAX_VALUE);
843
return arr;
844
} else {
845
return null;
846
}
847
} else if (category == SheetCollate.class) {
848
if (flavor == null ||
849
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
850
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
851
SheetCollate []arr = new SheetCollate[2];
852
arr[0] = SheetCollate.UNCOLLATED;
853
arr[1] = SheetCollate.COLLATED;
854
return arr;
855
} else {
856
return null;
857
}
858
} else if (category == Sides.class) {
859
if (flavor == null ||
860
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
861
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
862
Sides []arr = new Sides[3];
863
arr[0] = Sides.ONE_SIDED;
864
arr[1] = Sides.TWO_SIDED_LONG_EDGE;
865
arr[2] = Sides.TWO_SIDED_SHORT_EDGE;
866
return arr;
867
} else {
868
return null;
869
}
870
} else {
871
return null;
872
}
873
}
874
875
private static MediaPrintableArea[] mpas = null;
876
private MediaPrintableArea[] getAllPrintableAreas() {
877
878
if (mpas == null) {
879
Media[] media = (Media[])getSupportedAttributeValues(Media.class,
880
null, null);
881
mpas = new MediaPrintableArea[media.length];
882
for (int i=0; i< mpas.length; i++) {
883
if (media[i] instanceof MediaSizeName) {
884
MediaSizeName msn = (MediaSizeName)media[i];
885
MediaSize mediaSize = MediaSize.getMediaSizeForName(msn);
886
if (mediaSize == null) {
887
mpas[i] = (MediaPrintableArea)
888
getDefaultAttributeValue(MediaPrintableArea.class);
889
} else {
890
mpas[i] = new MediaPrintableArea(0.25f, 0.25f,
891
mediaSize.getX(MediaSize.INCH)-0.5f,
892
mediaSize.getY(MediaSize.INCH)-0.5f,
893
MediaSize.INCH);
894
}
895
}
896
}
897
}
898
MediaPrintableArea[] mpasCopy = new MediaPrintableArea[mpas.length];
899
System.arraycopy(mpas, 0, mpasCopy, 0, mpas.length);
900
return mpasCopy;
901
}
902
903
/* Is this one of the flavors that this service explicitly
904
* generates postscript for, and so can control how it is rendered?
905
*/
906
private boolean isServiceFormattedFlavor(DocFlavor flavor) {
907
return
908
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
909
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
910
flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
911
flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
912
flavor.equals(DocFlavor.URL.GIF) ||
913
flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
914
flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
915
flavor.equals(DocFlavor.URL.JPEG) ||
916
flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
917
flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
918
flavor.equals(DocFlavor.URL.PNG);
919
}
920
921
public boolean isAttributeValueSupported(Attribute attr,
922
DocFlavor flavor,
923
AttributeSet attributes) {
924
if (attr == null) {
925
throw new NullPointerException("null attribute");
926
}
927
if (flavor != null) {
928
if (!isDocFlavorSupported(flavor)) {
929
throw new IllegalArgumentException(flavor +
930
" is an unsupported flavor");
931
} else if (isAutoSense(flavor)) {
932
return false;
933
}
934
}
935
Class<? extends Attribute> category = attr.getCategory();
936
if (!isAttributeCategorySupported(category)) {
937
return false;
938
}
939
else if (attr.getCategory() == Chromaticity.class) {
940
if (flavor == null || isServiceFormattedFlavor(flavor)) {
941
return attr == Chromaticity.COLOR;
942
} else {
943
return false;
944
}
945
}
946
else if (attr.getCategory() == Copies.class) {
947
return (flavor == null ||
948
!(flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) ||
949
flavor.equals(DocFlavor.URL.POSTSCRIPT) ||
950
flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT))) &&
951
isSupportedCopies((Copies)attr);
952
} else if (attr.getCategory() == Destination.class) {
953
URI uri = ((Destination)attr).getURI();
954
if ("file".equals(uri.getScheme()) &&
955
!uri.getSchemeSpecificPart().isEmpty()) {
956
return true;
957
} else {
958
return false;
959
}
960
} else if (attr.getCategory() == Media.class) {
961
if (attr instanceof MediaSizeName) {
962
return isSupportedMedia((MediaSizeName)attr);
963
} else {
964
return false;
965
}
966
} else if (attr.getCategory() == OrientationRequested.class) {
967
if (attr == OrientationRequested.REVERSE_PORTRAIT ||
968
(flavor != null) &&
969
!isServiceFormattedFlavor(flavor)) {
970
return false;
971
}
972
} else if (attr.getCategory() == PageRanges.class) {
973
if (flavor != null &&
974
!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
975
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
976
return false;
977
}
978
} else if (attr.getCategory() == SheetCollate.class) {
979
if (flavor != null &&
980
!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
981
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
982
return false;
983
}
984
} else if (attr.getCategory() == Sides.class) {
985
if (flavor != null &&
986
!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
987
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
988
return false;
989
}
990
} else if (attr.getCategory() == DialogOwner.class) {
991
DialogOwner owner = (DialogOwner)attr;
992
// ID not supported on any dialog type on Unix platforms.
993
if (DialogOwnerAccessor.getID(owner) != 0) {
994
return false;
995
}
996
// UnixPrintService is not used on Mac, so this is
997
// always some Unix system that does not have CUPS/IPP
998
// Which means we always use a Swing dialog and we need
999
// only check if alwaysOnTop is supported by the toolkit.
1000
if (owner.getOwner() != null) {
1001
return true;
1002
} else {
1003
return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
1004
}
1005
} else if (attr.getCategory() == DialogTypeSelection.class) {
1006
DialogTypeSelection dts = (DialogTypeSelection)attr;
1007
return dts == DialogTypeSelection.COMMON;
1008
}
1009
return true;
1010
}
1011
1012
public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
1013
AttributeSet attributes) {
1014
1015
if (flavor != null && !isDocFlavorSupported(flavor)) {
1016
throw new IllegalArgumentException("flavor " + flavor +
1017
"is not supported");
1018
}
1019
1020
if (attributes == null) {
1021
return null;
1022
}
1023
1024
Attribute attr;
1025
AttributeSet unsupp = new HashAttributeSet();
1026
Attribute []attrs = attributes.toArray();
1027
for (int i=0; i<attrs.length; i++) {
1028
try {
1029
attr = attrs[i];
1030
if (!isAttributeCategorySupported(attr.getCategory())) {
1031
unsupp.add(attr);
1032
} else if (!isAttributeValueSupported(attr, flavor,
1033
attributes)) {
1034
unsupp.add(attr);
1035
}
1036
} catch (ClassCastException e) {
1037
}
1038
}
1039
if (unsupp.isEmpty()) {
1040
return null;
1041
} else {
1042
return unsupp;
1043
}
1044
}
1045
1046
public ServiceUIFactory getServiceUIFactory() {
1047
return null;
1048
}
1049
1050
public String toString() {
1051
return "Unix Printer : " + getName();
1052
}
1053
1054
public boolean equals(Object obj) {
1055
return (obj == this ||
1056
(obj instanceof UnixPrintService &&
1057
((UnixPrintService)obj).getName().equals(getName())));
1058
}
1059
1060
public int hashCode() {
1061
return this.getClass().hashCode()+getName().hashCode();
1062
}
1063
1064
public boolean usesClass(Class<?> c) {
1065
return (c == sun.print.PSPrinterJob.class);
1066
}
1067
1068
}
1069
1070