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