Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/print/PrintServiceLookupProvider.java
32287 views
1
/*
2
* Copyright (c) 2000, 2013, 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.BufferedReader;
29
import java.io.FileInputStream;
30
import java.io.InputStream;
31
import java.io.InputStreamReader;
32
import java.io.IOException;
33
import java.util.ArrayList;
34
import java.util.Vector;
35
import java.security.AccessController;
36
import java.security.PrivilegedActionException;
37
import java.security.PrivilegedExceptionAction;
38
import javax.print.DocFlavor;
39
import javax.print.MultiDocPrintService;
40
import javax.print.PrintService;
41
import javax.print.PrintServiceLookup;
42
import javax.print.attribute.Attribute;
43
import javax.print.attribute.AttributeSet;
44
import javax.print.attribute.HashPrintRequestAttributeSet;
45
import javax.print.attribute.HashPrintServiceAttributeSet;
46
import javax.print.attribute.PrintRequestAttribute;
47
import javax.print.attribute.PrintRequestAttributeSet;
48
import javax.print.attribute.PrintServiceAttribute;
49
import javax.print.attribute.PrintServiceAttributeSet;
50
import javax.print.attribute.standard.PrinterName;
51
import javax.print.attribute.standard.PrinterURI;
52
import java.io.File;
53
import java.io.FileReader;
54
import java.net.URL;
55
import java.nio.file.Files;
56
57
/*
58
* Remind: This class uses solaris commands. We also need a linux
59
* version
60
*/
61
public class PrintServiceLookupProvider extends PrintServiceLookup
62
implements BackgroundServiceLookup, Runnable {
63
64
/* Remind: the current implementation is static, as its assumed
65
* its preferable to minimize creation of PrintService instances.
66
* Later we should add logic to add/remove services on the fly which
67
* will take a hit of needing to regather the list of services.
68
*/
69
private String defaultPrinter;
70
private PrintService defaultPrintService;
71
private PrintService[] printServices; /* includes the default printer */
72
private Vector lookupListeners = null;
73
private static String debugPrefix = "PrintServiceLookupProvider>> ";
74
private static boolean pollServices = true;
75
private static final int DEFAULT_MINREFRESH = 120; // 2 minutes
76
private static int minRefreshTime = DEFAULT_MINREFRESH;
77
78
79
static String osname;
80
81
// List of commands used to deal with the printer queues on AIX
82
String[] lpNameComAix = {
83
"/usr/bin/lsallq",
84
"/usr/bin/lpstat -W -p|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
85
"/usr/bin/lpstat -W -d|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
86
"/usr/bin/lpstat -W -v"
87
};
88
private static final int aix_lsallq = 0;
89
private static final int aix_lpstat_p = 1;
90
private static final int aix_lpstat_d = 2;
91
private static final int aix_lpstat_v = 3;
92
private static int aix_defaultPrinterEnumeration = aix_lsallq;
93
94
static {
95
/* The system property "sun.java2d.print.polling"
96
* can be used to force the printing code to poll or not poll
97
* for PrintServices.
98
*/
99
String pollStr = java.security.AccessController.doPrivileged(
100
new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));
101
102
if (pollStr != null) {
103
if (pollStr.equalsIgnoreCase("true")) {
104
pollServices = true;
105
} else if (pollStr.equalsIgnoreCase("false")) {
106
pollServices = false;
107
}
108
}
109
110
/* The system property "sun.java2d.print.minRefreshTime"
111
* can be used to specify minimum refresh time (in seconds)
112
* for polling PrintServices. The default is 120.
113
*/
114
String refreshTimeStr = java.security.AccessController.doPrivileged(
115
new sun.security.action.GetPropertyAction(
116
"sun.java2d.print.minRefreshTime"));
117
118
if (refreshTimeStr != null) {
119
try {
120
minRefreshTime = (new Integer(refreshTimeStr)).intValue();
121
} catch (NumberFormatException e) {
122
}
123
if (minRefreshTime < DEFAULT_MINREFRESH) {
124
minRefreshTime = DEFAULT_MINREFRESH;
125
}
126
}
127
128
osname = java.security.AccessController.doPrivileged(
129
new sun.security.action.GetPropertyAction("os.name"));
130
131
/* The system property "sun.java2d.print.aix.lpstat"
132
* can be used to force the usage of 'lpstat -p' to enumerate all
133
* printer queues. By default we use 'lsallq', because 'lpstat -p' can
134
* take lots of time if thousands of printers are attached to a server.
135
*/
136
if (isAIX()) {
137
String aixPrinterEnumerator = java.security.AccessController.doPrivileged(
138
new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat"));
139
140
if (aixPrinterEnumerator != null) {
141
if (aixPrinterEnumerator.equalsIgnoreCase("lpstat")) {
142
aix_defaultPrinterEnumeration = aix_lpstat_p;
143
} else if (aixPrinterEnumerator.equalsIgnoreCase("lsallq")) {
144
aix_defaultPrinterEnumeration = aix_lsallq;
145
}
146
}
147
}
148
}
149
150
static boolean isMac() {
151
return osname.startsWith("Mac");
152
}
153
154
static boolean isSysV() {
155
return osname.equals("SunOS");
156
}
157
158
static boolean isLinux() {
159
return (osname.equals("Linux"));
160
}
161
162
static boolean isBSD() {
163
return (osname.equals("Linux") ||
164
osname.contains("OS X"));
165
}
166
167
static boolean isAIX() {
168
return osname.equals("AIX");
169
}
170
171
static final int UNINITIALIZED = -1;
172
static final int BSD_LPD = 0;
173
static final int BSD_LPD_NG = 1;
174
175
static int cmdIndex = UNINITIALIZED;
176
177
String[] lpcFirstCom = {
178
"/usr/sbin/lpc status | grep : | sed -ne '1,1 s/://p'",
179
"/usr/sbin/lpc status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
180
};
181
182
String[] lpcAllCom = {
183
"/usr/sbin/lpc status all | grep : | sed -e 's/://'",
184
"/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort"
185
};
186
187
String[] lpcNameCom = {
188
"| grep : | sed -ne 's/://p'",
189
"| grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
190
};
191
192
193
static int getBSDCommandIndex() {
194
String command = "/usr/sbin/lpc status all";
195
String[] names = execCmd(command);
196
197
if ((names == null) || (names.length == 0)) {
198
return BSD_LPD_NG;
199
}
200
201
for (int i=0; i<names.length; i++) {
202
if (names[i].indexOf('@') != -1) {
203
return BSD_LPD_NG;
204
}
205
}
206
207
return BSD_LPD;
208
}
209
210
211
public PrintServiceLookupProvider() {
212
// start the printer listener thread
213
if (pollServices) {
214
PrinterChangeListener thr = new PrinterChangeListener();
215
thr.setDaemon(true);
216
thr.start();
217
IPPPrintService.debug_println(debugPrefix+"polling turned on");
218
}
219
}
220
221
/* Want the PrintService which is default print service to have
222
* equality of reference with the equivalent in list of print services
223
* This isn't required by the API and there's a risk doing this will
224
* lead people to assume its guaranteed.
225
*/
226
public synchronized PrintService[] getPrintServices() {
227
SecurityManager security = System.getSecurityManager();
228
if (security != null) {
229
security.checkPrintJobAccess();
230
}
231
232
if (printServices == null || !pollServices) {
233
refreshServices();
234
}
235
if (printServices == null) {
236
return new PrintService[0];
237
} else {
238
return (PrintService[])printServices.clone();
239
}
240
}
241
242
private int addPrintServiceToList(ArrayList printerList, PrintService ps) {
243
int index = printerList.indexOf(ps);
244
// Check if PrintService with same name is already in the list.
245
if (CUPSPrinter.isCupsRunning() && index != -1) {
246
// Bug in Linux: Duplicate entry of a remote printer
247
// and treats it as local printer but it is returning wrong
248
// information when queried using IPP. Workaround is to remove it.
249
// Even CUPS ignores these entries as shown in lpstat or using
250
// their web configuration.
251
PrinterURI uri = (PrinterURI)ps.getAttribute(PrinterURI.class);
252
if (uri.getURI().getHost().equals("localhost")) {
253
IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, ignoring the new local printer: "+ps);
254
return index; // Do not add this.
255
}
256
PrintService oldPS = (PrintService)(printerList.get(index));
257
uri = (PrinterURI)oldPS.getAttribute(PrinterURI.class);
258
if (uri.getURI().getHost().equals("localhost")) {
259
IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, removing existing local printer: "+oldPS);
260
printerList.remove(oldPS);
261
} else {
262
return index;
263
}
264
}
265
printerList.add(ps);
266
return (printerList.size() - 1);
267
}
268
269
270
// refreshes "printServices"
271
public synchronized void refreshServices() {
272
/* excludes the default printer */
273
String[] printers = null; // array of printer names
274
String[] printerURIs = null; //array of printer URIs
275
276
try {
277
getDefaultPrintService();
278
} catch (Throwable t) {
279
IPPPrintService.debug_println(debugPrefix+
280
"Exception getting default printer : " + t);
281
}
282
if (CUPSPrinter.isCupsRunning()) {
283
try {
284
printerURIs = CUPSPrinter.getAllPrinters();
285
IPPPrintService.debug_println("CUPS URIs = " + printerURIs);
286
if (printerURIs != null) {
287
for (int p = 0; p < printerURIs.length; p++) {
288
IPPPrintService.debug_println("URI="+printerURIs[p]);
289
}
290
}
291
} catch (Throwable t) {
292
IPPPrintService.debug_println(debugPrefix+
293
"Exception getting all CUPS printers : " + t);
294
}
295
if ((printerURIs != null) && (printerURIs.length > 0)) {
296
printers = new String[printerURIs.length];
297
for (int i=0; i<printerURIs.length; i++) {
298
int lastIndex = printerURIs[i].lastIndexOf("/");
299
printers[i] = printerURIs[i].substring(lastIndex+1);
300
}
301
}
302
} else {
303
if (isMac() || isSysV()) {
304
printers = getAllPrinterNamesSysV();
305
} else if (isAIX()) {
306
printers = getAllPrinterNamesAIX();
307
} else { //BSD
308
printers = getAllPrinterNamesBSD();
309
}
310
}
311
312
if (printers == null) {
313
if (defaultPrintService != null) {
314
printServices = new PrintService[1];
315
printServices[0] = defaultPrintService;
316
} else {
317
printServices = null;
318
}
319
return;
320
}
321
322
ArrayList printerList = new ArrayList();
323
int defaultIndex = -1;
324
for (int p=0; p<printers.length; p++) {
325
if (printers[p] == null) {
326
continue;
327
}
328
if ((defaultPrintService != null)
329
&& printers[p].equals(getPrinterDestName(defaultPrintService))) {
330
defaultIndex = addPrintServiceToList(printerList, defaultPrintService);
331
} else {
332
if (printServices == null) {
333
IPPPrintService.debug_println(debugPrefix+
334
"total# of printers = "+printers.length);
335
336
if (CUPSPrinter.isCupsRunning()) {
337
try {
338
addPrintServiceToList(printerList,
339
new IPPPrintService(printers[p],
340
printerURIs[p],
341
true));
342
} catch (Exception e) {
343
IPPPrintService.debug_println(debugPrefix+
344
" getAllPrinters Exception "+
345
e);
346
347
}
348
} else {
349
printerList.add(new UnixPrintService(printers[p]));
350
}
351
} else {
352
int j;
353
for (j=0; j<printServices.length; j++) {
354
if (printServices[j] != null) {
355
if (printers[p].equals(getPrinterDestName(printServices[j]))) {
356
printerList.add(printServices[j]);
357
printServices[j] = null;
358
break;
359
}
360
}
361
}
362
363
if (j == printServices.length) { // not found?
364
if (CUPSPrinter.isCupsRunning()) {
365
try {
366
addPrintServiceToList(printerList,
367
new IPPPrintService(printers[p],
368
printerURIs[p],
369
true));
370
} catch (Exception e) {
371
IPPPrintService.debug_println(debugPrefix+
372
" getAllPrinters Exception "+
373
e);
374
375
}
376
} else {
377
printerList.add(new UnixPrintService(printers[p]));
378
}
379
}
380
}
381
}
382
}
383
384
// Look for deleted services and invalidate these
385
if (printServices != null) {
386
for (int j=0; j < printServices.length; j++) {
387
if ((printServices[j] instanceof UnixPrintService) &&
388
(!printServices[j].equals(defaultPrintService))) {
389
((UnixPrintService)printServices[j]).invalidateService();
390
}
391
}
392
}
393
394
//if defaultService is not found in printerList
395
if (defaultIndex == -1 && defaultPrintService != null) {
396
defaultIndex = addPrintServiceToList(printerList, defaultPrintService);
397
}
398
399
printServices = (PrintService[])printerList.toArray(
400
new PrintService[] {});
401
402
// swap default with the first in the list
403
if (defaultIndex > 0) {
404
PrintService saveService = printServices[0];
405
printServices[0] = printServices[defaultIndex];
406
printServices[defaultIndex] = saveService;
407
}
408
}
409
410
private boolean matchesAttributes(PrintService service,
411
PrintServiceAttributeSet attributes) {
412
413
Attribute [] attrs = attributes.toArray();
414
Attribute serviceAttr;
415
for (int i=0; i<attrs.length; i++) {
416
serviceAttr
417
= service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
418
if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
419
return false;
420
}
421
}
422
return true;
423
}
424
425
/* This checks for validity of the printer name before passing as
426
* parameter to a shell command.
427
*/
428
private boolean checkPrinterName(String s) {
429
char c;
430
431
for (int i=0; i < s.length(); i++) {
432
c = s.charAt(i);
433
if (Character.isLetterOrDigit(c) ||
434
c == '-' || c == '_' || c == '.' || c == '/') {
435
continue;
436
} else {
437
return false;
438
}
439
}
440
return true;
441
}
442
443
/*
444
* Gets the printer name compatible with the list of printers returned by
445
* the system when we query default or all the available printers.
446
*/
447
private String getPrinterDestName(PrintService ps) {
448
if (isMac()) {
449
return ((IPPPrintService)ps).getDest();
450
}
451
return ps.getName();
452
}
453
454
/* On a network with many (hundreds) of network printers, it
455
* can save several seconds if you know all you want is a particular
456
* printer, to ask for that printer rather than retrieving all printers.
457
*/
458
private PrintService getServiceByName(PrinterName nameAttr) {
459
String name = nameAttr.getValue();
460
if (name == null || name.equals("") || !checkPrinterName(name)) {
461
return null;
462
}
463
/* check if all printers are already available */
464
if (printServices != null) {
465
for (PrintService printService : printServices) {
466
PrinterName printerName =
467
(PrinterName)printService.getAttribute(PrinterName.class);
468
if (printerName.getValue().equals(name)) {
469
return printService;
470
}
471
}
472
}
473
/* take CUPS into account first */
474
if (CUPSPrinter.isCupsRunning()) {
475
try {
476
return new IPPPrintService(name,
477
new URL("http://"+
478
CUPSPrinter.getServer()+":"+
479
CUPSPrinter.getPort()+"/"+
480
name));
481
} catch (Exception e) {
482
IPPPrintService.debug_println(debugPrefix+
483
" getServiceByName Exception "+
484
e);
485
}
486
}
487
/* fallback if nothing not having a printer at this point */
488
PrintService printer = null;
489
if (isMac() || isSysV()) {
490
printer = getNamedPrinterNameSysV(name);
491
} else if (isAIX()) {
492
printer = getNamedPrinterNameAIX(name);
493
} else {
494
printer = getNamedPrinterNameBSD(name);
495
}
496
return printer;
497
}
498
499
private PrintService[]
500
getPrintServices(PrintServiceAttributeSet serviceSet) {
501
502
if (serviceSet == null || serviceSet.isEmpty()) {
503
return getPrintServices();
504
}
505
506
/* Typically expect that if a service attribute is specified that
507
* its a printer name and there ought to be only one match.
508
* Directly retrieve that service and confirm
509
* that it meets the other requirements.
510
* If printer name isn't mentioned then go a slow path checking
511
* all printers if they meet the reqiremements.
512
*/
513
PrintService[] services;
514
PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
515
PrintService defService;
516
if (name != null && (defService = getDefaultPrintService()) != null) {
517
/* To avoid execing a unix command see if the client is asking
518
* for the default printer by name, since we already have that
519
* initialised.
520
*/
521
522
PrinterName defName =
523
(PrinterName)defService.getAttribute(PrinterName.class);
524
525
if (defName != null && name.equals(defName)) {
526
if (matchesAttributes(defService, serviceSet)) {
527
services = new PrintService[1];
528
services[0] = defService;
529
return services;
530
} else {
531
return new PrintService[0];
532
}
533
} else {
534
/* Its not the default service */
535
PrintService service = getServiceByName(name);
536
if (service != null &&
537
matchesAttributes(service, serviceSet)) {
538
services = new PrintService[1];
539
services[0] = service;
540
return services;
541
} else {
542
return new PrintService[0];
543
}
544
}
545
} else {
546
/* specified service attributes don't include a name.*/
547
Vector matchedServices = new Vector();
548
services = getPrintServices();
549
for (int i = 0; i< services.length; i++) {
550
if (matchesAttributes(services[i], serviceSet)) {
551
matchedServices.add(services[i]);
552
}
553
}
554
services = new PrintService[matchedServices.size()];
555
for (int i = 0; i< services.length; i++) {
556
services[i] = (PrintService)matchedServices.elementAt(i);
557
}
558
return services;
559
}
560
}
561
562
/*
563
* If service attributes are specified then there must be additional
564
* filtering.
565
*/
566
public PrintService[] getPrintServices(DocFlavor flavor,
567
AttributeSet attributes) {
568
SecurityManager security = System.getSecurityManager();
569
if (security != null) {
570
security.checkPrintJobAccess();
571
}
572
PrintRequestAttributeSet requestSet = null;
573
PrintServiceAttributeSet serviceSet = null;
574
575
if (attributes != null && !attributes.isEmpty()) {
576
577
requestSet = new HashPrintRequestAttributeSet();
578
serviceSet = new HashPrintServiceAttributeSet();
579
580
Attribute[] attrs = attributes.toArray();
581
for (int i=0; i<attrs.length; i++) {
582
if (attrs[i] instanceof PrintRequestAttribute) {
583
requestSet.add(attrs[i]);
584
} else if (attrs[i] instanceof PrintServiceAttribute) {
585
serviceSet.add(attrs[i]);
586
}
587
}
588
}
589
590
PrintService[] services = getPrintServices(serviceSet);
591
if (services.length == 0) {
592
return services;
593
}
594
595
if (CUPSPrinter.isCupsRunning()) {
596
ArrayList matchingServices = new ArrayList();
597
for (int i=0; i<services.length; i++) {
598
try {
599
if (services[i].
600
getUnsupportedAttributes(flavor, requestSet) == null) {
601
matchingServices.add(services[i]);
602
}
603
} catch (IllegalArgumentException e) {
604
}
605
}
606
services = new PrintService[matchingServices.size()];
607
return (PrintService[])matchingServices.toArray(services);
608
609
} else {
610
// We only need to compare 1 PrintService because all
611
// UnixPrintServices are the same anyway. We will not use
612
// default PrintService because it might be null.
613
PrintService service = services[0];
614
if ((flavor == null ||
615
service.isDocFlavorSupported(flavor)) &&
616
service.getUnsupportedAttributes(flavor, requestSet) == null)
617
{
618
return services;
619
} else {
620
return new PrintService[0];
621
}
622
}
623
}
624
625
/*
626
* return empty array as don't support multi docs
627
*/
628
public MultiDocPrintService[]
629
getMultiDocPrintServices(DocFlavor[] flavors,
630
AttributeSet attributes) {
631
SecurityManager security = System.getSecurityManager();
632
if (security != null) {
633
security.checkPrintJobAccess();
634
}
635
return new MultiDocPrintService[0];
636
}
637
638
639
public synchronized PrintService getDefaultPrintService() {
640
SecurityManager security = System.getSecurityManager();
641
if (security != null) {
642
security.checkPrintJobAccess();
643
}
644
645
// clear defaultPrintService
646
defaultPrintService = null;
647
String psuri = null;
648
649
IPPPrintService.debug_println("isRunning ? "+
650
(CUPSPrinter.isCupsRunning()));
651
if (CUPSPrinter.isCupsRunning()) {
652
String[] printerInfo = CUPSPrinter.getDefaultPrinter();
653
if (printerInfo != null && printerInfo.length >= 2) {
654
defaultPrinter = printerInfo[0];
655
psuri = printerInfo[1];
656
}
657
} else {
658
if (isMac() || isSysV()) {
659
defaultPrinter = getDefaultPrinterNameSysV();
660
} else if (isAIX()) {
661
defaultPrinter = getDefaultPrinterNameAIX();
662
} else {
663
defaultPrinter = getDefaultPrinterNameBSD();
664
}
665
}
666
if (defaultPrinter == null) {
667
return null;
668
}
669
defaultPrintService = null;
670
if (printServices != null) {
671
for (int j=0; j<printServices.length; j++) {
672
if (defaultPrinter.equals(getPrinterDestName(printServices[j]))) {
673
defaultPrintService = printServices[j];
674
break;
675
}
676
}
677
}
678
if (defaultPrintService == null) {
679
if (CUPSPrinter.isCupsRunning()) {
680
try {
681
PrintService defaultPS;
682
if ((psuri != null) && !psuri.startsWith("file")) {
683
defaultPS = new IPPPrintService(defaultPrinter,
684
psuri, true);
685
} else {
686
defaultPS = new IPPPrintService(defaultPrinter,
687
new URL("http://"+
688
CUPSPrinter.getServer()+":"+
689
CUPSPrinter.getPort()+"/"+
690
defaultPrinter));
691
}
692
defaultPrintService = defaultPS;
693
} catch (Exception e) {
694
}
695
} else {
696
defaultPrintService = new UnixPrintService(defaultPrinter);
697
}
698
}
699
700
return defaultPrintService;
701
}
702
703
public synchronized void
704
getServicesInbackground(BackgroundLookupListener listener) {
705
if (printServices != null) {
706
listener.notifyServices(printServices);
707
} else {
708
if (lookupListeners == null) {
709
lookupListeners = new Vector();
710
lookupListeners.add(listener);
711
Thread lookupThread = new Thread(this);
712
lookupThread.start();
713
} else {
714
lookupListeners.add(listener);
715
}
716
}
717
}
718
719
/* This method isn't used in most cases because we rely on code in
720
* javax.print.PrintServiceLookup. This is needed just for the cases
721
* where those interfaces are by-passed.
722
*/
723
private PrintService[] copyOf(PrintService[] inArr) {
724
if (inArr == null || inArr.length == 0) {
725
return inArr;
726
} else {
727
PrintService []outArr = new PrintService[inArr.length];
728
System.arraycopy(inArr, 0, outArr, 0, inArr.length);
729
return outArr;
730
}
731
}
732
733
public void run() {
734
PrintService[] services = getPrintServices();
735
synchronized (this) {
736
BackgroundLookupListener listener;
737
for (int i=0; i<lookupListeners.size(); i++) {
738
listener =
739
(BackgroundLookupListener)lookupListeners.elementAt(i);
740
listener.notifyServices(copyOf(services));
741
}
742
lookupListeners = null;
743
}
744
}
745
746
private String getDefaultPrinterNameBSD() {
747
if (cmdIndex == UNINITIALIZED) {
748
cmdIndex = getBSDCommandIndex();
749
}
750
String[] names = execCmd(lpcFirstCom[cmdIndex]);
751
if (names == null || names.length == 0) {
752
return null;
753
}
754
755
if ((cmdIndex==BSD_LPD_NG) &&
756
(names[0].startsWith("missingprinter"))) {
757
return null;
758
}
759
return names[0];
760
}
761
762
private PrintService getNamedPrinterNameBSD(String name) {
763
if (cmdIndex == UNINITIALIZED) {
764
cmdIndex = getBSDCommandIndex();
765
}
766
String command = "/usr/sbin/lpc status " + name + lpcNameCom[cmdIndex];
767
String[] result = execCmd(command);
768
769
if (result == null || !(result[0].equals(name))) {
770
return null;
771
}
772
return new UnixPrintService(name);
773
}
774
775
private String[] getAllPrinterNamesBSD() {
776
if (cmdIndex == UNINITIALIZED) {
777
cmdIndex = getBSDCommandIndex();
778
}
779
String[] names = execCmd(lpcAllCom[cmdIndex]);
780
if (names == null || names.length == 0) {
781
return null;
782
}
783
return names;
784
}
785
786
static String getDefaultPrinterNameSysV() {
787
String defaultPrinter = "lp";
788
String command = "/usr/bin/lpstat -d";
789
790
String [] names = execCmd(command);
791
if (names == null || names.length == 0) {
792
return defaultPrinter;
793
} else {
794
int index = names[0].indexOf(":");
795
if (index == -1 || (names[0].length() <= index+1)) {
796
return null;
797
} else {
798
String name = names[0].substring(index+1).trim();
799
if (name.length() == 0) {
800
return null;
801
} else {
802
return name;
803
}
804
}
805
}
806
}
807
808
private PrintService getNamedPrinterNameSysV(String name) {
809
810
String command = "/usr/bin/lpstat -v " + name;
811
String []result = execCmd(command);
812
813
if (result == null || result[0].indexOf("unknown printer") > 0) {
814
return null;
815
} else {
816
return new UnixPrintService(name);
817
}
818
}
819
820
private String[] getAllPrinterNamesSysV() {
821
String defaultPrinter = "lp";
822
String command = "/usr/bin/lpstat -v|/usr/bin/expand|/usr/bin/cut -f3 -d' ' |/usr/bin/cut -f1 -d':' | /usr/bin/sort";
823
824
String [] names = execCmd(command);
825
ArrayList printerNames = new ArrayList();
826
for (int i=0; i < names.length; i++) {
827
if (!names[i].equals("_default") &&
828
!names[i].equals(defaultPrinter) &&
829
!names[i].equals("")) {
830
printerNames.add(names[i]);
831
}
832
}
833
return (String[])printerNames.toArray(new String[printerNames.size()]);
834
}
835
836
private String getDefaultPrinterNameAIX() {
837
String[] names = execCmd(lpNameComAix[aix_lpstat_d]);
838
// Remove headers and bogus entries added by remote printers.
839
names = UnixPrintService.filterPrinterNamesAIX(names);
840
if (names == null || names.length != 1) {
841
// No default printer found
842
return null;
843
} else {
844
return names[0];
845
}
846
}
847
848
private PrintService getNamedPrinterNameAIX(String name) {
849
// On AIX there should be no blank after '-v'.
850
String[] result = execCmd(lpNameComAix[aix_lpstat_v] + name);
851
// Remove headers and bogus entries added by remote printers.
852
result = UnixPrintService.filterPrinterNamesAIX(result);
853
if (result == null || result.length != 1) {
854
return null;
855
} else {
856
return new UnixPrintService(name);
857
}
858
}
859
860
private String[] getAllPrinterNamesAIX() {
861
// Determine all printers of the system.
862
String [] names = execCmd(lpNameComAix[aix_defaultPrinterEnumeration]);
863
864
// Remove headers and bogus entries added by remote printers.
865
names = UnixPrintService.filterPrinterNamesAIX(names);
866
867
ArrayList<String> printerNames = new ArrayList<String>();
868
for ( int i=0; i < names.length; i++) {
869
printerNames.add(names[i]);
870
}
871
return (String[])printerNames.toArray(new String[printerNames.size()]);
872
}
873
874
static String[] execCmd(final String command) {
875
ArrayList results = null;
876
try {
877
final String[] cmd = new String[3];
878
if (isSysV() || isAIX()) {
879
cmd[0] = "/usr/bin/sh";
880
cmd[1] = "-c";
881
cmd[2] = "env LC_ALL=C " + command;
882
} else {
883
cmd[0] = "/bin/sh";
884
cmd[1] = "-c";
885
cmd[2] = "LC_ALL=C " + command;
886
}
887
888
results = (ArrayList)AccessController.doPrivileged(
889
new PrivilegedExceptionAction() {
890
public Object run() throws IOException {
891
892
Process proc;
893
BufferedReader bufferedReader = null;
894
File f = Files.createTempFile("prn","xc").toFile();
895
cmd[2] = cmd[2]+">"+f.getAbsolutePath();
896
897
proc = Runtime.getRuntime().exec(cmd);
898
try {
899
boolean done = false; // in case of interrupt.
900
while (!done) {
901
try {
902
proc.waitFor();
903
done = true;
904
} catch (InterruptedException e) {
905
}
906
}
907
908
if (proc.exitValue() == 0) {
909
FileReader reader = new FileReader(f);
910
bufferedReader = new BufferedReader(reader);
911
String line;
912
ArrayList results = new ArrayList();
913
while ((line = bufferedReader.readLine())
914
!= null) {
915
results.add(line);
916
}
917
return results;
918
}
919
} finally {
920
f.delete();
921
// promptly close all streams.
922
if (bufferedReader != null) {
923
bufferedReader.close();
924
}
925
proc.getInputStream().close();
926
proc.getErrorStream().close();
927
proc.getOutputStream().close();
928
}
929
return null;
930
}
931
});
932
} catch (PrivilegedActionException e) {
933
}
934
if (results == null) {
935
return new String[0];
936
} else {
937
return (String[])results.toArray(new String[results.size()]);
938
}
939
}
940
941
private class PrinterChangeListener extends Thread {
942
943
public void run() {
944
int refreshSecs;
945
while (true) {
946
try {
947
refreshServices();
948
} catch (Exception se) {
949
IPPPrintService.debug_println(debugPrefix+"Exception in refresh thread.");
950
break;
951
}
952
953
if ((printServices != null) &&
954
(printServices.length > minRefreshTime)) {
955
// compute new refresh time 1 printer = 1 sec
956
refreshSecs = printServices.length;
957
} else {
958
refreshSecs = minRefreshTime;
959
}
960
try {
961
sleep(refreshSecs * 1000);
962
} catch (InterruptedException e) {
963
break;
964
}
965
}
966
}
967
}
968
}
969
970