1 /* PrintServiceLookup.java --
2    Copyright (C) 2004, 2006 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package javax.print;
40 
41 import gnu.classpath.ServiceFactory;
42 import gnu.javax.print.CupsPrintServiceLookup;
43 
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.HashSet;
47 import java.util.Iterator;
48 
49 import javax.print.attribute.AttributeSet;
50 
51 
52 /**
53  * <code>PrintServiceLookup</code> implementations provide a way to lookup
54  * print services based on different constraints.
55  * <p>
56  * Implementations are located and loaded automatically through the SPI JAR
57  * file specification. Therefore implementation classes must provide a default
58  * constructor for instantiation. Furthermore, applications are able to
59  * register further instances directly at runtime.
60  * </p><p>
61  * If an SecurityManager is installed implementors should call
62  * <code>checkPrintJobAccess()</code> to disable access for untrusted code.
63  * This check is to be made in every lookup service implementation for
64  * flexibility. Print services registered by applications through
65  * <code>registerService(PrintService)</code> are suppressed in the
66  * lookup results if a security manager is installed and disallows access.
67  * </p>
68  *
69  * @author Michael Koch (konqueror@gmx.de)
70  * @author Wolfgang Baer (WBaer@gmx.de)
71  */
72 public abstract class PrintServiceLookup
73 {
74 
75   private static final CupsPrintServiceLookup systemProvider;
76   private static final HashSet printServices;
77   private static final HashSet printServiceLookups;
78 
79   static
80   {
81     systemProvider = new CupsPrintServiceLookup();
82 
83     printServices = new HashSet();
84     printServiceLookups = new HashSet();
85 
86     // check for service providers
87     Iterator it = ServiceFactory.lookupProviders(PrintServiceLookup.class);
88 
89     while (it.hasNext())
it.next()90       printServiceLookups.add(it.next());
91   }
92 
93   /**
94    * Constructs a <code>PrintServiceLookup</code> object.
95    */
PrintServiceLookup()96   public PrintServiceLookup()
97   {
98     // nothing to do here
99   }
100 
101   /**
102    * Explicitly registers the provided print service lookup implementation.
103    * <p>
104    * The registration will silently fail (returning <code>false</code>) if
105    * the lookup service is already registered or the registration somehow
106    * else fails.
107    * </p>
108    *
109    * @param sp the print service lookup implementation to register.
110    * @return <code>true</code> if registered, <code>false</code> otherwise.
111    */
registerServiceProvider(PrintServiceLookup sp)112   public static boolean registerServiceProvider(PrintServiceLookup sp)
113   {
114     return printServiceLookups.add(sp);
115   }
116 
117   /**
118    * Explicitly registers the provided print service instance.
119    * <p>
120    * The registration will silently fail (returning <code>false</code>) if
121    * the print service instance is already registered or the registration
122    * somehow else fails.
123    * </p>
124    * @param service the single print service to register.
125    * @return <code>true</code> if registered, <code>false</code> otherwise.
126    */
registerService(PrintService service)127   public static boolean registerService(PrintService service)
128   {
129     if (service instanceof StreamPrintService)
130       return false;
131 
132     // security
133     try
134       {
135         SecurityManager sm = System.getSecurityManager();
136         if (sm != null)
137           sm.checkPrintJobAccess();
138 
139         return printServices.add(service);
140       }
141     catch (SecurityException se)
142       {
143         return false;
144       }
145   }
146 
147   /**
148    * Searches print services capable of printing in the given document flavor
149    * which supports the specified printing attributes.
150    *
151    * @param flavor the document flavor to support. If <code>null</code> this
152    * constraint is ignored during lookup.
153    * @param attributes the printing attributes to support. If
154    * <code>null</code> this constraint is ignored during lookup.
155    * @return The resulting available print services, or an array of length 0
156    * if none is found.
157    */
lookupPrintServices(DocFlavor flavor, AttributeSet attributes)158   public static final PrintService[] lookupPrintServices(DocFlavor flavor,
159     AttributeSet attributes)
160   {
161     ArrayList result = new ArrayList();
162 
163     PrintService[] services =
164       systemProvider.getPrintServices(flavor, attributes);
165     result.addAll(Arrays.asList(services));
166 
167     for (Iterator it = printServiceLookups.iterator(); it.hasNext(); )
168       {
169         PrintServiceLookup lookup = (PrintServiceLookup) it.next();
170         services = lookup.getPrintServices(flavor, attributes);
171         result.addAll(Arrays.asList(services));
172       }
173 
174     for (Iterator it = printServices.iterator(); it.hasNext(); )
175       {
176         PrintService service = (PrintService) it.next();
177         if (systemProvider.checkPrintService(flavor, attributes, service))
178           result.add(service);
179       }
180 
181     return (PrintService[]) result.toArray(new PrintService[result.size()]);
182   }
183 
184   /**
185    * Searches print services capable of multi document printing in all of the
186    * given document flavors and supporting the specified printing attributes.
187    *
188    * @param flavors the document flavors to support. If <code>null</code> this
189    * constraint is ignored during lookup.
190    * @param attributes the printing attributes to support. If
191    * <code>null</code> this constraint is ignored during lookup.
192    * @return The resulting available multi document print services, or an
193    * array of length 0 if none is found.
194    */
lookupMultiDocPrintServices( DocFlavor[] flavors, AttributeSet attributes)195   public static final MultiDocPrintService[] lookupMultiDocPrintServices(
196     DocFlavor[] flavors, AttributeSet attributes)
197   {
198     ArrayList result = new ArrayList();
199 
200     MultiDocPrintService[] services =
201       systemProvider.getMultiDocPrintServices(flavors, attributes);
202     result.addAll(Arrays.asList(services));
203 
204     for (Iterator it = printServiceLookups.iterator(); it.hasNext(); )
205       {
206         PrintServiceLookup lookup = (PrintServiceLookup) it.next();
207         services = lookup.getMultiDocPrintServices(flavors, attributes);
208         result.addAll(Arrays.asList(services));
209       }
210 
211     for (Iterator it = printServices.iterator(); it.hasNext(); )
212       {
213         PrintService service = (PrintService) it.next();
214         if (systemProvider.checkMultiDocPrintService(flavors, attributes, service))
215           result.add(service);
216       }
217 
218     return (MultiDocPrintService[]) result.toArray(
219       new MultiDocPrintService[result.size()]);
220   }
221 
222 
223   /**
224    * Searches the default print service in the current environment.
225    * <p>
226    * If multiple lookup services are registered and each has a default
227    * print service the result is not specified. Usually the default
228    * print service of the native platform lookup service is returned.
229    * </p><p>
230    * The GNU classpath implementation will return the CUPS default
231    * printing service as the default print service, if available.
232    * </p><p>
233    * The default print service may be overriden by users through
234    * the property <code>javax.print.defaultPrinter</code>. A service
235    * specified must be found to be returned as the default.
236    * </p>
237    *
238    * @return The default print service, or <code>null</code> if none found.
239    */
lookupDefaultPrintService()240   public static final PrintService lookupDefaultPrintService()
241   {
242     // TODO Find out what the property controls and use it
243     // String defaultPrinter = System.getProperty("javax.print.defaultPrinter");
244 
245     // first test for platform specified default services
246     PrintService service = systemProvider.getDefaultPrintService();
247 
248     if (service != null)
249       return service;
250 
251     // none available by systemDefaultProvider
252     // search in other registered ones and take first
253     for (Iterator it = printServiceLookups.iterator(); it.hasNext(); )
254       {
255         service = ((PrintServiceLookup) it.next()).getDefaultPrintService();
256         if (service != null)
257           return service;
258       }
259 
260     return null;
261   }
262 
263   /**
264    * Not to be called directly by applications.
265    *
266    * @return The default lookup service of the implementing lookup service or
267    * <code>null</code> if there is no default one.
268    */
getDefaultPrintService()269   public abstract PrintService getDefaultPrintService();
270 
271   /**
272    * Not to be called directly by applications.
273    *
274    * @param flavors the document flavors which have to be supported.
275    * @param attributes the attributes which have to be supported.
276    *
277    * @return The multidoc print services of the implementing lookup service
278    * for the given parameters, or an array of length 0 if none is available.
279    */
280   public abstract MultiDocPrintService[]
getMultiDocPrintServices(DocFlavor[] flavors, AttributeSet attributes)281     getMultiDocPrintServices(DocFlavor[] flavors, AttributeSet attributes);
282 
283   /**
284    * Not to be called directly by applications.
285    *
286    * @return All known print services of the implementing lookup service
287    * regardless of supported features, or an array of length 0 if none is
288    * available.
289    */
getPrintServices()290   public abstract PrintService[] getPrintServices();
291 
292   /**
293    * Not to be called directly by applications.
294    *
295    * @param flavor the document flavor which has to be supported.
296    * @param attributes the attributes which have to be supported.
297    *
298    * @return The print services of the implementing lookup service
299    * for the given parameters, or an array of length 0 if none is available.
300    */
301   public abstract PrintService[]
getPrintServices(DocFlavor flavor, AttributeSet attributes)302     getPrintServices(DocFlavor flavor, AttributeSet attributes);
303 }
304