8031134: PPC64: implement printing on AIX
authorsimonis
Mon, 20 Jan 2014 09:20:13 +0100
changeset 22603 816588059f9d
parent 22602 0d9a07b0d7e9
child 22604 9b394795e216
8031134: PPC64: implement printing on AIX Reviewed-by: prr
jdk/src/solaris/classes/sun/print/UnixPrintService.java
jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java
--- a/jdk/src/solaris/classes/sun/print/UnixPrintService.java	Fri Jan 17 21:54:30 2014 +0100
+++ b/jdk/src/solaris/classes/sun/print/UnixPrintService.java	Mon Jan 20 09:20:13 2014 +0100
@@ -28,6 +28,7 @@
 import java.io.File;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.ArrayList;
 import java.util.Locale;
 
 import javax.print.DocFlavor;
@@ -273,11 +274,58 @@
         return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS ;
     }
 
+    // Filter the list of possible AIX Printers and remove header lines
+    // and extra lines which have been added for remote printers.
+    // 'protected' because this method is also used from UnixPrintServiceLookup.
+    protected static String[] filterPrinterNamesAIX(String[] posPrinters) {
+        ArrayList printers = new ArrayList();
+        String [] splitPart;
+
+        for(int i = 0; i < posPrinters.length; i++) {
+            // Remove the header lines
+            if (posPrinters[i].startsWith("---") ||
+                posPrinters[i].startsWith("Queue") ||
+                posPrinters[i].equals("")) continue;
+
+            // Check if there is a ":" in the end of the first colomn.
+            // This means that it is not a valid printer definition.
+            splitPart = posPrinters[i].split(" ");
+            if(splitPart.length >= 1 && !splitPart[0].trim().endsWith(":")) {
+                printers.add(posPrinters[i]);
+            }
+        }
+
+        return (String[])printers.toArray(new String[printers.size()]);
+    }
+
+    private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsAIX() {
+        // On AIX there should not be a blank after '-a'.
+        String command = "/usr/bin/lpstat -a" + printer;
+        String results[]= UnixPrintServiceLookup.execCmd(command);
+
+        // Remove headers and bogus entries added by remote printers.
+        results = filterPrinterNamesAIX(results);
+
+        if (results != null && results.length > 0) {
+            for (int i = 0; i < results.length; i++) {
+                if (results[i].contains("READY") ||
+                    results[i].contains("RUNNING")) {
+                    return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
+                }
+            }
+        }
+
+        return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
+
+    }
+
     private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
         if (UnixPrintServiceLookup.isSysV()) {
             return getPrinterIsAcceptingJobsSysV();
         } else if (UnixPrintServiceLookup.isBSD()) {
             return getPrinterIsAcceptingJobsBSD();
+        } else if (UnixPrintServiceLookup.isAIX()) {
+            return getPrinterIsAcceptingJobsAIX();
         } else {
             return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
         }
@@ -345,11 +393,32 @@
         return new QueuedJobCount(qlen);
     }
 
+    private QueuedJobCount getQueuedJobCountAIX() {
+        // On AIX there should not be a blank after '-a'.
+        String command = "/usr/bin/lpstat -a" + printer;
+        String results[]=  UnixPrintServiceLookup.execCmd(command);
+
+        // Remove headers and bogus entries added by remote printers.
+        results = filterPrinterNamesAIX(results);
+
+        int qlen = 0;
+        if (results != null && results.length > 0){
+            for (int i = 0; i < results.length; i++) {
+                if (results[i].contains("QUEUED")){
+                    qlen ++;
+                }
+            }
+        }
+        return new QueuedJobCount(qlen);
+    }
+
     private QueuedJobCount getQueuedJobCount() {
         if (UnixPrintServiceLookup.isSysV()) {
             return getQueuedJobCountSysV();
         } else if (UnixPrintServiceLookup.isBSD()) {
             return getQueuedJobCountBSD();
+        } else if (UnixPrintServiceLookup.isAIX()) {
+            return getQueuedJobCountAIX();
         } else {
             return new QueuedJobCount(0);
         }
@@ -369,6 +438,13 @@
         return attrs;
     }
 
+    private PrintServiceAttributeSet getAIXServiceAttributes() {
+        PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
+        attrs.add(getQueuedJobCountAIX());
+        attrs.add(getPrinterIsAcceptingJobsAIX());
+        return attrs;
+    }
+
     private boolean isSupportedCopies(Copies copies) {
         int numCopies = copies.getValue();
         return (numCopies > 0 && numCopies < MAXCOPIES);
@@ -394,6 +470,8 @@
     private PrintServiceAttributeSet getDynamicAttributes() {
         if (UnixPrintServiceLookup.isSysV()) {
             return getSysVServiceAttributes();
+        } else if (UnixPrintServiceLookup.isAIX()) {
+            return getAIXServiceAttributes();
         } else {
             return getBSDServiceAttributes();
         }
--- a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java	Fri Jan 17 21:54:30 2014 +0100
+++ b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java	Mon Jan 20 09:20:13 2014 +0100
@@ -78,6 +78,19 @@
 
     static String osname;
 
+    // List of commands used to deal with the printer queues on AIX
+    String[] lpNameComAix = {
+      "/usr/bin/lsallq",
+      "/usr/bin/lpstat -W -p|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
+      "/usr/bin/lpstat -W -d|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
+      "/usr/bin/lpstat -W -v"
+    };
+    private static final int aix_lsallq = 0;
+    private static final int aix_lpstat_p = 1;
+    private static final int aix_lpstat_d = 2;
+    private static final int aix_lpstat_v = 3;
+    private static int aix_defaultPrinterEnumeration = aix_lsallq;
+
     static {
         /* The system property "sun.java2d.print.polling"
          * can be used to force the printing code to poll or not poll
@@ -114,6 +127,24 @@
 
         osname = java.security.AccessController.doPrivileged(
             new sun.security.action.GetPropertyAction("os.name"));
+
+        /* The system property "sun.java2d.print.aix.lpstat"
+         * can be used to force the usage of 'lpstat -p' to enumerate all
+         * printer queues. By default we use 'lsallq', because 'lpstat -p' can
+         * take lots of time if thousands of printers are attached to a server.
+         */
+        if (isAIX()) {
+            String aixPrinterEnumerator = java.security.AccessController.doPrivileged(
+                new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat"));
+
+            if (aixPrinterEnumerator != null) {
+                if (aixPrinterEnumerator.equalsIgnoreCase("lpstat")) {
+                    aix_defaultPrinterEnumeration = aix_lpstat_p;
+                } else if (aixPrinterEnumerator.equalsIgnoreCase("lsallq")) {
+                    aix_defaultPrinterEnumeration = aix_lsallq;
+                }
+            }
+        }
     }
 
     static boolean isMac() {
@@ -133,6 +164,10 @@
                 osname.contains("OS X"));
     }
 
+    static boolean isAIX() {
+        return osname.equals("AIX");
+    }
+
     static final int UNINITIALIZED = -1;
     static final int BSD_LPD = 0;
     static final int BSD_LPD_NG = 1;
@@ -251,6 +286,8 @@
         } else {
             if (isMac() || isSysV()) {
                 printers = getAllPrinterNamesSysV();
+            } else if (isAIX()) {
+                printers = getAllPrinterNamesAIX();
             } else { //BSD
                 printers = getAllPrinterNamesBSD();
             }
@@ -435,6 +472,8 @@
         PrintService printer = null;
         if (isMac() || isSysV()) {
             printer = getNamedPrinterNameSysV(name);
+        } else if (isAIX()) {
+            printer = getNamedPrinterNameAIX(name);
         } else {
             printer = getNamedPrinterNameBSD(name);
         }
@@ -600,6 +639,8 @@
         } else {
             if (isMac() || isSysV()) {
                 defaultPrinter = getDefaultPrinterNameSysV();
+            } else if (isAIX()) {
+                defaultPrinter = getDefaultPrinterNameAIX();
             } else {
                 defaultPrinter = getDefaultPrinterNameBSD();
             }
@@ -774,11 +815,49 @@
         return (String[])printerNames.toArray(new String[printerNames.size()]);
     }
 
+    private String getDefaultPrinterNameAIX() {
+        String[] names = execCmd(lpNameComAix[aix_lpstat_d]);
+        // Remove headers and bogus entries added by remote printers.
+        names = UnixPrintService.filterPrinterNamesAIX(names);
+        if (names == null || names.length != 1) {
+            // No default printer found
+            return null;
+        } else {
+            return names[0];
+        }
+    }
+
+    private PrintService getNamedPrinterNameAIX(String name) {
+        // On AIX there should be no blank after '-v'.
+        String[] result = execCmd(lpNameComAix[aix_lpstat_v] + name);
+        // Remove headers and bogus entries added by remote printers.
+        result = UnixPrintService.filterPrinterNamesAIX(result);
+        if (result == null || result.length != 1) {
+            return null;
+        } else {
+            return new UnixPrintService(name);
+        }
+    }
+
+    private String[] getAllPrinterNamesAIX() {
+        // Determine all printers of the system.
+        String [] names = execCmd(lpNameComAix[aix_defaultPrinterEnumeration]);
+
+        // Remove headers and bogus entries added by remote printers.
+        names = UnixPrintService.filterPrinterNamesAIX(names);
+
+        ArrayList<String> printerNames = new ArrayList<String>();
+        for ( int i=0; i < names.length; i++) {
+            printerNames.add(names[i]);
+        }
+        return (String[])printerNames.toArray(new String[printerNames.size()]);
+    }
+
     static String[] execCmd(final String command) {
         ArrayList results = null;
         try {
             final String[] cmd = new String[3];
-            if (isSysV()) {
+            if (isSysV() || isAIX()) {
                 cmd[0] = "/usr/bin/sh";
                 cmd[1] = "-c";
                 cmd[2] = "env LC_ALL=C " + command;