235 lines · 9.2 KB · Java
RawDownload
/* * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.print; import java.io.OutputStream; import java.util.ArrayList;import java.util.Iterator; import javax.print.DocFlavor; import sun.awt.AppContext;import java.util.ServiceLoader;import java.util.ServiceConfigurationError; /** * A <code>StreamPrintServiceFactory</code> is the factory for * {@link StreamPrintService} instances, * which can print to an output stream in a particular * document format described as a mime type. * A typical output document format may be Postscript(TM). * <p> * This class is implemented by a service and located by the * implementation using the * <a href="../../../technotes/guides/jar/jar.html#Service Provider"> * SPI JAR File specification</a>. * <p> * Applications locate instances of this class by calling the * {@link #lookupStreamPrintServiceFactories(DocFlavor, String)} method. * <p> * Applications can use a <code>StreamPrintService</code> obtained from a * factory in place of a <code>PrintService</code> which represents a * physical printer device. */ public abstract class StreamPrintServiceFactory {     static class Services {        private ArrayList listOfFactories = null;    }     private static Services getServices() {        Services services =            (Services)AppContext.getAppContext().get(Services.class);        if (services == null) {            services = new Services();            AppContext.getAppContext().put(Services.class, services);        }        return services;    }     private static ArrayList getListOfFactories() {        return getServices().listOfFactories;    }     private static ArrayList initListOfFactories() {        ArrayList listOfFactories = new ArrayList();        getServices().listOfFactories = listOfFactories;        return listOfFactories;    }     /**     * Locates factories for print services that can be used with     * a print job to output a stream of data in the     * format specified by {@code outputMimeType}.     * <p>     * The {@code outputMimeType} parameter describes the document type that     * you want to create, whereas the {@code flavor} parameter describes the     * format in which the input data will be provided by the application     * to the {@code StreamPrintService}.     * <p>     * Although null is an acceptable value to use in the lookup of stream     * printing services, it's typical to search for a particular     * desired format, such as Postscript(TM).     * <p>     * @param flavor of the input document type - null means match all     * types.     * @param outputMimeType representing the required output format, used to     * identify suitable stream printer factories. A value of null means     * match all formats.     * @return - matching factories for stream print service instance,     *           empty if no suitable factories could be located.     */     public static StreamPrintServiceFactory[]         lookupStreamPrintServiceFactories(DocFlavor flavor,                                           String outputMimeType) {          ArrayList list = getFactories(flavor, outputMimeType);         return (StreamPrintServiceFactory[])               (list.toArray(new StreamPrintServiceFactory[list.size()]));     }     /** Queries the factory for the document format that is emitted     * by printers obtained from this factory.     *     * @return the output format described as a mime type.     */    public abstract String getOutputFormat();     /**     * Queries the factory for the document flavors that can be accepted     * by printers obtained from this factory.     * @return array of supported doc flavors.     */    public abstract DocFlavor[] getSupportedDocFlavors();     /**     * Returns a <code>StreamPrintService</code> that can print to     * the specified output stream.     * The output stream is created and managed by the application.     * It is the application's responsibility to close the stream and     * to ensure that this Printer is not reused.     * The application should not close this stream until any print job     * created from the printer is complete. Doing so earlier may generate     * a <code>PrinterException</code> and an event indicating that the     * job failed.     * <p>     * Whereas a <code>PrintService</code> connected to a physical printer     * can be reused,     * a <code>StreamPrintService</code> connected to a stream cannot.     * The underlying <code>StreamPrintService</code> may be disposed by     * the print system with     * the {@link StreamPrintService#dispose() dispose} method     * before returning from the     * {@link DocPrintJob#print(Doc, javax.print.attribute.PrintRequestAttributeSet) print}     * method of <code>DocPrintJob</code> so that the print system knows     * this printer is no longer usable.     * This is equivalent to a physical printer going offline - permanently.     * Applications may supply a null print stream to create a queryable     * service. It is not valid to create a PrintJob for such a stream.     * Implementations which allocate resources on construction should examine     * the stream and may wish to only allocate resources if the stream is     * non-null.     * <p>     * @param out destination stream for generated output.     * @return a PrintService which will generate the format specified by the     * DocFlavor supported by this Factory.     */    public abstract StreamPrintService getPrintService(OutputStream out);      private static ArrayList getAllFactories() {        synchronized (StreamPrintServiceFactory.class) {           ArrayList listOfFactories = getListOfFactories();            if (listOfFactories != null) {                return listOfFactories;            } else {                listOfFactories = initListOfFactories();            }             try {                java.security.AccessController.doPrivileged(                     new java.security.PrivilegedExceptionAction() {                        public Object run() {                            Iterator<StreamPrintServiceFactory> iterator =                                ServiceLoader.load                                (StreamPrintServiceFactory.class).iterator();                            ArrayList lof = getListOfFactories();                            while (iterator.hasNext()) {                                try {                                    lof.add(iterator.next());                                }  catch (ServiceConfigurationError err) {                                     /* In the applet case, we continue */                                    if (System.getSecurityManager() != null) {                                        err.printStackTrace();                                    } else {                                        throw err;                                    }                                }                            }                            return null;                        }                });            } catch (java.security.PrivilegedActionException e) {            }            return listOfFactories;        }    }     private static boolean isMember(DocFlavor flavor, DocFlavor[] flavors) {        for (int f=0; f<flavors.length; f++ ) {            if (flavor.equals(flavors[f])) {                return true;            }        }        return false;    }     private static ArrayList getFactories(DocFlavor flavor, String outType) {         if (flavor == null && outType == null) {            return getAllFactories();        }         ArrayList list = new ArrayList();        Iterator iterator = getAllFactories().iterator();        while (iterator.hasNext()) {            StreamPrintServiceFactory factory =                (StreamPrintServiceFactory)iterator.next();            if ((outType == null ||                 outType.equalsIgnoreCase(factory.getOutputFormat())) &&                (flavor == null ||                 isMember(flavor, factory.getSupportedDocFlavors()))) {                list.add(factory);            }        }         return list;    } }