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) || (str2 == null && str1 != 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 if (!str1[i].equals(str2[j])) {
425 return true;
426 }
427 }
428 }
429 }
430
431 return false;
432 }
433
434 @Override
435 public void run() {
436 while (true) {
437 if (prevRemotePrinters != null) {
438 String[] currentRemotePrinters = getRemotePrintersNames();
439 if (doCompare(prevRemotePrinters, currentRemotePrinters)) {
440
441 // updated the printers data
442 // printers list now contains both local and network printer data
443 refreshServices();
444
445 // store the current data for next comparison
446 prevRemotePrinters = currentRemotePrinters;
447 }
448 } else {
449 prevRemotePrinters = getRemotePrintersNames();
450 }
451
452 try {
453 Thread.sleep(minRefreshTime * 1000);
454 } catch (InterruptedException e) {
455 break;
456 }
457 }
458 }
459 }
460
461 private native String getDefaultPrinterName();
462 private native String[] getAllPrinterNames();
463 private native long notifyFirstPrinterChange(String printer);
464 private native void notifyClosePrinterChange(long chgObj);
465 private native int notifyPrinterChange(long chgObj);
466 private native String[] getRemotePrintersNames();
467 }
|