|
1 /* |
|
2 * Copyright 2000-2007 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 package javax.print; |
|
27 |
|
28 import java.io.OutputStream; |
|
29 |
|
30 import java.util.ArrayList; |
|
31 import java.util.Iterator; |
|
32 |
|
33 import javax.print.DocFlavor; |
|
34 |
|
35 import sun.awt.AppContext; |
|
36 import java.util.ServiceLoader; |
|
37 import java.util.ServiceConfigurationError; |
|
38 |
|
39 /** |
|
40 * A <code>StreamPrintServiceFactory</code> is the factory for |
|
41 * {@link StreamPrintService} instances, |
|
42 * which can print to an output stream in a particular |
|
43 * document format described as a mime type. |
|
44 * A typical output document format may be Postscript(TM). |
|
45 * <p> |
|
46 * This class is implemented by a service and located by the |
|
47 * implementation using the |
|
48 * <a href="../../../technotes/guides/jar/jar.html#Service Provider"> |
|
49 * SPI JAR File specification</a>. |
|
50 * <p> |
|
51 * Applications locate instances of this class by calling the |
|
52 * {@link #lookupStreamPrintServiceFactories(DocFlavor, String)} method. |
|
53 * <p> |
|
54 * Applications can use a <code>StreamPrintService</code> obtained from a |
|
55 * factory in place of a <code>PrintService</code> which represents a |
|
56 * physical printer device. |
|
57 */ |
|
58 |
|
59 public abstract class StreamPrintServiceFactory { |
|
60 |
|
61 static class Services { |
|
62 private ArrayList listOfFactories = null; |
|
63 } |
|
64 |
|
65 private static Services getServices() { |
|
66 Services services = |
|
67 (Services)AppContext.getAppContext().get(Services.class); |
|
68 if (services == null) { |
|
69 services = new Services(); |
|
70 AppContext.getAppContext().put(Services.class, services); |
|
71 } |
|
72 return services; |
|
73 } |
|
74 |
|
75 private static ArrayList getListOfFactories() { |
|
76 return getServices().listOfFactories; |
|
77 } |
|
78 |
|
79 private static ArrayList initListOfFactories() { |
|
80 ArrayList listOfFactories = new ArrayList(); |
|
81 getServices().listOfFactories = listOfFactories; |
|
82 return listOfFactories; |
|
83 } |
|
84 |
|
85 /** |
|
86 * Locates factories for print services that can be used with |
|
87 * a print job to output a stream of data in the |
|
88 * format specified by {@code outputMimeType}. |
|
89 * <p> |
|
90 * The {@code outputMimeType} parameter describes the document type that |
|
91 * you want to create, whereas the {@code flavor} parameter describes the |
|
92 * format in which the input data will be provided by the application |
|
93 * to the {@code StreamPrintService}. |
|
94 * <p> |
|
95 * Although null is an acceptable value to use in the lookup of stream |
|
96 * printing services, it's typical to search for a particular |
|
97 * desired format, such as Postscript(TM). |
|
98 * <p> |
|
99 * @param flavor of the input document type - null means match all |
|
100 * types. |
|
101 * @param outputMimeType representing the required output format, used to |
|
102 * identify suitable stream printer factories. A value of null means |
|
103 * match all formats. |
|
104 * @return - matching factories for stream print service instance, |
|
105 * empty if no suitable factories could be located. |
|
106 */ |
|
107 public static StreamPrintServiceFactory[] |
|
108 lookupStreamPrintServiceFactories(DocFlavor flavor, |
|
109 String outputMimeType) { |
|
110 |
|
111 ArrayList list = getFactories(flavor, outputMimeType); |
|
112 return (StreamPrintServiceFactory[]) |
|
113 (list.toArray(new StreamPrintServiceFactory[list.size()])); |
|
114 } |
|
115 |
|
116 /** Queries the factory for the document format that is emitted |
|
117 * by printers obtained from this factory. |
|
118 * |
|
119 * @return the output format described as a mime type. |
|
120 */ |
|
121 public abstract String getOutputFormat(); |
|
122 |
|
123 /** |
|
124 * Queries the factory for the document flavors that can be accepted |
|
125 * by printers obtained from this factory. |
|
126 * @return array of supported doc flavors. |
|
127 */ |
|
128 public abstract DocFlavor[] getSupportedDocFlavors(); |
|
129 |
|
130 /** |
|
131 * Returns a <code>StreamPrintService</code> that can print to |
|
132 * the specified output stream. |
|
133 * The output stream is created and managed by the application. |
|
134 * It is the application's responsibility to close the stream and |
|
135 * to ensure that this Printer is not reused. |
|
136 * The application should not close this stream until any print job |
|
137 * created from the printer is complete. Doing so earlier may generate |
|
138 * a <code>PrinterException</code> and an event indicating that the |
|
139 * job failed. |
|
140 * <p> |
|
141 * Whereas a <code>PrintService</code> connected to a physical printer |
|
142 * can be reused, |
|
143 * a <code>StreamPrintService</code> connected to a stream cannot. |
|
144 * The underlying <code>StreamPrintService</code> may be disposed by |
|
145 * the print system with |
|
146 * the {@link StreamPrintService#dispose() dispose} method |
|
147 * before returning from the |
|
148 * {@link DocPrintJob#print(Doc, javax.print.attribute.PrintRequestAttributeSet) print} |
|
149 * method of <code>DocPrintJob</code> so that the print system knows |
|
150 * this printer is no longer usable. |
|
151 * This is equivalent to a physical printer going offline - permanently. |
|
152 * Applications may supply a null print stream to create a queryable |
|
153 * service. It is not valid to create a PrintJob for such a stream. |
|
154 * Implementations which allocate resources on construction should examine |
|
155 * the stream and may wish to only allocate resources if the stream is |
|
156 * non-null. |
|
157 * <p> |
|
158 * @param out destination stream for generated output. |
|
159 * @return a PrintService which will generate the format specified by the |
|
160 * DocFlavor supported by this Factory. |
|
161 */ |
|
162 public abstract StreamPrintService getPrintService(OutputStream out); |
|
163 |
|
164 |
|
165 private static ArrayList getAllFactories() { |
|
166 synchronized (StreamPrintServiceFactory.class) { |
|
167 |
|
168 ArrayList listOfFactories = getListOfFactories(); |
|
169 if (listOfFactories != null) { |
|
170 return listOfFactories; |
|
171 } else { |
|
172 listOfFactories = initListOfFactories(); |
|
173 } |
|
174 |
|
175 try { |
|
176 java.security.AccessController.doPrivileged( |
|
177 new java.security.PrivilegedExceptionAction() { |
|
178 public Object run() { |
|
179 Iterator<StreamPrintServiceFactory> iterator = |
|
180 ServiceLoader.load |
|
181 (StreamPrintServiceFactory.class).iterator(); |
|
182 ArrayList lof = getListOfFactories(); |
|
183 while (iterator.hasNext()) { |
|
184 try { |
|
185 lof.add(iterator.next()); |
|
186 } catch (ServiceConfigurationError err) { |
|
187 /* In the applet case, we continue */ |
|
188 if (System.getSecurityManager() != null) { |
|
189 err.printStackTrace(); |
|
190 } else { |
|
191 throw err; |
|
192 } |
|
193 } |
|
194 } |
|
195 return null; |
|
196 } |
|
197 }); |
|
198 } catch (java.security.PrivilegedActionException e) { |
|
199 } |
|
200 return listOfFactories; |
|
201 } |
|
202 } |
|
203 |
|
204 private static boolean isMember(DocFlavor flavor, DocFlavor[] flavors) { |
|
205 for (int f=0; f<flavors.length; f++ ) { |
|
206 if (flavor.equals(flavors[f])) { |
|
207 return true; |
|
208 } |
|
209 } |
|
210 return false; |
|
211 } |
|
212 |
|
213 private static ArrayList getFactories(DocFlavor flavor, String outType) { |
|
214 |
|
215 if (flavor == null && outType == null) { |
|
216 return getAllFactories(); |
|
217 } |
|
218 |
|
219 ArrayList list = new ArrayList(); |
|
220 Iterator iterator = getAllFactories().iterator(); |
|
221 while (iterator.hasNext()) { |
|
222 StreamPrintServiceFactory factory = |
|
223 (StreamPrintServiceFactory)iterator.next(); |
|
224 if ((outType == null || |
|
225 outType.equalsIgnoreCase(factory.getOutputFormat())) && |
|
226 (flavor == null || |
|
227 isMember(flavor, factory.getSupportedDocFlavors()))) { |
|
228 list.add(factory); |
|
229 } |
|
230 } |
|
231 |
|
232 return list; |
|
233 } |
|
234 |
|
235 } |