Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java
41153 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 javax.print;
27
28
import java.util.ArrayList;
29
import java.util.Iterator;
30
import java.util.ServiceConfigurationError;
31
import java.util.ServiceLoader;
32
33
import javax.print.attribute.AttributeSet;
34
35
import sun.awt.AppContext;
36
37
/**
38
* Implementations of this class provide lookup services for print services
39
* (typically equivalent to printers) of a particular type.
40
* <p>
41
* Multiple implementations may be installed concurrently. All implementations
42
* must be able to describe the located printers as instances of a
43
* {@code PrintService}. Typically implementations of this service class are
44
* located automatically in JAR files (see the SPI JAR file specification).
45
* These classes must be instantiable using a default constructor. Alternatively
46
* applications may explicitly register instances at runtime.
47
* <p>
48
* Applications use only the static methods of this abstract class. The instance
49
* methods are implemented by a service provider in a subclass and the
50
* unification of the results from all installed lookup classes are reported by
51
* the static methods of this class when called by the application.
52
* <p>
53
* A {@code PrintServiceLookup} implementor is recommended to check for the
54
* {@code SecurityManager.checkPrintJobAccess()} to deny access to untrusted
55
* code. Following this recommended policy means that untrusted code may not be
56
* able to locate any print services. Downloaded applets are the most common
57
* example of untrusted code.
58
* <p>
59
* This check is made on a per lookup service basis to allow flexibility in the
60
* policy to reflect the needs of different lookup services.
61
* <p>
62
* Services which are registered by {@link #registerService(PrintService)} will
63
* not be included in lookup results if a security manager is installed and its
64
* {@code checkPrintJobAccess()} method denies access.
65
*/
66
public abstract class PrintServiceLookup {
67
68
/**
69
* Constructor for subclasses to call.
70
*/
71
protected PrintServiceLookup() {}
72
73
/**
74
* Contains a lists of services.
75
*/
76
static class Services {
77
78
/**
79
* The list of lookup services.
80
*/
81
private ArrayList<PrintServiceLookup> listOfLookupServices = null;
82
83
/**
84
* The list of registered services.
85
*/
86
private ArrayList<PrintService> registeredServices = null;
87
}
88
89
/**
90
* Returns the services from the current appcontext.
91
*
92
* @return the services
93
*/
94
private static Services getServicesForContext() {
95
Services services =
96
(Services)AppContext.getAppContext().get(Services.class);
97
if (services == null) {
98
services = new Services();
99
AppContext.getAppContext().put(Services.class, services);
100
}
101
return services;
102
}
103
104
/**
105
* Returns the list of lookup services.
106
*
107
* @return the list of lookup services
108
*/
109
private static ArrayList<PrintServiceLookup> getListOfLookupServices() {
110
return getServicesForContext().listOfLookupServices;
111
}
112
113
/**
114
* Initialize the list of lookup services.
115
*
116
* @return the list of lookup services
117
*/
118
private static ArrayList<PrintServiceLookup> initListOfLookupServices() {
119
ArrayList<PrintServiceLookup> listOfLookupServices = new ArrayList<>();
120
getServicesForContext().listOfLookupServices = listOfLookupServices;
121
return listOfLookupServices;
122
}
123
124
/**
125
* Returns the list of registered services.
126
*
127
* @return the list of registered services
128
*/
129
private static ArrayList<PrintService> getRegisteredServices() {
130
return getServicesForContext().registeredServices;
131
}
132
133
/**
134
* Initialize the list of registered services.
135
*
136
* @return the list of registered services
137
*/
138
private static ArrayList<PrintService> initRegisteredServices() {
139
ArrayList<PrintService> registeredServices = new ArrayList<>();
140
getServicesForContext().registeredServices = registeredServices;
141
return registeredServices;
142
}
143
144
/**
145
* Locates print services capable of printing the specified
146
* {@link DocFlavor}.
147
*
148
* @param flavor the flavor to print. If {@code null}, this constraint is
149
* not used.
150
* @param attributes attributes that the print service must support. If
151
* {@code null} this constraint is not used.
152
* @return array of matching {@code PrintService} objects representing print
153
* services that support the specified flavor attributes. If no
154
* services match, the array is zero-length.
155
*/
156
public static final PrintService[]
157
lookupPrintServices(DocFlavor flavor,
158
AttributeSet attributes) {
159
ArrayList<PrintService> list = getServices(flavor, attributes);
160
return list.toArray(new PrintService[list.size()]);
161
}
162
163
/**
164
* Locates {@code MultiDoc} print {@code Services} capable of printing
165
* {@code MultiDocs} containing all the specified doc flavors.
166
* <p>
167
* This method is useful to help locate a service that can print a
168
* {@code MultiDoc} in which the elements may be different flavors. An
169
* application could perform this itself by multiple lookups on each
170
* {@code DocFlavor} in turn and collating the results, but the lookup
171
* service may be able to do this more efficiently.
172
*
173
* @param flavors the flavors to print. If {@code null} or empty this
174
* constraint is not used. Otherwise return only multidoc print
175
* services that can print all specified doc flavors.
176
* @param attributes attributes that the print service must support. If
177
* {@code null} this constraint is not used.
178
* @return array of matching {@link MultiDocPrintService} objects. If no
179
* services match, the array is zero-length.
180
*/
181
public static final MultiDocPrintService[]
182
lookupMultiDocPrintServices(DocFlavor[] flavors,
183
AttributeSet attributes) {
184
ArrayList<MultiDocPrintService> list = getMultiDocServices(flavors, attributes);
185
return list.toArray(new MultiDocPrintService[list.size()]);
186
}
187
188
/**
189
* Locates the default print service for this environment. This may return
190
* {@code null}. If multiple lookup services each specify a default, the
191
* chosen service is not precisely defined, but a platform native service,
192
* rather than an installed service, is usually returned as the default. If
193
* there is no clearly identifiable platform native default print service,
194
* the default is the first to be located in an implementation-dependent
195
* manner.
196
* <p>
197
* This may include making use of any preferences API that is available as
198
* part of the Java or native platform. This algorithm may be overridden by
199
* a user setting the property {@code javax.print.defaultPrinter}. A service
200
* specified must be discovered to be valid and currently available to be
201
* returned as the default.
202
*
203
* @return the default {@code PrintService}
204
*/
205
public static final PrintService lookupDefaultPrintService() {
206
207
Iterator<PrintServiceLookup> psIterator = getAllLookupServices().iterator();
208
while (psIterator.hasNext()) {
209
try {
210
PrintServiceLookup lus = psIterator.next();
211
PrintService service = lus.getDefaultPrintService();
212
if (service != null) {
213
return service;
214
}
215
} catch (Exception e) {
216
}
217
}
218
return null;
219
}
220
221
/**
222
* Allows an application to explicitly register a class that implements
223
* lookup services. The registration will not persist across VM invocations.
224
* This is useful if an application needs to make a new service available
225
* that is not part of the installation. If the lookup service is already
226
* registered, or cannot be registered, the method returns {@code false}.
227
*
228
* @param sp an implementation of a lookup service
229
* @return {@code true} if the new lookup service is newly registered;
230
* {@code false} otherwise
231
*/
232
public static boolean registerServiceProvider(PrintServiceLookup sp) {
233
synchronized (PrintServiceLookup.class) {
234
Iterator<PrintServiceLookup> psIterator =
235
getAllLookupServices().iterator();
236
while (psIterator.hasNext()) {
237
try {
238
Object lus = psIterator.next();
239
if (lus.getClass() == sp.getClass()) {
240
return false;
241
}
242
} catch (Exception e) {
243
}
244
}
245
getListOfLookupServices().add(sp);
246
return true;
247
}
248
}
249
250
/**
251
* Allows an application to directly register an instance of a class which
252
* implements a print service. The lookup operations for this service will
253
* be performed by the {@code PrintServiceLookup} class using the attribute
254
* values and classes reported by the service. This may be less efficient
255
* than a lookup service tuned for that service. Therefore registering a
256
* {@code PrintServiceLookup} instance instead is recommended. The method
257
* returns {@code true} if this service is not previously registered and is
258
* now successfully registered. This method should not be called with
259
* {@code StreamPrintService} instances. They will always fail to register
260
* and the method will return {@code false}.
261
*
262
* @param service an implementation of a print service
263
* @return {@code true} if the service is newly registered; {@code false}
264
* otherwise
265
*/
266
public static boolean registerService(PrintService service) {
267
synchronized (PrintServiceLookup.class) {
268
if (service == null || service instanceof StreamPrintService) {
269
return false;
270
}
271
ArrayList<PrintService> registeredServices = getRegisteredServices();
272
if (registeredServices == null) {
273
registeredServices = initRegisteredServices();
274
}
275
else {
276
if (registeredServices.contains(service)) {
277
return false;
278
}
279
}
280
registeredServices.add(service);
281
return true;
282
}
283
}
284
285
/**
286
* Locates services that can be positively confirmed to support the
287
* combination of attributes and {@code DocFlavors} specified. This method
288
* is not called directly by applications.
289
* <p>
290
* Implemented by a service provider, used by the static methods of this
291
* class.
292
* <p>
293
* The results should be the same as obtaining all the {@code PrintServices}
294
* and querying each one individually on its support for the specified
295
* attributes and flavors, but the process can be more efficient by taking
296
* advantage of the capabilities of lookup services for the print services.
297
*
298
* @param flavor of document required. If {@code null} it is ignored.
299
* @param attributes required to be supported. If {@code null} this
300
* constraint is not used.
301
* @return array of matching {@code PrintServices}. If no services match,
302
* the array is zero-length.
303
*/
304
public abstract PrintService[] getPrintServices(DocFlavor flavor,
305
AttributeSet attributes);
306
307
/**
308
* Not called directly by applications. Implemented by a service provider,
309
* used by the static methods of this class.
310
*
311
* @return array of all {@code PrintServices} known to this lookup service
312
* class. If none are found, the array is zero-length.
313
*/
314
public abstract PrintService[] getPrintServices() ;
315
316
/**
317
* Not called directly by applications.
318
* <p>
319
* Implemented by a service provider, used by the static methods of this
320
* class.
321
* <p>
322
* Locates {@code MultiDoc} print services which can be positively confirmed
323
* to support the combination of attributes and {@code DocFlavors}
324
* specified.
325
*
326
* @param flavors of documents required. If {@code null} or empty it is
327
* ignored.
328
* @param attributes required to be supported. If {@code null} this
329
* constraint is not used.
330
* @return array of matching {@code PrintServices}. If no services match,
331
* the array is zero-length.
332
*/
333
public abstract MultiDocPrintService[]
334
getMultiDocPrintServices(DocFlavor[] flavors,
335
AttributeSet attributes);
336
337
/**
338
* Not called directly by applications. Implemented by a service provider,
339
* and called by the print lookup service.
340
*
341
* @return the default {@code PrintService} for this lookup service. If
342
* there is no default, returns {@code null}.
343
*/
344
public abstract PrintService getDefaultPrintService();
345
346
/**
347
* Returns all lookup services for this environment.
348
*
349
* @return all lookup services for this environment
350
*/
351
@SuppressWarnings("removal")
352
private static ArrayList<PrintServiceLookup> getAllLookupServices() {
353
synchronized (PrintServiceLookup.class) {
354
ArrayList<PrintServiceLookup> listOfLookupServices = getListOfLookupServices();
355
if (listOfLookupServices != null) {
356
return listOfLookupServices;
357
} else {
358
listOfLookupServices = initListOfLookupServices();
359
}
360
try {
361
java.security.AccessController.doPrivileged(
362
new java.security.PrivilegedExceptionAction<Object>() {
363
public Object run() {
364
Iterator<PrintServiceLookup> iterator =
365
ServiceLoader.load(PrintServiceLookup.class).
366
iterator();
367
ArrayList<PrintServiceLookup> los = getListOfLookupServices();
368
while (iterator.hasNext()) {
369
try {
370
los.add(iterator.next());
371
} catch (ServiceConfigurationError err) {
372
/* In the applet case, we continue */
373
if (System.getSecurityManager() != null) {
374
err.printStackTrace();
375
} else {
376
throw err;
377
}
378
}
379
}
380
return null;
381
}
382
});
383
} catch (java.security.PrivilegedActionException e) {
384
}
385
386
return listOfLookupServices;
387
}
388
}
389
390
/**
391
* Locates print services capable of printing the specified
392
* {@link DocFlavor}.
393
*
394
* @param flavor the flavor to print. If {@code null}, this constraint is
395
* not used.
396
* @param attributes attributes that the print service must support. If
397
* {@code null} this constraint is not used.
398
* @return list of matching {@code PrintService} objects representing print
399
* services that support the specified flavor attributes. If no
400
* services match, the empty list is returned.
401
*/
402
private static ArrayList<PrintService> getServices(DocFlavor flavor,
403
AttributeSet attributes) {
404
405
ArrayList<PrintService> listOfServices = new ArrayList<>();
406
Iterator<PrintServiceLookup> psIterator = getAllLookupServices().iterator();
407
while (psIterator.hasNext()) {
408
try {
409
PrintServiceLookup lus = psIterator.next();
410
PrintService[] services=null;
411
if (flavor == null && attributes == null) {
412
try {
413
services = lus.getPrintServices();
414
} catch (Throwable tr) {
415
}
416
} else {
417
services = lus.getPrintServices(flavor, attributes);
418
}
419
if (services == null) {
420
continue;
421
}
422
for (int i=0; i<services.length; i++) {
423
listOfServices.add(services[i]);
424
}
425
} catch (Exception e) {
426
}
427
}
428
/*
429
* add any directly registered services
430
*/
431
ArrayList<PrintService> registeredServices = null;
432
try {
433
@SuppressWarnings("removal")
434
SecurityManager security = System.getSecurityManager();
435
if (security != null) {
436
security.checkPrintJobAccess();
437
}
438
registeredServices = getRegisteredServices();
439
} catch (SecurityException se) {
440
}
441
if (registeredServices != null) {
442
PrintService[] services = registeredServices.toArray(
443
new PrintService[registeredServices.size()]);
444
for (int i=0; i<services.length; i++) {
445
if (!listOfServices.contains(services[i])) {
446
if (flavor == null && attributes == null) {
447
listOfServices.add(services[i]);
448
} else if (((flavor != null &&
449
services[i].isDocFlavorSupported(flavor)) ||
450
flavor == null) &&
451
null == services[i].getUnsupportedAttributes(
452
flavor, attributes)) {
453
listOfServices.add(services[i]);
454
}
455
}
456
}
457
}
458
return listOfServices;
459
}
460
461
/**
462
* Locates {@code MultiDoc} print {@code Services} capable of printing
463
* {@code MultiDocs} containing all the specified doc flavors.
464
*
465
* @param flavors the flavors to print. If {@code null} or empty this
466
* constraint is not used. Otherwise return only multidoc print
467
* services that can print all specified doc flavors.
468
* @param attributes attributes that the print service must support. If
469
* {@code null} this constraint is not used.
470
* @return list of matching {@link MultiDocPrintService} objects. If no
471
* services match, the empty list is returned.
472
*/
473
private static ArrayList<MultiDocPrintService> getMultiDocServices(DocFlavor[] flavors,
474
AttributeSet attributes) {
475
476
477
ArrayList<MultiDocPrintService> listOfServices = new ArrayList<>();
478
Iterator<PrintServiceLookup> psIterator = getAllLookupServices().iterator();
479
while (psIterator.hasNext()) {
480
try {
481
PrintServiceLookup lus = psIterator.next();
482
MultiDocPrintService[] services =
483
lus.getMultiDocPrintServices(flavors, attributes);
484
if (services == null) {
485
continue;
486
}
487
for (int i=0; i<services.length; i++) {
488
listOfServices.add(services[i]);
489
}
490
} catch (Exception e) {
491
}
492
}
493
/*
494
* add any directly registered services
495
*/
496
ArrayList<PrintService> registeredServices = null;
497
try {
498
@SuppressWarnings("removal")
499
SecurityManager security = System.getSecurityManager();
500
if (security != null) {
501
security.checkPrintJobAccess();
502
}
503
registeredServices = getRegisteredServices();
504
} catch (Exception e) {
505
}
506
if (registeredServices != null) {
507
PrintService[] services =
508
registeredServices.toArray(new PrintService[registeredServices.size()]);
509
for (int i=0; i<services.length; i++) {
510
if (services[i] instanceof MultiDocPrintService &&
511
!listOfServices.contains(services[i])) {
512
if (flavors == null || flavors.length == 0) {
513
listOfServices.add((MultiDocPrintService)services[i]);
514
} else {
515
boolean supported = true;
516
for (int f=0; f<flavors.length; f++) {
517
if (services[i].isDocFlavorSupported(flavors[f])) {
518
519
if (services[i].getUnsupportedAttributes(
520
flavors[f], attributes) != null) {
521
supported = false;
522
break;
523
}
524
} else {
525
supported = false;
526
break;
527
}
528
}
529
if (supported) {
530
listOfServices.add((MultiDocPrintService)services[i]);
531
}
532
}
533
}
534
}
535
}
536
return listOfServices;
537
}
538
}
539
540