KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > print > PrintServiceLookup


1 /*
2  * @(#)PrintServiceLookup.java 1.14 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8
9 package javax.print;
10
11 import java.util.ArrayList JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.List JavaDoc;
14 import javax.print.attribute.AttributeSet JavaDoc;
15
16 import sun.awt.AppContext;
17 import sun.misc.Service;
18
19 /** Implementations of this class provide lookup services for
20   * print services (typically equivalent to printers) of a particular type.
21   * <p>
22   * Multiple implementations may be installed concurrently.
23   * All implementations must be able to describe the located printers
24   * as instances of a PrintService.
25   * Typically implementations of this service class are located
26   * automatically in JAR files (see the SPI JAR file specification).
27   * These classes must be instantiable using a default constructor.
28   * Alternatively applications may explicitly register instances
29   * at runtime.
30   * <p>
31   * Applications use only the static methods of this abstract class.
32   * The instance methods are implemented by a service provider in a subclass
33   * and the unification of the results from all installed lookup classes
34   * are reported by the static methods of this class when called by
35   * the application.
36   * <p>
37   * A PrintServiceLookup implementor is recommended to check for the
38   * SecurityManager.checkPrintJobAccess() to deny access to untrusted code.
39   * Following this recommended policy means that untrusted code may not
40   * be able to locate any print services. Downloaded applets are the most
41   * common example of untrusted code.
42   * <p>
43   * This check is made on a per lookup service basis to allow flexibility in
44   * the policy to reflect the needs of different lookup services.
45   * <p>
46   * Services which are registered by registerService(PrintService)
47   * will not be included in lookup results if a security manager is
48   * installed and its checkPrintJobAccess() method denies access.
49   */

50
51 public abstract class PrintServiceLookup {
52    
53     static class Services {
54     private ArrayList JavaDoc listOfLookupServices = null;
55     private ArrayList JavaDoc registeredServices = null;
56     }
57
58     private static Services getServicesForContext() {
59     Services services =
60         (Services)AppContext.getAppContext().get(Services.class);
61     if (services == null) {
62         services = new Services();
63         AppContext.getAppContext().put(Services.class, services);
64     }
65     return services;
66     }
67
68     private static ArrayList JavaDoc getListOfLookupServices() {
69     return getServicesForContext().listOfLookupServices;
70     }
71
72     private static ArrayList JavaDoc initListOfLookupServices() {
73     ArrayList JavaDoc listOfLookupServices = new ArrayList JavaDoc();
74     getServicesForContext().listOfLookupServices = listOfLookupServices;
75     return listOfLookupServices;
76     }
77
78
79     private static ArrayList JavaDoc getRegisteredServices() {
80     return getServicesForContext().registeredServices;
81     }
82
83     private static ArrayList JavaDoc initRegisteredServices() {
84     ArrayList JavaDoc registeredServices = new ArrayList JavaDoc();
85     getServicesForContext().registeredServices = registeredServices;
86     return registeredServices;
87     }
88
89     /**
90      * Locates print services capable of printing the specified
91      * {@link DocFlavor}.
92      *
93      * @param flavor the flavor to print. If null, this constraint is not
94      * used.
95      * @param attributes attributes that the print service must support.
96      * If null this constraint is not used.
97      *
98      * @return array of matching <code>PrintService</code> objects
99      * representing print services that support the specified flavor
100      * attributes. If no services match, the array is zero-length.
101      */

102     public static final PrintService JavaDoc[]
103     lookupPrintServices(DocFlavor JavaDoc flavor,
104                 AttributeSet JavaDoc attributes) {
105     ArrayList JavaDoc list = getServices(flavor, attributes);
106     return (PrintService JavaDoc[])(list.toArray(new PrintService JavaDoc[list.size()]));
107     }
108
109
110     /**
111      * Locates MultiDoc print Services capable of printing MultiDocs
112      * containing all the specified doc flavors.
113      * <P> This method is useful to help locate a service that can print
114      * a <code>MultiDoc</code> in which the elements may be different
115      * flavors. An application could perform this itself by multiple lookups
116      * on each <code>DocFlavor</code> in turn and collating the results,
117      * but the lookup service may be able to do this more efficiently.
118      *
119      * @param flavors the flavors to print. If null or empty this
120      * constraint is not used.
121      * Otherwise return only multidoc print services that can print all
122      * specified doc flavors.
123      * @param attributes attributes that the print service must
124      * support. If null this constraint is not used.
125      *
126      * @return array of matching {@link MultiDocPrintService} objects.
127      * If no services match, the array is zero-length.
128      *
129      */

130     public static final MultiDocPrintService JavaDoc[]
131     lookupMultiDocPrintServices(DocFlavor JavaDoc[] flavors,
132                     AttributeSet JavaDoc attributes) {
133     ArrayList JavaDoc list = getMultiDocServices(flavors, attributes);
134     return (MultiDocPrintService JavaDoc[])
135         list.toArray(new MultiDocPrintService JavaDoc[list.size()]);
136     }
137     
138     
139     /**
140      * Locates the default print service for this environment.
141      * This may return null.
142      * If multiple lookup services each specify a default, the
143      * chosen service is not precisely defined, but a
144      * platform native service, rather than an installed service,
145      * is usually returned as the default. If there is no clearly
146      * identifiable
147      * platform native default print service, the default is the first
148      * to be located in an implementation-dependent manner.
149      * <p>
150      * This may include making use of any preferences API that is available
151      * as part of the Java or native platform.
152      * This algorithm may be overridden by a user setting the property
153      * javax.print.defaultPrinter.
154      * A service specified must be discovered to be valid and currently
155      * available to be returned as the default.
156      *
157      * @return the default PrintService.
158      */

159     
160     public static final PrintService JavaDoc lookupDefaultPrintService() {
161     
162     Iterator JavaDoc psIterator = getAllLookupServices().iterator();
163     while (psIterator.hasNext()) {
164         try {
165         PrintServiceLookup JavaDoc lus = (PrintServiceLookup JavaDoc)psIterator.next();
166         PrintService JavaDoc service = lus.getDefaultPrintService();
167         if (service != null) {
168             return service;
169         }
170         } catch (Exception JavaDoc e) {
171         }
172     }
173     return null;
174     }
175
176    
177     /**
178      * Allows an application to explicitly register a class that
179      * implements lookup services. The registration will not persist
180      * across VM invocations.
181      * This is useful if an application needs to make a new service
182      * available that is not part of the installation.
183      * If the lookup service is already registered, or cannot be registered,
184      * the method returns false.
185      * <p>
186      *
187      * @param sp an implementation of a lookup service.
188      * @return <code>true</code> if the new lookup service is newly
189      * registered; <code>false</code> otherwise.
190      */

191     public static boolean registerServiceProvider(PrintServiceLookup JavaDoc sp) {
192     synchronized (PrintServiceLookup JavaDoc.class) {
193         Iterator JavaDoc psIterator = getAllLookupServices().iterator();
194         while (psIterator.hasNext()) {
195         try {
196             Object JavaDoc lus = psIterator.next();
197             if (lus.getClass() == sp.getClass()) {
198             return false;
199             }
200         } catch (Exception JavaDoc e) {
201         }
202         }
203         getListOfLookupServices().add(sp);
204         return true;
205     }
206
207     }
208
209   
210     /**
211      * Allows an application to directly register an instance of a
212      * class which implements a print service.
213      * The lookup operations for this service will be
214      * performed by the PrintServiceLookup class using the attribute
215      * values and classes reported by the service.
216      * This may be less efficient than a lookup
217      * service tuned for that service.
218      * Therefore registering a <code>PrintServiceLookup</code> instance
219      * instead is recommended.
220      * The method returns true if this service is not previously
221      * registered and is now successfully registered.
222      * This method should not be called with StreamPrintService instances.
223      * They will always fail to register and the method will return false.
224      * @param service an implementation of a print service.
225      * @return <code>true</code> if the service is newly
226      * registered; <code>false</code> otherwise.
227      */

228
229     public static boolean registerService(PrintService JavaDoc service) {
230     synchronized (PrintServiceLookup JavaDoc.class) {
231         if (service instanceof StreamPrintService JavaDoc) {
232         return false;
233         }
234         ArrayList JavaDoc registeredServices = getRegisteredServices();
235         if (registeredServices == null) {
236         registeredServices = initRegisteredServices();
237         }
238         else {
239           if (registeredServices.contains(service)) {
240         return false;
241           }
242         }
243         registeredServices.add(service);
244         return true;
245     }
246     }
247
248
249    /**
250     * Locates services that can be positively confirmed to support
251     * the combination of attributes and DocFlavors specified.
252     * This method is not called directly by applications.
253     * <p>
254     * Implemented by a service provider, used by the static methods
255     * of this class.
256     * <p>
257     * The results should be the same as obtaining all the PrintServices
258     * and querying each one individually on its support for the
259     * specified attributes and flavors, but the process can be more
260     * efficient by taking advantage of the capabilities of lookup services
261     * for the print services.
262     *
263     * @param flavor of document required. If null it is ignored.
264     * @param attributes required to be supported. If null this
265     * constraint is not used.
266     * @return array of matching PrintServices. If no services match, the
267     * array is zero-length.
268     */

269     public abstract PrintService JavaDoc[] getPrintServices(DocFlavor JavaDoc flavor,
270                             AttributeSet JavaDoc attributes);
271     
272     /**
273      * Not called directly by applications.
274      * Implemented by a service provider, used by the static methods
275      * of this class.
276      * @return array of all PrintServices known to this lookup service
277      * class. If none are found, the array is zero-length.
278      */

279     public abstract PrintService JavaDoc[] getPrintServices() ;
280     
281        
282    /**
283     * Not called directly by applications.
284     * <p>
285     * Implemented by a service provider, used by the static methods
286     * of this class.
287     * <p>
288     * Locates MultiDoc print services which can be positively confirmed
289     * to support the combination of attributes and DocFlavors specified.
290     * <p>
291     *
292     * @param flavors of documents required. If null or empty it is ignored.
293     * @param attributes required to be supported. If null this
294      * constraint is not used.
295     * @return array of matching PrintServices. If no services match, the
296     * array is zero-length.
297     */

298     public abstract MultiDocPrintService JavaDoc[]
299     getMultiDocPrintServices(DocFlavor JavaDoc[] flavors,
300                  AttributeSet JavaDoc attributes);
301     
302     /**
303      * Not called directly by applications.
304      * Implemented by a service provider, and called by the print lookup
305      * service
306      * @return the default PrintService for this lookup service.
307      * If there is no default, returns null.
308      */

309     public abstract PrintService JavaDoc getDefaultPrintService();
310     
311     private static ArrayList JavaDoc getAllLookupServices() {
312     synchronized (PrintServiceLookup JavaDoc.class) {
313         ArrayList JavaDoc listOfLookupServices = getListOfLookupServices();
314         if (listOfLookupServices != null) {
315         return listOfLookupServices;
316         } else {
317         listOfLookupServices = initListOfLookupServices();
318         }
319         try {
320         java.security.AccessController.doPrivileged(
321              new java.security.PrivilegedExceptionAction JavaDoc() {
322                         public Object JavaDoc run() {
323                 Iterator JavaDoc iterator =
324                 Service.providers(PrintServiceLookup JavaDoc.class);
325                 ArrayList JavaDoc los = getListOfLookupServices();
326                 while (iterator.hasNext()) {
327                 try {
328                     PrintServiceLookup JavaDoc lus =
329                     (PrintServiceLookup JavaDoc)iterator.next();
330                     los.add(lus);
331                 } catch (Exception JavaDoc e) {
332                 }
333                 }
334                 return null;
335             }
336         });
337         } catch (java.security.PrivilegedActionException JavaDoc e) {
338         }
339
340         return listOfLookupServices;
341     }
342     }
343
344     private static ArrayList JavaDoc getServices(DocFlavor JavaDoc flavor,
345                      AttributeSet JavaDoc attributes) {
346     
347     ArrayList JavaDoc listOfServices = new ArrayList JavaDoc();
348     Iterator JavaDoc psIterator = getAllLookupServices().iterator();
349     while (psIterator.hasNext()) {
350         try {
351         PrintServiceLookup JavaDoc lus = (PrintServiceLookup JavaDoc)psIterator.next();
352         PrintService JavaDoc[] services=null;
353         if (flavor == null && attributes == null) {
354             try {
355             services = lus.getPrintServices();
356             } catch (Throwable JavaDoc tr) {
357             }
358         } else {
359             services = lus.getPrintServices(flavor, attributes);
360         }
361         if (services == null) {
362             continue;
363         }
364         for (int i=0; i<services.length; i++) {
365             listOfServices.add(services[i]);
366         }
367         } catch (Exception JavaDoc e) {
368         }
369     }
370     /* add any directly registered services */
371     ArrayList JavaDoc registeredServices = null;
372     try {
373       SecurityManager JavaDoc security = System.getSecurityManager();
374       if (security != null) {
375         security.checkPrintJobAccess();
376       }
377       registeredServices = getRegisteredServices();
378     } catch (SecurityException JavaDoc se) {
379     }
380     if (registeredServices != null) {
381         PrintService JavaDoc[] services = (PrintService JavaDoc[])
382         registeredServices.toArray(
383                new PrintService JavaDoc[registeredServices.size()]);
384         for (int i=0; i<services.length; i++) {
385         if (!listOfServices.contains(services[i])) {
386             if (flavor == null && attributes == null) {
387             listOfServices.add(services[i]);
388             } else if (((flavor != null &&
389                  services[i].isDocFlavorSupported(flavor)) ||
390                 flavor == null) &&
391                    null == services[i].getUnsupportedAttributes(
392                               flavor, attributes)) {
393             listOfServices.add(services[i]);
394             }
395         }
396         }
397     }
398     return listOfServices;
399     }
400     
401     private static ArrayList JavaDoc getMultiDocServices(DocFlavor JavaDoc[] flavors,
402                          AttributeSet JavaDoc attributes) {
403     
404
405     ArrayList JavaDoc listOfServices = new ArrayList JavaDoc();
406     Iterator JavaDoc psIterator = getAllLookupServices().iterator();
407     while (psIterator.hasNext()) {
408         try {
409         PrintServiceLookup JavaDoc lus = (PrintServiceLookup JavaDoc)psIterator.next();
410         MultiDocPrintService JavaDoc[] services =
411             lus.getMultiDocPrintServices(flavors, attributes);
412         if (services == null) {
413             continue;
414         }
415         for (int i=0; i<services.length; i++) {
416             listOfServices.add(services[i]);
417         }
418         } catch (Exception JavaDoc e) {
419         }
420     }
421     /* add any directly registered services */
422     ArrayList JavaDoc registeredServices = null;
423     try {
424       SecurityManager JavaDoc security = System.getSecurityManager();
425       if (security != null) {
426         security.checkPrintJobAccess();
427       }
428       registeredServices = getRegisteredServices();
429     } catch (Exception JavaDoc e) {
430     }
431     if (registeredServices != null) {
432         PrintService JavaDoc[] services = (PrintService JavaDoc[])
433         registeredServices.toArray(
434                new PrintService JavaDoc[registeredServices.size()]);
435         for (int i=0; i<services.length; i++) {
436         if (services[i] instanceof MultiDocPrintService JavaDoc &&
437             !listOfServices.contains(services[i])) {
438             if (flavors == null || flavors.length == 0) {
439             listOfServices.add(services[i]);
440             } else {
441             boolean supported = true;
442             for (int f=0; f<flavors.length; f++) {
443                 if (services[i].isDocFlavorSupported(flavors[f])) {
444        
445                 if (services[i].getUnsupportedAttributes(
446                      flavors[f], attributes) != null) {
447                         supported = false;
448                     break;
449                 }
450                 } else {
451                 supported = false;
452                 break;
453                 }
454             }
455             if (supported) {
456                 listOfServices.add(services[i]);
457             }
458             }
459         }
460         }
461     }
462     return listOfServices;
463     }
464
465 }
466
467
Popular Tags