001/* PrintServiceLookup.java -- 002 Copyright (C) 2004, 2006 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package javax.print; 040 041import gnu.classpath.ServiceFactory; 042import gnu.javax.print.CupsPrintServiceLookup; 043 044import java.util.ArrayList; 045import java.util.Arrays; 046import java.util.HashSet; 047import java.util.Iterator; 048 049import javax.print.attribute.AttributeSet; 050 051 052/** 053 * <code>PrintServiceLookup</code> implementations provide a way to lookup 054 * print services based on different constraints. 055 * <p> 056 * Implementations are located and loaded automatically through the SPI JAR 057 * file specification. Therefore implementation classes must provide a default 058 * constructor for instantiation. Furthermore, applications are able to 059 * register further instances directly at runtime. 060 * </p><p> 061 * If an SecurityManager is installed implementors should call 062 * <code>checkPrintJobAccess()</code> to disable access for untrusted code. 063 * This check is to be made in every lookup service implementation for 064 * flexibility. Print services registered by applications through 065 * <code>registerService(PrintService)</code> are suppressed in the 066 * lookup results if a security manager is installed and disallows access. 067 * </p> 068 * 069 * @author Michael Koch (konqueror@gmx.de) 070 * @author Wolfgang Baer (WBaer@gmx.de) 071 */ 072public abstract class PrintServiceLookup 073{ 074 075 private static final CupsPrintServiceLookup systemProvider; 076 private static final HashSet printServices; 077 private static final HashSet printServiceLookups; 078 079 static 080 { 081 systemProvider = new CupsPrintServiceLookup(); 082 083 printServices = new HashSet(); 084 printServiceLookups = new HashSet(); 085 086 // check for service providers 087 Iterator it = ServiceFactory.lookupProviders(PrintServiceLookup.class); 088 089 while (it.hasNext()) 090 printServiceLookups.add(it.next()); 091 } 092 093 /** 094 * Constructs a <code>PrintServiceLookup</code> object. 095 */ 096 public PrintServiceLookup() 097 { 098 // nothing to do here 099 } 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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[] 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 */ 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[] 302 getPrintServices(DocFlavor flavor, AttributeSet attributes); 303}