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

Save This Page
Home » openjdk-7 » javax » print » [javadoc | source]