| /* |
| * 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; |
| } |
| |
| } |