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