< prev index next >

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

Print this page




  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 
  26 package sun.print;
  27 
  28 import java.security.AccessController;
  29 import java.util.ArrayList;

  30 import javax.print.DocFlavor;
  31 import javax.print.MultiDocPrintService;
  32 import javax.print.PrintService;
  33 import javax.print.PrintServiceLookup;
  34 import javax.print.attribute.Attribute;
  35 import javax.print.attribute.AttributeSet;
  36 import javax.print.attribute.HashPrintRequestAttributeSet;
  37 import javax.print.attribute.HashPrintServiceAttributeSet;
  38 import javax.print.attribute.PrintRequestAttribute;
  39 import javax.print.attribute.PrintRequestAttributeSet;
  40 import javax.print.attribute.PrintServiceAttribute;
  41 import javax.print.attribute.PrintServiceAttributeSet;
  42 import javax.print.attribute.standard.PrinterName;
  43 
  44 public class PrintServiceLookupProvider extends PrintServiceLookup {
  45 
  46     private String defaultPrinter;
  47     private PrintService defaultPrintService;
  48     private String[] printers; /* excludes the default printer */
  49     private PrintService[] printServices; /* includes the default printer */
  50     private static boolean pollServices = true;
  51     private static final int DEFAULT_MINREFRESH = 240;  // 4 minutes
  52     private static int minRefreshTime = DEFAULT_MINREFRESH;


  53 
  54     static {
  55         /* The system property "sun.java2d.print.polling"
  56          * can be used to force the printing code to poll or not poll
  57          * for PrintServices.
  58          */
  59         String pollStr = java.security.AccessController.doPrivileged(
  60             new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));
  61 
  62         if (pollStr != null) {
  63             if (pollStr.equalsIgnoreCase("false")) {
  64                 pollServices = false;
  65             }
  66         }
  67 
  68         /* The system property "sun.java2d.print.minRefreshTime"
  69          * can be used to specify minimum refresh time (in seconds)
  70          * for polling PrintServices.  The default is 240.
  71          */
  72         String refreshTimeStr = java.security.AccessController.doPrivileged(
  73             new sun.security.action.GetPropertyAction(
  74                 "sun.java2d.print.minRefreshTime"));
  75 
  76         if (refreshTimeStr != null) {
  77             try {
  78                 minRefreshTime = Integer.parseInt(refreshTimeStr);
  79             } catch (NumberFormatException e) {
  80                 // ignore
  81             }
  82             if (minRefreshTime < DEFAULT_MINREFRESH) {
  83                 minRefreshTime = DEFAULT_MINREFRESH;
  84             }
  85         }
  86 
  87         java.security.AccessController.doPrivileged(
  88             new java.security.PrivilegedAction<Void>() {
  89                 public Void run() {
  90                     System.loadLibrary("awt");
  91                     return null;
  92                 }
  93             });
  94     }
  95 











  96     /* The singleton win32 print lookup service.
  97      * Code that is aware of this field and wants to use it must first
  98      * see if its null, and if so instantiate it by calling a method such as
  99      * javax.print.PrintServiceLookup.defaultPrintService() so that the
 100      * same instance is stored there.
 101      */
 102     private static PrintServiceLookupProvider win32PrintLUS;
 103 
 104     /* Think carefully before calling this. Preferably don't call it. */
 105     public static PrintServiceLookupProvider getWin32PrintLUS() {
 106         if (win32PrintLUS == null) {
 107             /* This call is internally synchronized.
 108              * When it returns an instance of this class will have
 109              * been instantiated - else there's a JDK internal error.
 110              */
 111             PrintServiceLookup.lookupDefaultPrintService();
 112         }
 113         return win32PrintLUS;
 114     }
 115 


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


  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 
  26 package sun.print;
  27 
  28 import java.security.AccessController;
  29 import java.util.ArrayList;
  30 import java.util.Arrays;
  31 import javax.print.DocFlavor;
  32 import javax.print.MultiDocPrintService;
  33 import javax.print.PrintService;
  34 import javax.print.PrintServiceLookup;
  35 import javax.print.attribute.Attribute;
  36 import javax.print.attribute.AttributeSet;
  37 import javax.print.attribute.HashPrintRequestAttributeSet;
  38 import javax.print.attribute.HashPrintServiceAttributeSet;
  39 import javax.print.attribute.PrintRequestAttribute;
  40 import javax.print.attribute.PrintRequestAttributeSet;
  41 import javax.print.attribute.PrintServiceAttribute;
  42 import javax.print.attribute.PrintServiceAttributeSet;
  43 import javax.print.attribute.standard.PrinterName;
  44 
  45 public class PrintServiceLookupProvider extends PrintServiceLookup {
  46 
  47     private String defaultPrinter;
  48     private PrintService defaultPrintService;
  49     private String[] printers; /* excludes the default printer */
  50     private PrintService[] printServices; /* includes the default printer */
  51 
  52     private static final int DEFAULT_REFRESH_TIME = 240;  // 4 minutes
  53     private static final int MINIMUM_REFRESH_TIME = 120;  // 2 minutes
  54     private static final boolean pollServices;
  55     private static final int refreshTime;
  56 
  57     static {
  58         /* The system property "sun.java2d.print.polling"
  59          * can be used to force the printing code to poll or not poll
  60          * for PrintServices.
  61          */
  62         String pollStr = java.security.AccessController.doPrivileged(
  63             new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));
  64         pollServices = !("false".equalsIgnoreCase(pollStr));





  65 
  66         /* The system property "sun.java2d.print.minRefreshTime"
  67          * can be used to specify minimum refresh time (in seconds)
  68          * for polling PrintServices.  The default is 240.
  69          */
  70         String refreshTimeStr = java.security.AccessController.doPrivileged(
  71             new sun.security.action.GetPropertyAction(
  72                 "sun.java2d.print.minRefreshTime"));
  73         refreshTime = (refreshTimeStr != null)
  74                       ? getRefreshTime(refreshTimeStr)
  75                       : DEFAULT_REFRESH_TIME;








  76 
  77         java.security.AccessController.doPrivileged(
  78             new java.security.PrivilegedAction<Void>() {
  79                 public Void run() {
  80                     System.loadLibrary("awt");
  81                     return null;
  82                 }
  83             });
  84     }
  85 
  86     private static int getRefreshTime(final String refreshTimeStr) {
  87         try {
  88             int minRefreshTime = Integer.parseInt(refreshTimeStr);
  89             return (minRefreshTime < MINIMUM_REFRESH_TIME)
  90                    ? MINIMUM_REFRESH_TIME
  91                    : minRefreshTime;
  92         } catch (NumberFormatException e) {
  93             return DEFAULT_REFRESH_TIME;
  94         }
  95     }
  96 
  97     /* The singleton win32 print lookup service.
  98      * Code that is aware of this field and wants to use it must first
  99      * see if its null, and if so instantiate it by calling a method such as
 100      * javax.print.PrintServiceLookup.defaultPrintService() so that the
 101      * same instance is stored there.
 102      */
 103     private static PrintServiceLookupProvider win32PrintLUS;
 104 
 105     /* Think carefully before calling this. Preferably don't call it. */
 106     public static PrintServiceLookupProvider getWin32PrintLUS() {
 107         if (win32PrintLUS == null) {
 108             /* This call is internally synchronized.
 109              * When it returns an instance of this class will have
 110              * been instantiated - else there's a JDK internal error.
 111              */
 112             PrintServiceLookup.lookupDefaultPrintService();
 113         }
 114         return win32PrintLUS;
 115     }
 116 


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


































 408         @Override
 409         public void run() {
 410             // Init the list of remote printers
 411             prevRemotePrinters = getRemotePrintersNames();
 412 
 413             while (true) {
 414                 try {
 415                     Thread.sleep(refreshTime * 1000);
 416                 } catch (InterruptedException e) {
 417                     break;
 418                 }
 419 
 420                 String[] currentRemotePrinters = getRemotePrintersNames();
 421                 if (!Arrays.equals(prevRemotePrinters, currentRemotePrinters)) {
 422                     // The list of remote printers got updated,
 423                     // so update the cached list printers which
 424                     // includes both local and network printers
 425                     refreshServices();
 426 
 427                     // store the current data for next comparison
 428                     prevRemotePrinters = currentRemotePrinters;
 429                 }
 430             }
 431         }
 432     }
 433 
 434     private native String getDefaultPrinterName();
 435     private native String[] getAllPrinterNames();
 436     private native long notifyFirstPrinterChange(String printer);
 437     private native void notifyClosePrinterChange(long chgObj);
 438     private native int notifyPrinterChange(long chgObj);
 439     private native String[] getRemotePrintersNames();
 440 }
< prev index next >