PageRenderTime 80ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/src/windows/classes/sun/print/Win32PrintServiceLookup.java

https://github.com/ikeji/openjdk7-jdk
Java | 343 lines | 244 code | 39 blank | 60 comment | 84 complexity | 4396a3f7cc4e44b737d1e5a29f1a65ae MD5 | raw file
  1. /*
  2. * Copyright (c) 2000, 2007, Oracle and/or its affiliates. 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. Oracle designates this
  8. * particular file as subject to the "Classpath" exception as provided
  9. * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22. * or visit www.oracle.com if you need additional information or have any
  23. * questions.
  24. */
  25. package sun.print;
  26. import java.io.BufferedReader;
  27. import java.io.InputStream;
  28. import java.io.InputStreamReader;
  29. import java.io.IOException;
  30. import java.util.ArrayList;
  31. import java.security.AccessController;
  32. import java.security.PrivilegedActionException;
  33. import java.security.PrivilegedExceptionAction;
  34. import javax.print.DocFlavor;
  35. import javax.print.MultiDocPrintService;
  36. import javax.print.PrintService;
  37. import javax.print.PrintServiceLookup;
  38. import javax.print.attribute.Attribute;
  39. import javax.print.attribute.AttributeSet;
  40. import javax.print.attribute.HashPrintRequestAttributeSet;
  41. import javax.print.attribute.HashPrintServiceAttributeSet;
  42. import javax.print.attribute.PrintRequestAttribute;
  43. import javax.print.attribute.PrintRequestAttributeSet;
  44. import javax.print.attribute.PrintServiceAttribute;
  45. import javax.print.attribute.PrintServiceAttributeSet;
  46. import javax.print.attribute.standard.PrinterName;
  47. public class Win32PrintServiceLookup extends PrintServiceLookup {
  48. private String defaultPrinter;
  49. private PrintService defaultPrintService;
  50. private String[] printers; /* excludes the default printer */
  51. private PrintService[] printServices; /* includes the default printer */
  52. static {
  53. java.security.AccessController.doPrivileged(
  54. new sun.security.action.LoadLibraryAction("awt"));
  55. }
  56. /* The singleton win32 print lookup service.
  57. * Code that is aware of this field and wants to use it must first
  58. * see if its null, and if so instantiate it by calling a method such as
  59. * javax.print.PrintServiceLookup.defaultPrintService() so that the
  60. * same instance is stored there.
  61. */
  62. private static Win32PrintServiceLookup win32PrintLUS;
  63. /* Think carefully before calling this. Preferably don't call it. */
  64. public static Win32PrintServiceLookup getWin32PrintLUS() {
  65. if (win32PrintLUS == null) {
  66. /* This call is internally synchronized.
  67. * When it returns an instance of this class will have
  68. * been instantiated - else there's a JDK internal error.
  69. */
  70. PrintServiceLookup.lookupDefaultPrintService();
  71. }
  72. return win32PrintLUS;
  73. }
  74. public Win32PrintServiceLookup() {
  75. if (win32PrintLUS == null) {
  76. win32PrintLUS = this;
  77. String osName = AccessController.doPrivileged(
  78. new sun.security.action.GetPropertyAction("os.name"));
  79. // There's no capability for Win98 to refresh printers.
  80. // See "OpenPrinter" for more info.
  81. if (osName != null && osName.startsWith("Windows 98")) {
  82. return;
  83. }
  84. // start the printer listener thread
  85. PrinterChangeListener thr = new PrinterChangeListener();
  86. thr.setDaemon(true);
  87. thr.start();
  88. } /* else condition ought to never happen! */
  89. }
  90. /* Want the PrintService which is default print service to have
  91. * equality of reference with the equivalent in list of print services
  92. * This isn't required by the API and there's a risk doing this will
  93. * lead people to assume its guaranteed.
  94. */
  95. public synchronized PrintService[] getPrintServices() {
  96. SecurityManager security = System.getSecurityManager();
  97. if (security != null) {
  98. security.checkPrintJobAccess();
  99. }
  100. if (printServices == null) {
  101. refreshServices();
  102. }
  103. return printServices;
  104. }
  105. private synchronized void refreshServices() {
  106. printers = getAllPrinterNames();
  107. if (printers == null) {
  108. // In Windows it is safe to assume no default if printers == null so we
  109. // don't get the default.
  110. printServices = new PrintService[0];
  111. return;
  112. }
  113. PrintService[] newServices = new PrintService[printers.length];
  114. PrintService defService = getDefaultPrintService();
  115. for (int p = 0; p < printers.length; p++) {
  116. if (defService != null &&
  117. printers[p].equals(defService.getName())) {
  118. newServices[p] = defService;
  119. } else {
  120. if (printServices == null) {
  121. newServices[p] = new Win32PrintService(printers[p]);
  122. } else {
  123. int j;
  124. for (j = 0; j < printServices.length; j++) {
  125. if ((printServices[j]!= null) &&
  126. (printers[p].equals(printServices[j].getName()))) {
  127. newServices[p] = printServices[j];
  128. printServices[j] = null;
  129. break;
  130. }
  131. }
  132. if (j == printServices.length) {
  133. newServices[p] = new Win32PrintService(printers[p]);
  134. }
  135. }
  136. }
  137. }
  138. // Look for deleted services and invalidate these
  139. if (printServices != null) {
  140. for (int j=0; j < printServices.length; j++) {
  141. if ((printServices[j] instanceof Win32PrintService) &&
  142. (!printServices[j].equals(defaultPrintService))) {
  143. ((Win32PrintService)printServices[j]).invalidateService();
  144. }
  145. }
  146. }
  147. printServices = newServices;
  148. }
  149. public synchronized PrintService getPrintServiceByName(String name) {
  150. if (name == null || name.equals("")) {
  151. return null;
  152. } else {
  153. /* getPrintServices() is now very fast. */
  154. PrintService[] printServices = getPrintServices();
  155. for (int i=0; i<printServices.length; i++) {
  156. if (printServices[i].getName().equals(name)) {
  157. return printServices[i];
  158. }
  159. }
  160. return null;
  161. }
  162. }
  163. boolean matchingService(PrintService service,
  164. PrintServiceAttributeSet serviceSet) {
  165. if (serviceSet != null) {
  166. Attribute [] attrs = serviceSet.toArray();
  167. Attribute serviceAttr;
  168. for (int i=0; i<attrs.length; i++) {
  169. serviceAttr
  170. = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
  171. if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
  172. return false;
  173. }
  174. }
  175. }
  176. return true;
  177. }
  178. public PrintService[] getPrintServices(DocFlavor flavor,
  179. AttributeSet attributes) {
  180. SecurityManager security = System.getSecurityManager();
  181. if (security != null) {
  182. security.checkPrintJobAccess();
  183. }
  184. PrintRequestAttributeSet requestSet = null;
  185. PrintServiceAttributeSet serviceSet = null;
  186. if (attributes != null && !attributes.isEmpty()) {
  187. requestSet = new HashPrintRequestAttributeSet();
  188. serviceSet = new HashPrintServiceAttributeSet();
  189. Attribute[] attrs = attributes.toArray();
  190. for (int i=0; i<attrs.length; i++) {
  191. if (attrs[i] instanceof PrintRequestAttribute) {
  192. requestSet.add(attrs[i]);
  193. } else if (attrs[i] instanceof PrintServiceAttribute) {
  194. serviceSet.add(attrs[i]);
  195. }
  196. }
  197. }
  198. /*
  199. * Special case: If client is asking for a particular printer
  200. * (by name) then we can save time by getting just that service
  201. * to check against the rest of the specified attributes.
  202. */
  203. PrintService[] services = null;
  204. if (serviceSet != null && serviceSet.get(PrinterName.class) != null) {
  205. PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
  206. PrintService service = getPrintServiceByName(name.getValue());
  207. if (service == null || !matchingService(service, serviceSet)) {
  208. services = new PrintService[0];
  209. } else {
  210. services = new PrintService[1];
  211. services[0] = service;
  212. }
  213. } else {
  214. services = getPrintServices();
  215. }
  216. if (services.length == 0) {
  217. return services;
  218. } else {
  219. ArrayList matchingServices = new ArrayList();
  220. for (int i=0; i<services.length; i++) {
  221. try {
  222. if (services[i].
  223. getUnsupportedAttributes(flavor, requestSet) == null) {
  224. matchingServices.add(services[i]);
  225. }
  226. } catch (IllegalArgumentException e) {
  227. }
  228. }
  229. services = new PrintService[matchingServices.size()];
  230. return (PrintService[])matchingServices.toArray(services);
  231. }
  232. }
  233. /*
  234. * return empty array as don't support multi docs
  235. */
  236. public MultiDocPrintService[]
  237. getMultiDocPrintServices(DocFlavor[] flavors,
  238. AttributeSet attributes) {
  239. SecurityManager security = System.getSecurityManager();
  240. if (security != null) {
  241. security.checkPrintJobAccess();
  242. }
  243. return new MultiDocPrintService[0];
  244. }
  245. public synchronized PrintService getDefaultPrintService() {
  246. SecurityManager security = System.getSecurityManager();
  247. if (security != null) {
  248. security.checkPrintJobAccess();
  249. }
  250. // Windows does not have notification for a change in default
  251. // so we always get the latest.
  252. defaultPrinter = getDefaultPrinterName();
  253. if (defaultPrinter == null) {
  254. return null;
  255. }
  256. if ((defaultPrintService != null) &&
  257. defaultPrintService.getName().equals(defaultPrinter)) {
  258. return defaultPrintService;
  259. }
  260. // Not the same as default so proceed to get new PrintService.
  261. // clear defaultPrintService
  262. defaultPrintService = null;
  263. if (printServices != null) {
  264. for (int j=0; j<printServices.length; j++) {
  265. if (defaultPrinter.equals(printServices[j].getName())) {
  266. defaultPrintService = printServices[j];
  267. break;
  268. }
  269. }
  270. }
  271. if (defaultPrintService == null) {
  272. defaultPrintService = new Win32PrintService(defaultPrinter);
  273. }
  274. return defaultPrintService;
  275. }
  276. class PrinterChangeListener extends Thread {
  277. long chgObj;
  278. PrinterChangeListener() {
  279. chgObj = notifyFirstPrinterChange(null);
  280. }
  281. public void run() {
  282. if (chgObj != -1) {
  283. while (true) {
  284. // wait for configuration to change
  285. if (notifyPrinterChange(chgObj) != 0) {
  286. try {
  287. refreshServices();
  288. } catch (SecurityException se) {
  289. break;
  290. }
  291. } else {
  292. notifyClosePrinterChange(chgObj);
  293. break;
  294. }
  295. }
  296. }
  297. }
  298. }
  299. private native String getDefaultPrinterName();
  300. private native String[] getAllPrinterNames();
  301. private native long notifyFirstPrinterChange(String printer);
  302. private native void notifyClosePrinterChange(long chgObj);
  303. private native int notifyPrinterChange(long chgObj);
  304. }