< prev index next >

src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java

Print this page




  79              * When it returns an instance of this class will have
  80              * been instantiated - else there's a JDK internal error.
  81              */
  82             PrintServiceLookup.lookupDefaultPrintService();
  83         }
  84         return win32PrintLUS;
  85     }
  86 
  87     public PrintServiceLookupProvider() {
  88 
  89         if (win32PrintLUS == null) {
  90             win32PrintLUS = this;
  91 
  92             String osName = AccessController.doPrivileged(
  93                 new sun.security.action.GetPropertyAction("os.name"));
  94             // There's no capability for Win98 to refresh printers.
  95             // See "OpenPrinter" for more info.
  96             if (osName != null && osName.startsWith("Windows 98")) {
  97                 return;
  98             }
  99             // start the printer listener thread
 100             Thread thr = new Thread(null, new PrinterChangeListener(),
 101                                     "PrinterListener", 0, false);
 102             thr.setDaemon(true);
 103             thr.start();






 104         } /* else condition ought to never happen! */
 105     }
 106 
 107     /* Want the PrintService which is default print service to have
 108      * equality of reference with the equivalent in list of print services
 109      * This isn't required by the API and there's a risk doing this will
 110      * lead people to assume its guaranteed.
 111      */
 112     public synchronized PrintService[] getPrintServices() {
 113         SecurityManager security = System.getSecurityManager();
 114         if (security != null) {
 115             security.checkPrintJobAccess();
 116         }
 117         if (printServices == null) {
 118             refreshServices();
 119         }
 120         return printServices;
 121     }
 122 
 123     private synchronized void refreshServices() {


 299 
 300          // Not the same as default so proceed to get new PrintService.
 301 
 302         // clear defaultPrintService
 303         defaultPrintService = null;
 304 
 305         if (printServices != null) {
 306             for (int j=0; j<printServices.length; j++) {
 307                 if (defaultPrinter.equals(printServices[j].getName())) {
 308                     defaultPrintService = printServices[j];
 309                     break;
 310                 }
 311             }
 312         }
 313 
 314         if (defaultPrintService == null) {
 315             defaultPrintService = new Win32PrintService(defaultPrinter);
 316         }
 317         return defaultPrintService;
 318     }
 319 
 320     class PrinterChangeListener implements Runnable {
 321         long chgObj;
 322         PrinterChangeListener() {
 323             chgObj = notifyFirstPrinterChange(null);
 324         }
 325 
 326         @Override
 327         public void run() {
 328             if (chgObj != -1) {
 329                 while (true) {
 330                     // wait for configuration to change
 331                     if (notifyPrinterChange(chgObj) != 0) {
 332                         try {
 333                             refreshServices();
 334                         } catch (SecurityException se) {
 335                             break;
 336                         }
 337                     } else {
 338                         notifyClosePrinterChange(chgObj);
 339                         break;
 340                     }
 341                 }
 342             }
 343         }
 344     }
 345 

































































 346     private native String getDefaultPrinterName();
 347     private native String[] getAllPrinterNames();
 348     private native long notifyFirstPrinterChange(String printer);
 349     private native void notifyClosePrinterChange(long chgObj);
 350     private native int notifyPrinterChange(long chgObj);

 351 }


  79              * When it returns an instance of this class will have
  80              * been instantiated - else there's a JDK internal error.
  81              */
  82             PrintServiceLookup.lookupDefaultPrintService();
  83         }
  84         return win32PrintLUS;
  85     }
  86 
  87     public PrintServiceLookupProvider() {
  88 
  89         if (win32PrintLUS == null) {
  90             win32PrintLUS = this;
  91 
  92             String osName = AccessController.doPrivileged(
  93                 new sun.security.action.GetPropertyAction("os.name"));
  94             // There's no capability for Win98 to refresh printers.
  95             // See "OpenPrinter" for more info.
  96             if (osName != null && osName.startsWith("Windows 98")) {
  97                 return;
  98             }
  99             // start the local printer listener thread
 100             Thread thr = new Thread(null, new PrinterChangeListener(),
 101                                     "PrinterListener", 0, false);
 102             thr.setDaemon(true);
 103             thr.start();
 104 
 105             // start the remote printer listener thread
 106             Thread remThr = new Thread(null, new RemotePrinterChangeListener(),
 107                                     "RemotePrinterListener", 0, false);
 108             remThr.setDaemon(true);
 109             remThr.start();
 110         } /* else condition ought to never happen! */
 111     }
 112 
 113     /* Want the PrintService which is default print service to have
 114      * equality of reference with the equivalent in list of print services
 115      * This isn't required by the API and there's a risk doing this will
 116      * lead people to assume its guaranteed.
 117      */
 118     public synchronized PrintService[] getPrintServices() {
 119         SecurityManager security = System.getSecurityManager();
 120         if (security != null) {
 121             security.checkPrintJobAccess();
 122         }
 123         if (printServices == null) {
 124             refreshServices();
 125         }
 126         return printServices;
 127     }
 128 
 129     private synchronized void refreshServices() {


 305 
 306          // Not the same as default so proceed to get new PrintService.
 307 
 308         // clear defaultPrintService
 309         defaultPrintService = null;
 310 
 311         if (printServices != null) {
 312             for (int j=0; j<printServices.length; j++) {
 313                 if (defaultPrinter.equals(printServices[j].getName())) {
 314                     defaultPrintService = printServices[j];
 315                     break;
 316                 }
 317             }
 318         }
 319 
 320         if (defaultPrintService == null) {
 321             defaultPrintService = new Win32PrintService(defaultPrinter);
 322         }
 323         return defaultPrintService;
 324     }

 325     class PrinterChangeListener implements Runnable {
 326         long chgObj;
 327         PrinterChangeListener() {
 328             chgObj = notifyFirstPrinterChange(null);
 329         }
 330 
 331         @Override
 332         public void run() {
 333             if (chgObj != -1) {
 334                 while (true) {
 335                     // wait for configuration to change
 336                     if (notifyPrinterChange(chgObj) != 0) {
 337                         try {
 338                             refreshServices();
 339                         } catch (SecurityException se) {
 340                             break;
 341                         }
 342                     } else {
 343                         notifyClosePrinterChange(chgObj);
 344                         break;
 345                     }
 346                 }
 347             }
 348         }
 349     }    
 350 
 351     /* Windows provides *PrinterChangeNotification* functions that provides 
 352        information about printer status changes of the local printers but not
 353        network printers.
 354        Alternatively, Windows provides a way thro' which one can get the
 355        network printer status changes by using WMI, RegistryKeyChange combination,
 356        which is a slightly complex mechanism. 
 357        The Windows WMI offers an async and sync method to read thro' registry 
 358        via the WQL query. The async method is considered dangerous as it leaves 
 359        open a channel until we close it. But the async method has the advantage of 
 360        being notified of a change in registry by calling callback without polling for it.
 361        The sync method uses the polling mechanism to notify.
 362        RegistryValueChange cannot be used in combination with WMI to get registry
 363        value change notification because of an error that may be generated because the
 364        scope of the query would be too big to handle(at times).
 365        Hence an alternative mechanism is choosen via the EnumPrinters by polling for the
 366        count of printer status changes(add\remove) and based on it update the printers
 367        list.
 368     */
 369     class RemotePrinterChangeListener implements Runnable {
 370         private static final long DELAY = 1000 * 60 * 4; // 4 min pooling
 371         private String[] prevRemotePrinters;
 372 
 373         RemotePrinterChangeListener() {
 374             prevRemotePrinters = GetRemotePrintersNames();
 375         }
 376 
 377         boolean doCompare(String[] str1, String[] str2) {
 378             if(str1.length != str2.length) {
 379                 return true;
 380             } else {
 381                 for(int i = 0;i < str1.length;i++) {
 382                     for(int j = 0;j < str2.length;j++) {
 383                         if(!str1[i].equals(str2[j])) {
 384                             return true;
 385                         }
 386                     }
 387                 }
 388             }
 389 
 390             return false;
 391         }
 392 
 393         @Override
 394         public void run() {
 395             while(true) {
 396                 String[] currentRemotePrinters = GetRemotePrintersNames();
 397                 if(doCompare(prevRemotePrinters, currentRemotePrinters)) {
 398 
 399                     // updated the printers data
 400                     // printers list now contains both local and network printer data
 401                     refreshServices();
 402 
 403                     // store the current data for next comparison
 404                     prevRemotePrinters = currentRemotePrinters;
 405                 }
 406 
 407                 try {
 408                     Thread.sleep(DELAY);
 409                 } catch (InterruptedException e) {
 410                     break;
 411                 }
 412             }
 413         }
 414     }
 415 
 416     private native String getDefaultPrinterName();
 417     private native String[] getAllPrinterNames();
 418     private native long notifyFirstPrinterChange(String printer);
 419     private native void notifyClosePrinterChange(long chgObj);
 420     private native int notifyPrinterChange(long chgObj);
 421     private native String[] GetRemotePrintersNames();
 422 }
< prev index next >