< prev index next >

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

Print this page




 386 
 387     /* Windows provides *PrinterChangeNotification* functions that provides
 388        information about printer status changes of the local printers but not
 389        network printers.
 390        Alternatively, Windows provides a way thro' which one can get the
 391        network printer status changes by using WMI, RegistryKeyChange combination,
 392        which is a slightly complex mechanism.
 393        The Windows WMI offers an async and sync method to read thro' registry
 394        via the WQL query. The async method is considered dangerous as it leaves
 395        open a channel until we close it. But the async method has the advantage of
 396        being notified of a change in registry by calling callback without polling for it.
 397        The sync method uses the polling mechanism to notify.
 398        RegistryValueChange cannot be used in combination with WMI to get registry
 399        value change notification because of an error that may be generated because the
 400        scope of the query would be too big to handle(at times).
 401        Hence an alternative mechanism is choosen via the EnumPrinters by polling for the
 402        count of printer status changes(add\remove) and based on it update the printers
 403        list.
 404     */
 405     class RemotePrinterChangeListener implements Runnable {
 406         private String[] prevRemotePrinters;
 407 
 408         RemotePrinterChangeListener() {
 409             prevRemotePrinters = getRemotePrintersNames();
 410         }
 411 
 412         boolean doCompare(String[] str1, String[] str2) {






 413             if (str1.length != str2.length) {
 414                 return true;
 415             } else {
 416                 for (int i = 0;i < str1.length;i++) {
 417                     for (int j = 0;j < str2.length;j++) {












 418                         if (!str1[i].equals(str2[j])) {
 419                             return true;
 420                         }
 421                     }
 422                 }
 423             }
 424 
 425             return false;
 426         }
 427 
 428         @Override
 429         public void run() {
 430             while (true) {

 431                 String[] currentRemotePrinters = getRemotePrintersNames();
 432                 if (doCompare(prevRemotePrinters, currentRemotePrinters)) {
 433 
 434                     // updated the printers data
 435                     // printers list now contains both local and network printer data
 436                     refreshServices();
 437 
 438                     // store the current data for next comparison
 439                     prevRemotePrinters = currentRemotePrinters;



 440                 }
 441 
 442                 try {
 443                     Thread.sleep(minRefreshTime * 1000);
 444                 } catch (InterruptedException e) {
 445                     break;
 446                 }
 447             }
 448         }
 449     }
 450 
 451     private native String getDefaultPrinterName();
 452     private native String[] getAllPrinterNames();
 453     private native long notifyFirstPrinterChange(String printer);
 454     private native void notifyClosePrinterChange(long chgObj);
 455     private native int notifyPrinterChange(long chgObj);
 456     private native String[] getRemotePrintersNames();
 457 }


 386 
 387     /* Windows provides *PrinterChangeNotification* functions that provides
 388        information about printer status changes of the local printers but not
 389        network printers.
 390        Alternatively, Windows provides a way thro' which one can get the
 391        network printer status changes by using WMI, RegistryKeyChange combination,
 392        which is a slightly complex mechanism.
 393        The Windows WMI offers an async and sync method to read thro' registry
 394        via the WQL query. The async method is considered dangerous as it leaves
 395        open a channel until we close it. But the async method has the advantage of
 396        being notified of a change in registry by calling callback without polling for it.
 397        The sync method uses the polling mechanism to notify.
 398        RegistryValueChange cannot be used in combination with WMI to get registry
 399        value change notification because of an error that may be generated because the
 400        scope of the query would be too big to handle(at times).
 401        Hence an alternative mechanism is choosen via the EnumPrinters by polling for the
 402        count of printer status changes(add\remove) and based on it update the printers
 403        list.
 404     */
 405     class RemotePrinterChangeListener implements Runnable {
 406         private String[] prevRemotePrinters = null;
 407 
 408         RemotePrinterChangeListener() {
 409             prevRemotePrinters = getRemotePrintersNames();
 410         }
 411 
 412         boolean doCompare(String[] str1, String[] str2) {
 413             if (str1 == null && str2 == null) {
 414                 return false;
 415             } else if (str1 == null || str2 == null) {
 416                 return true;
 417             }
 418 
 419             if (str1.length != str2.length) {
 420                 return true;
 421             } else {
 422                 for (int i = 0;i < str1.length;i++) {
 423                     for (int j = 0;j < str2.length;j++) {
 424                         // skip if both are nulls
 425                         if (str1[i] == null && str2[j] == null) {
 426                             continue;
 427                         }
 428 
 429                         // return true if there is a 'difference' but
 430                         // no need to access the individual string
 431                         if (str1[i] == null || str2[j] == null) {
 432                             return true;
 433                         }
 434 
 435                         // do comparison only if they are non-nulls
 436                         if (!str1[i].equals(str2[j])) {
 437                             return true;
 438                         }
 439                     }
 440                 }
 441             }
 442 
 443             return false;
 444         }
 445 
 446         @Override
 447         public void run() {
 448             while (true) {
 449                 if (prevRemotePrinters != null && prevRemotePrinters.length > 0) {
 450                     String[] currentRemotePrinters = getRemotePrintersNames();
 451                     if (doCompare(prevRemotePrinters, currentRemotePrinters)) {
 452 
 453                         // updated the printers data
 454                         // printers list now contains both local and network printer data
 455                         refreshServices();
 456 
 457                         // store the current data for next comparison
 458                         prevRemotePrinters = currentRemotePrinters;
 459                     }
 460                 } else {
 461                     prevRemotePrinters = getRemotePrintersNames();
 462                 }
 463 
 464                 try {
 465                     Thread.sleep(minRefreshTime * 1000);
 466                 } catch (InterruptedException e) {
 467                     break;
 468                 }
 469             }
 470         }
 471     }
 472 
 473     private native String getDefaultPrinterName();
 474     private native String[] getAllPrinterNames();
 475     private native long notifyFirstPrinterChange(String printer);
 476     private native void notifyClosePrinterChange(long chgObj);
 477     private native int notifyPrinterChange(long chgObj);
 478     private native String[] getRemotePrintersNames();
 479 }
< prev index next >