Source for javax.print.PrintServiceLookup

   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())
  90:       printServiceLookups.add(it.next());
  91:   }
  92: 
  93:   /**
  94:    * Constructs a <code>PrintServiceLookup</code> object.
  95:    */
  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:    */
 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: }