From f10a91610fc25c80f9d607ee66109683b57cd0f0 Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Mon, 20 Jan 2014 09:20:13 +0100 Subject: [PATCH] 8031134: PPC64: implement printing on AIX Reviewed-by: prr --- .../classes/sun/print/UnixPrintService.java | 78 ++++++++++++++++++ .../sun/print/UnixPrintServiceLookup.java | 81 ++++++++++++++++++- 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/jdk/src/solaris/classes/sun/print/UnixPrintService.java b/jdk/src/solaris/classes/sun/print/UnixPrintService.java index 30b8dd03082..bb9a6dfce58 100644 --- a/jdk/src/solaris/classes/sun/print/UnixPrintService.java +++ b/jdk/src/solaris/classes/sun/print/UnixPrintService.java @@ -28,6 +28,7 @@ package sun.print; 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 @@ public class UnixPrintService implements PrintService, AttributeUpdater, 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 @@ public class UnixPrintService implements PrintService, AttributeUpdater, 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 @@ public class UnixPrintService implements PrintService, AttributeUpdater, 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 @@ public class UnixPrintService implements PrintService, AttributeUpdater, private PrintServiceAttributeSet getDynamicAttributes() { if (UnixPrintServiceLookup.isSysV()) { return getSysVServiceAttributes(); + } else if (UnixPrintServiceLookup.isAIX()) { + return getAIXServiceAttributes(); } else { return getBSDServiceAttributes(); } diff --git a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java index fb6950b7d0d..13749463cd8 100644 --- a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java +++ b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java @@ -78,6 +78,19 @@ public class UnixPrintServiceLookup extends PrintServiceLookup 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 @@ public class UnixPrintServiceLookup extends PrintServiceLookup 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 @@ public class UnixPrintServiceLookup extends PrintServiceLookup 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 @@ public class UnixPrintServiceLookup extends PrintServiceLookup } else { if (isMac() || isSysV()) { printers = getAllPrinterNamesSysV(); + } else if (isAIX()) { + printers = getAllPrinterNamesAIX(); } else { //BSD printers = getAllPrinterNamesBSD(); } @@ -435,6 +472,8 @@ public class UnixPrintServiceLookup extends PrintServiceLookup PrintService printer = null; if (isMac() || isSysV()) { printer = getNamedPrinterNameSysV(name); + } else if (isAIX()) { + printer = getNamedPrinterNameAIX(name); } else { printer = getNamedPrinterNameBSD(name); } @@ -600,6 +639,8 @@ public class UnixPrintServiceLookup extends PrintServiceLookup } else { if (isMac() || isSysV()) { defaultPrinter = getDefaultPrinterNameSysV(); + } else if (isAIX()) { + defaultPrinter = getDefaultPrinterNameAIX(); } else { defaultPrinter = getDefaultPrinterNameBSD(); } @@ -774,11 +815,49 @@ public class UnixPrintServiceLookup extends PrintServiceLookup 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 printerNames = new ArrayList(); + 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;