You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/10/09 07:33:21 UTC
svn commit: r454289 [14/22] - in
/incubator/harmony/enhanced/classlib/trunk/modules/H-1609: ./ modules/
modules/applet/ modules/applet/src/ modules/applet/src/main/
modules/applet/src/main/java/ modules/applet/src/main/java/java/
modules/applet/src/mai...
Added: incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/awt/PSPrinterJob.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/awt/PSPrinterJob.java?view=auto&rev=454289
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/awt/PSPrinterJob.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/awt/PSPrinterJob.java Sun Oct 8 22:33:09 2006
@@ -0,0 +1,619 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Aleksei V. Ivaschenko
+ * @version $Revision: 1.3 $
+ */
+
+package org.apache.harmony.x.print.awt;
+
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.KeyboardFocusManager;
+import java.awt.Rectangle;
+import java.awt.Window;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Paper;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.io.PrintStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Locale;
+
+import javax.print.Doc;
+import javax.print.DocFlavor;
+import javax.print.DocPrintJob;
+import javax.print.PrintException;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.ServiceUI;
+import javax.print.SimpleDoc;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.Size2DSyntax;
+import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.JobName;
+import javax.print.attribute.standard.Media;
+import javax.print.attribute.standard.MediaPrintableArea;
+import javax.print.attribute.standard.MediaSize;
+import javax.print.attribute.standard.MediaSizeName;
+import javax.print.attribute.standard.OrientationRequested;
+import javax.print.attribute.standard.RequestingUserName;
+import javax.swing.JOptionPane;
+
+import org.apache.harmony.x.print.ServiceUIDialog;
+import org.apache.harmony.x.print.attributes.MediaMargins;
+
+
+public class PSPrinterJob extends PrinterJob {
+
+ private Printable psPrintable;
+ private Pageable psDocument;
+ private PageFormat psFormat;
+ private PrintStream stream;
+
+ PrintRequestAttributeSet attrs; // Job attributes
+ private PrintService service = null; // Job print service
+
+ static String os = null; // OS type
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ os = System.getProperty("os.name");
+ if (os.startsWith("Windows")) {
+ System.loadLibrary("print");
+ }
+ return null;
+ }
+ });
+ }
+
+ public PSPrinterJob() {
+ super();
+ attrs = new HashPrintRequestAttributeSet();
+ service = PrintServiceLookup.lookupDefaultPrintService();
+ /* Probably need to add default attributes to attrs here */
+ }
+
+ public void setPrintable(Printable painter) {
+ psPrintable = painter;
+ }
+
+ /*
+ * @see java.awt.print.PrinterJob#setPrintable(Printable, PageFormat)
+ */
+ public void setPrintable(Printable painter, PageFormat format) {
+ psPrintable = painter;
+ psFormat = format;
+ }
+
+ /*
+ * @see java.awt.print.PrinterJob#setPageable(Pageable)
+ */
+ public void setPageable(Pageable document) throws NullPointerException {
+ if (document == null){
+ throw new NullPointerException("Pageable argument is null");
+ }
+ psDocument = document;
+ }
+
+ /*
+ * @see java.awt.print.PrinterJob#print()
+ */
+ public void print() throws PrinterException {
+ Doc doc = null;
+ if (psPrintable != null) {
+ Pageable pageable = new Pageable() {
+ public int getNumberOfPages() {
+ return UNKNOWN_NUMBER_OF_PAGES;
+ }
+ public PageFormat getPageFormat(int pageIndex)
+ throws IndexOutOfBoundsException {
+ return (psFormat != null) ? psFormat : defaultPage();
+ }
+ public Printable getPrintable(int pageIndex)
+ throws IndexOutOfBoundsException {
+ return psPrintable;
+ }
+ };
+
+ doc = new SimpleDoc(pageable,
+ DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
+ } else if (psDocument != null) {
+ doc = new SimpleDoc(psDocument,
+ DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
+ } else {
+ throw new PrinterException("Neither Printable nor Pageable were " +
+ "specified.");
+ }
+
+ PrintService pService = service;
+ if (pService == null) {
+ pService = PrintServiceLookup.lookupDefaultPrintService();
+ }
+
+ try {
+ DocPrintJob job = pService.createPrintJob();
+ job.print(doc, attrs);
+ } catch (PrintException pe) {
+ throw new PrinterException(pe.getMessage());
+ }
+ }
+
+ /*
+ * @see java.awt.print.PrinterJob#print(PrintRequestAttributeSet)
+ */
+ public void print(PrintRequestAttributeSet attributes)
+ throws PrinterException {
+ attrs = attributes;
+ print();
+ }
+
+ public PrintService getPrintService() {
+ return service;
+ }
+
+ public void setPrintService(PrintService printservice)
+ throws PrinterException {
+ if (printservice.isDocFlavorSupported(
+ DocFlavor.SERVICE_FORMATTED.PRINTABLE) &&
+ printservice.isDocFlavorSupported(
+ DocFlavor.SERVICE_FORMATTED.PAGEABLE)) {
+ service = printservice;
+ } else {
+ throw new PrinterException("PrintService doesn't support " +
+ "SERVICE_FORMATTED doc flavors.");
+ }
+ }
+
+ public void setJobName(String jobName) {
+ attrs.add(new JobName(jobName, Locale.getDefault()));
+ }
+
+ public void setCopies(int copies) {
+ attrs.add(new Copies(copies));
+ }
+
+ public int getCopies() {
+ return attrs.containsKey(Copies.class)
+ ? ((Copies) (attrs.get(Copies.class))).getValue()
+ : 1;
+ }
+
+ public String getUserName() {
+ return attrs.containsKey(RequestingUserName.class)
+ ? ((RequestingUserName)(attrs.get(RequestingUserName.class))).
+ getValue()
+ : null;
+ }
+
+ public String getJobName() {
+ return attrs.containsKey(JobName.class)
+ ? ((JobName)(attrs.get(JobName.class))).getValue()
+ : null;
+ }
+
+ /*
+ * This method shows Windows native print dialog on Windows and
+ * javax.print.ServiceUI standard print dialog on Linux. We suppose that on
+ * Linux this dialog should contain the list of native print services only,
+ * however corresponding native agent function is not realized yet.
+ *
+ * Throws HeadlessException if Graphics Environment is headless.
+ */
+ public boolean printDialog() throws HeadlessException {
+ if (GraphicsEnvironment.isHeadless()) {
+ throw new HeadlessException();
+ }
+
+ if (os.startsWith("Windows")) { /* Windows OS */
+
+ /* call Windows native dialog */
+ String res = getPrinter(service.getName(), getCopies());
+
+ if (res != null) {
+ try {
+ setPrintService(findPrintService(res));
+ return true;
+ } catch(PrinterException e) {
+ JOptionPane.showMessageDialog(KeyboardFocusManager
+ .getCurrentKeyboardFocusManager().getActiveWindow(),
+ "Can not set selected printer!",
+ "Incorrect service",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ return false;
+ }
+ /* Linux OS */
+ /*
+ * TODO: Need to create new native agent function which returns
+ * a list of native printers. Need to call javax.print.ServiceUI
+ * print dialog with this native printers list instead of all
+ * registered print services list as it is realized here!
+ */
+ printDialog(attrs);
+ return false;
+ }
+
+ /*
+ * Calls cross-platforms print dialog with all registered print services
+ * (this function just calls ServiceUI.printDialog(...) method with
+ * corresponding parameters).
+ *
+ * Parameters:
+ * attrs - attributes for the dialog
+ *
+ * Throws:
+ * NullPointerException - if attrs is null
+ * HeadlessException - if Graphics Environment is headless
+ */
+ public boolean printDialog(PrintRequestAttributeSet dialogAttrs)
+ throws HeadlessException {
+
+ if (dialogAttrs == null) {
+ throw new NullPointerException();
+ } else if (GraphicsEnvironment.isHeadless()) {
+ throw new HeadlessException();
+ }
+
+ /* Combine this PrinterJob attrs attribute set and printerAttrs set
+ and resolve MediaPrintableArea/MediaMargins conflict if it is
+ needed */
+ PrintRequestAttributeSet sum =
+ updateMediaAndMarginsIfNeeded(dialogAttrs);
+
+ Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration().getBounds();
+
+ /* call cross-platform print dialog */
+ PrintService newSrv = ServiceUI.printDialog(
+ null,
+ screen.width / 3,
+ screen.height / 3,
+ lookupServicesForDialog(),
+ service,
+ DocFlavor.SERVICE_FORMATTED.PRINTABLE,
+ sum);
+
+ if (newSrv!=null) {
+ /* Set selected print service and update attrs attribute set
+ if user clicked "Print" button */
+ try {
+ setPrintService(newSrv);
+ this.attrs.clear();
+ this.attrs.addAll(sum);
+ return true;
+ } catch (PrinterException e) {
+ System.out.println(e);
+ return false;
+ }
+ }
+ return false; /* "Cancel button was pressed */
+ }
+
+ /*
+ * This method calls standard page dialog that allows PageFormat
+ * modification.
+ * Parameters:
+ * page - PageFormat for modification
+ * Returns:
+ * original page if the dialog is cancelled or print service for the
+ * job is not set
+ * new PageFormat object from the dialog if the user click "Print"
+ * button
+ * Throws HeadlessException if Graphics Environment is headless.
+ */
+ public PageFormat pageDialog(PageFormat page)
+ throws HeadlessException {
+ if (getPrintService() == null) {
+ return page;
+ }
+
+ /* get attribute set which combines this job attribute set and
+ attributes for the given page PageFormat */
+ HashPrintRequestAttributeSet myattrs = getAttrsForPageFormat(page);
+ return pageDialog(myattrs);
+ }
+
+ /*
+ * This method calls standard page dialog with the given attribute set
+ * Parameters:
+ * attrs - attribute set for the dialog
+ * Returns:
+ * original page if the dialog is cancelled or print service for the
+ * job is not set
+ * new PageFormat object from the dialog if the user click "Print"
+ * button
+ * Throws:
+ * HeadlessException if Graphics Environment is headless.
+ * NullPointerException if attrs is null
+ */
+ public PageFormat pageDialog(PrintRequestAttributeSet arg_attrs)
+ throws HeadlessException {
+
+ if (GraphicsEnvironment.isHeadless()) {
+ throw new HeadlessException();
+ } else if (arg_attrs == null) {
+ throw new NullPointerException();
+ } else if (getPrintService() == null) {
+ JOptionPane.showMessageDialog(KeyboardFocusManager
+ .getCurrentKeyboardFocusManager().getActiveWindow(),
+ "Print service is not set for the PrinterJob!", "Error!",
+ JOptionPane.ERROR_MESSAGE);
+ return null;
+ }
+
+ Window wnd = KeyboardFocusManager.getCurrentKeyboardFocusManager()
+ .getActiveWindow();
+ Window owner = (((wnd instanceof Dialog)||(wnd instanceof Frame))
+ ? wnd : new Frame());
+
+ /* Combine this PrinterJob this.attrs attribute set and attrs set
+ and resolve MediaPrintableArea/MediaMargins conflict if it is
+ needed */
+ PrintRequestAttributeSet sum = updateMediaAndMarginsIfNeeded(arg_attrs);
+
+ Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration().getBounds();
+
+ /* create and show the page dialog */
+ ServiceUIDialog dialog = new ServiceUIDialog(null,
+ screen.width/3,
+ screen.height/3,
+ getPrintService(),
+ sum,
+ owner);
+ dialog.show();
+
+ if (owner != wnd) {
+ owner.dispose();
+ }
+
+ /* update this.attrs attribute set and result page format to return */
+ if (dialog.getResult() == ServiceUIDialog.APPROVE_PRINT) {
+ PrintRequestAttributeSet newattrs = dialog.getAttributes();
+
+ if (!newattrs.containsKey(Media.class)) {
+ this.attrs.remove(Media.class);
+ }
+ if (!newattrs.containsKey(OrientationRequested.class)) {
+ this.attrs.remove(OrientationRequested.class);
+ }
+ if (!newattrs.containsKey(MediaPrintableArea.class)) {
+ this.attrs.remove(MediaPrintableArea.class);
+ }
+ if (!newattrs.containsKey(MediaMargins.class)) {
+ this.attrs.remove(MediaMargins.class);
+ }
+ this.attrs.addAll(newattrs);
+ return getPageFormatForAttrs(newattrs);
+ }
+
+ return null;
+
+ }
+
+ /*
+ * Returns this printer job's attribute set
+ */
+ public PrintRequestAttributeSet getAttributes() {
+ return attrs;
+ }
+
+ /*
+ * Native method which calls Windows java native dialog.
+ * This method add/update Copies attribute into the attr attribute set
+ * and set new selected printer if user clicked OK.
+ * It does not change any other PrinterJob attributes now.
+ * TODO: wtite new Windows native agent function which save dialog DEVMODE
+ * structure and returns correct attribute set for it.
+ */
+ native String getPrinter(String defaultPrinter, int copies);
+
+ public PageFormat defaultPage(PageFormat page) {
+ attrs.addAll(getAttrsForPageFormat(page));
+ return getPageFormatForAttrs(attrs);
+ }
+
+// ---------------------------------------------------------------
+
+ /*
+ * Returns PrintRequestAttributeSet which corresponds to given page
+ * PageFormat. We always adds MediaMArgins (not MediaPrintableArea)
+ * attribute for the result attribute set.
+ */
+ protected HashPrintRequestAttributeSet
+ getAttrsForPageFormat(PageFormat page) {
+
+ HashPrintRequestAttributeSet lattrs=new HashPrintRequestAttributeSet();
+
+ /* Add Orientation attribute */
+ switch (page.getOrientation()) {
+ case PageFormat.LANDSCAPE:
+ lattrs.add(OrientationRequested.LANDSCAPE);
+ break;
+ case PageFormat.PORTRAIT:
+ lattrs.add(OrientationRequested.PORTRAIT);
+ break;
+ case PageFormat.REVERSE_LANDSCAPE:
+ lattrs.add(OrientationRequested.REVERSE_LANDSCAPE);
+ break;
+ }
+
+ /* Add Media attribute */
+ MediaSizeName media = MediaSize.findMedia(
+ (float) (page.getWidth() / 72.0),
+ (float) (page.getHeight() / 72.0),
+ Size2DSyntax.INCH);
+ if (media != null) {
+ lattrs.add(media);
+ }
+
+ /* Add MediaMargins attribute */
+ lattrs.add(new MediaMargins((float) (page.getImageableX() / 72.0),
+ (float) (page.getImageableY() / 72.0),
+ (float) ((page.getWidth() - page.getImageableX() -
+ page.getImageableWidth()) / 72.0),
+ (float) ((page.getHeight() - page.getImageableHeight() -
+ page.getImageableY()) / 72.0),
+ MediaMargins.INCH));
+
+ return lattrs;
+ }
+
+ /*
+ * Returns PageFormat object which corresponds to the given newattrs
+ * attribute set.
+ */
+ protected PageFormat getPageFormatForAttrs(
+ PrintRequestAttributeSet newattrs) {
+
+ PageFormat pf = new PageFormat();
+
+ if (newattrs.containsKey(OrientationRequested.class)) {
+ OrientationRequested or = (OrientationRequested)
+ newattrs.get(OrientationRequested.class);
+ pf.setOrientation(or.equals(OrientationRequested.LANDSCAPE)
+ ? PageFormat.LANDSCAPE
+ : (or.equals(OrientationRequested.REVERSE_LANDSCAPE)
+ ? PageFormat.REVERSE_LANDSCAPE
+ : PageFormat.PORTRAIT));
+ }
+
+ Paper paper = new Paper();
+ MediaSize size = MediaSize.getMediaSizeForName(
+ newattrs.containsKey(Media.class)
+ && (newattrs.get(Media.class).getClass().
+ isAssignableFrom(MediaSizeName.class))
+ ? (MediaSizeName)newattrs.get(Media.class)
+ : MediaSizeName.ISO_A4);
+ paper.setSize(size.getX(Size2DSyntax.INCH) * 72.0,
+ size.getY(Size2DSyntax.INCH) * 72.0);
+
+
+ MediaMargins mm;
+ if (newattrs.containsKey(MediaMargins.class)) {
+ mm = (MediaMargins) newattrs.get(MediaMargins.class);
+ } else if(newattrs.containsKey(MediaPrintableArea.class)) {
+ mm = new MediaMargins(size,
+ (MediaPrintableArea) attrs.get(MediaPrintableArea.class));
+ } else {
+ mm = new MediaMargins(25.4F, 25.4F, 25.4F, 25.4F, MediaMargins.MM);
+ }
+ paper.setImageableArea(mm.getX1(MediaMargins.INCH) * 72.0,
+ mm.getY1(MediaMargins.INCH) * 72.0,
+ (size.getX(Size2DSyntax.INCH) - mm.getX1(MediaMargins.INCH) -
+ mm.getX2(MediaMargins.INCH)) * 72.0,
+ (size.getY(Size2DSyntax.INCH) - mm.getY1(MediaMargins.INCH) -
+ mm.getY2(MediaMargins.INCH)) * 72.0 );
+ pf.setPaper(paper);
+ return pf;
+ }
+
+ /*
+ * Find PrintService with the given name
+ */
+ protected PrintService findPrintService(String name) {
+ PrintService srvs [] =
+ PrintServiceLookup.lookupPrintServices(null, null);
+ if (srvs != null) {
+ for (int i = 0; i < srvs.length; i++) {
+ if (srvs[i].getName().equals(name)) {
+ return srvs[i];
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * This method returns all registered PrintServices list if this list
+ * contains this printer job's print service.
+ * If this list does not contain this job's print service, this function
+ * returns new print services list which contains all registered services
+ * plus this jib's service.
+ */
+ protected PrintService[] lookupServicesForDialog() {
+ PrintService [] services = lookupPrintServices();
+ if (services != null) {
+ for (int i = 0; i < services.length; i++) {
+ if (services[i].equals(service)) {
+ return services;
+ }
+ }
+ PrintService [] ret = new PrintService [services.length + 1];
+ for (int i = 0; i < services.length; i++) {
+ ret[i] = services[i];
+ }
+ ret[services.length] = service;
+ return ret;
+ }
+
+ return new PrintService [] {service};
+
+ }
+
+ /*
+ * This method adds newAttrs attributes to this.attrs attribute set. If
+ * newAttrs contains MediaMargins or MediaPrintableAttribute, result
+ * attribute set must not contain MediaPrintableArea or MediaMargins from
+ * this.attrs attribute set because of the possible conflict.
+ */
+ protected PrintRequestAttributeSet updateMediaAndMarginsIfNeeded(
+ PrintRequestAttributeSet newAttrs) {
+
+ /* create copy of this.attrs*/
+ PrintRequestAttributeSet sum =
+ new HashPrintRequestAttributeSet(this.attrs);
+
+ /* remove MediaMargins and MediaPrintableArea attributes from the copy
+ of job attributes if newAttrs contains MediaMargins or
+ PrintableArea */
+ if (newAttrs.containsKey(MediaPrintableArea.class)
+ || attrs.containsKey(MediaMargins.class)) {
+ sum.remove(MediaPrintableArea.class);
+ sum.remove(MediaMargins.class);
+ }
+
+ sum.addAll(newAttrs);
+ return sum;
+ }
+
+ /*
+ * TODO: Need to implement this methods
+ */
+ public void cancel() {
+ /* */
+ }
+
+ public boolean isCancelled() {
+ return false;
+ }
+
+ public PageFormat validatePage(PageFormat page) {
+ return null;
+ }
+
+
+
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/awt/PSPrinterJob.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSClient.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSClient.java?view=auto&rev=454289
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSClient.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSClient.java Sun Oct 8 22:33:09 2006
@@ -0,0 +1,980 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Igor A. Pyankov
+ * @version $Revision: 1.5 $
+ */
+
+package org.apache.harmony.x.print.cups;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilePermission;
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import javax.print.Doc;
+import javax.print.DocFlavor;
+import javax.print.PrintException;
+import javax.print.attribute.Attribute;
+import javax.print.attribute.AttributeSet;
+import javax.print.attribute.AttributeSetUtilities;
+import javax.print.attribute.DocAttributeSet;
+import javax.print.attribute.HashAttributeSet;
+import javax.print.attribute.HashPrintServiceAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.PrintServiceAttribute;
+import javax.print.attribute.PrintServiceAttributeSet;
+import javax.print.attribute.standard.Destination;
+import javax.print.attribute.standard.DocumentName;
+import javax.print.attribute.standard.JobName;
+import javax.print.attribute.standard.Media;
+import javax.print.attribute.standard.RequestingUserName;
+
+import org.apache.harmony.x.print.PrintClient;
+import org.apache.harmony.x.print.ipp.IppAttribute;
+import org.apache.harmony.x.print.ipp.IppAttributeGroup;
+import org.apache.harmony.x.print.ipp.IppAttributeGroupSet;
+import org.apache.harmony.x.print.ipp.IppDocument;
+import org.apache.harmony.x.print.ipp.IppPrinter;
+import org.apache.harmony.x.print.ipp.IppResponse;
+import org.apache.harmony.x.print.ipp.util.Ipp2Java;
+
+
+/*
+ * CUPSClient is a print client based on CUPS protocol.
+ * (see Common UNIX Printing System, http://www.cups.org/)
+ *
+ * The CUPS itself extends IPP protocol
+ * (see Internet Printing Protocol, http://www.pwg.org/ipp/index.html)
+ *
+ * So, this class supports as CUPS as IPP print servers
+ *
+ * The class uses special IPP package org.apache.harmony.x.print.ipp for
+ * ipp/cups specific operations.
+ *
+ * CUPSClient implements PrintClient interface, therefore
+ * see PrintClient.java for more information.
+ *
+ *
+ */
+class CUPSClient implements PrintClient {
+ // for debug
+ private static int verbose = 0;
+
+ private IppPrinter printer;
+ private URI printeruri;
+ private PrintServiceAttributeSet attributeset;
+ private DocFlavor[] supportedFlavors = null;
+
+ CUPSClient(String name) throws PrintException {
+ try {
+ this.printeruri = new URI(name);
+ this.printer = new IppPrinter(printeruri);
+ this.attributeset = new HashPrintServiceAttributeSet();
+ } catch (Exception e) {
+ throw new PrintException(e);
+ }
+ }
+
+ /*
+ * SPECIAL - supportedFlavors is global for perfomance
+ * but it can be set local for dynamic
+ *
+ * @org.apache.harmony.x.print.PrintClient#getSupportedDocFlavors()
+ */
+ public DocFlavor[] getSupportedDocFlavors() {
+ if (supportedFlavors == null) {
+ ArrayList df = new ArrayList();
+
+ try {
+ String[] mimetypes = new String[ALLDOCFLAVORS.length];
+ String[] validmimes;
+
+ for (int i = 0, ii = ALLDOCFLAVORS.length; i < ii; i++) {
+ mimetypes[i] = ALLDOCFLAVORS[i].getMimeType();
+ }
+ validmimes = printer.requestGetSupportedMimeTypes(mimetypes);
+ for (int i = 0, ii = ALLDOCFLAVORS.length; i < ii; i++) {
+ if (validmimes[i] != null) {
+ if (validmimes[i].equals("application/ps")) {
+ /*
+ * SPECIAL processing application/ps
+ */
+ df.add(ipp2java(ALLDOCFLAVORS[i]));
+ } else {
+ df.add(ALLDOCFLAVORS[i]);
+ }
+ }
+ }
+ } catch (Exception e) {
+ // IGNORE exception
+ e.printStackTrace();
+ }
+
+ supportedFlavors = (df.size() == 0 ? new DocFlavor[] { DocFlavor.INPUT_STREAM.AUTOSENSE }
+ : (DocFlavor[]) df.toArray(new DocFlavor[0]));
+ }
+ return supportedFlavors;
+ }
+
+ /*
+ * @see org.apache.harmony.x.print.PrintClient#getAttributes()
+ */
+ public PrintServiceAttributeSet getAttributes() {
+ synchronized (this) {
+ try {
+ IppResponse response;
+ IppAttributeGroup agroup;
+ IppAttribute attr;
+ Object[] attrx = new Object[0];
+
+ response = printer.requestPrinterDescriptionAttributes();
+ agroup = response
+ .getGroup(IppAttributeGroup.TAG_GET_PRINTER_ATTRIBUTES);
+ if (agroup != null) {
+ attributeset.clear();
+ for (int i = 0, ii = agroup.size(); i < ii; i++) {
+ attr = (IppAttribute) agroup.get(i);
+ attrx = Ipp2Java.getJavaByIpp(attr);
+ for (int j = 0, jj = attrx.length; j < jj; j++) {
+ if (attrx[j] instanceof PrintServiceAttribute) {
+ attributeset.add((Attribute) attrx[j]);
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ // IGNORE exception
+ e.printStackTrace();
+ }
+ }
+
+ return AttributeSetUtilities.unmodifiableView(attributeset);
+ }
+
+ /*
+ * @see org.apache.harmony.x.PrintClient#getSupportedAttributeCategories()
+ */
+ public Class[] getSupportedAttributeCategories() {
+ ArrayList clazz = new ArrayList();
+
+ try {
+ IppResponse response = printer.requestPrinterAttributes();
+ IppAttributeGroup agroup = response
+ .getGroup(IppAttributeGroup.TAG_GET_PRINTER_ATTRIBUTES);
+ String aname;
+ Class claz;
+ IppAttribute attr;
+
+ if (agroup != null) {
+ for (int i = 0, ii = agroup.size(); i < ii; i++) {
+ attr = (IppAttribute) agroup.get(i);
+ aname = new String(attr.getName());
+ if (aname.indexOf("-supported") > 0) {
+ claz = Ipp2Java.getClassByIppAttributeName(aname
+ .substring(0, aname.indexOf("-supported")));
+ if (claz != null) {
+ clazz.add(claz);
+ }
+ }
+ }
+ }
+ // SPECIAL attributes processing
+ getSupportedAttributeCategoriesEx(clazz);
+ } catch (Exception e) {
+ // IGNORE exception
+ // e.printStackTrace();
+ }
+ return (clazz.size() == 0 ? new Class[0] : (Class[]) clazz
+ .toArray(new Class[0]));
+ }
+
+ private void getSupportedAttributeCategoriesEx(ArrayList clazz) {
+ if (!clazz.contains(Destination.class)) {
+ clazz.add(Destination.class);
+ }
+ if (!clazz.contains(RequestingUserName.class)) {
+ clazz.add(RequestingUserName.class);
+ }
+ if (!clazz.contains(JobName.class)) {
+ clazz.add(JobName.class);
+ }
+ if (!clazz.contains(DocumentName.class)) {
+ clazz.add(DocumentName.class);
+ }
+ }
+
+ /*
+ * @see org.apache.harmony.x.print.PrintClient#getDefaultAttributeValue(java.lang.Class)
+ */
+ public Object getDefaultAttributeValue(Class category) {
+ if (category == null) {
+ throw new NullPointerException("Argument is null");
+ }
+ if (!(Attribute.class.isAssignableFrom(category))) {
+ throw new IllegalArgumentException(
+ "Argument must implement interface Attribute");
+ }
+
+ Object defval[] = null;
+
+ // SPECIAL attributes processing
+ defval = getDefaultAttributeValueEx(category);
+ if (defval != null) {
+ if (defval.length == 0) {
+ return null;
+ }
+ return defval[0];
+ }
+
+ if (Media.class.isAssignableFrom(category)) {
+ category = Media.class;
+ }
+ try {
+ IppResponse response = printer.requestPrinterAttributes();
+ IppAttributeGroup agroup = response
+ .getGroup(IppAttributeGroup.TAG_GET_PRINTER_ATTRIBUTES);
+ IppAttribute attr;
+ String aname;
+ int andex;
+
+ if (agroup != null) {
+ aname = Ipp2Java.getIppAttributeNameByClass(category);
+ if (aname != null) {
+ if (aname.endsWith("-supported")) {
+ aname = aname.substring(0, aname.indexOf("-supported"));
+ }
+ if (aname.endsWith("-default")) {
+ aname = aname.substring(0, aname.indexOf("-default"));
+ }
+ andex = agroup.findAttribute(aname + "-default");
+ if (andex >= 0) {
+ attr = (IppAttribute) agroup.get(andex);
+ defval = Ipp2Java.getJavaByIpp(attr);
+ }
+ }
+ }
+ } catch (Exception e) {
+ // IGNORE exception
+ e.printStackTrace();
+ }
+
+ return (defval != null && defval.length > 0 ? defval[0] : null);
+ }
+
+ /*
+ * If attribute was processed - return Object[1]
+ * Else - return null
+ */
+ private Object[] getDefaultAttributeValueEx(Class category) {
+ if (Destination.class.isAssignableFrom(category)) {
+ return new Object[0];
+ } else if (RequestingUserName.class.isAssignableFrom(category)) {
+ return new Object[] { new RequestingUserName(
+ (String) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty("user.name");
+ }
+ }), Locale.US) };
+ } else if (JobName.class.isAssignableFrom(category)) {
+ return new Object[] { new JobName("Java print job", Locale.US) };
+ } else if (DocumentName.class.isAssignableFrom(category)) {
+ return new Object[] { new DocumentName("Java print document",
+ Locale.US) };
+ }
+ return null;
+ }
+
+ /*
+ * @see org.apache.harmony.x.print.PrintClient#isAttributeValueSupported(javax.print.attribute.Attribute,
+ * javax.print.DocFlavor, javax.print.attribute.AttributeSet)
+ */
+ public boolean isAttributeValueSupported(Attribute attribute,
+ DocFlavor flavor, AttributeSet attributes) {
+
+ // verify parameters
+ if (attribute == null) {
+ throw new NullPointerException("Argument is null");
+ }
+ if (flavor != null && !isDocFlavorSupported(flavor)) {
+ throw new IllegalArgumentException("DocFlavor '" + flavor
+ + "' is not supported by the print service");
+ }
+
+ // SPECIAL attributes processing
+ boolean[] supportedEx = isAttributeValueSupportedEx(attribute, flavor);
+ if (supportedEx != null) {
+ return supportedEx[0];
+ }
+
+ boolean supported = false;
+ try {
+ IppDocument document;
+ IppResponse response;
+ IppAttributeGroup agroup;
+ IppAttributeGroupSet agroupset;
+ Attribute[] attrs;
+ String mime = null;
+ String aname;
+
+ aname = Ipp2Java.getIppAttributeNameByClass(attribute.getClass(),
+ -1);
+ if (aname == null) {
+ return false;
+ }
+ if (flavor == null) {
+ mime = "application/octet-stream";
+ } else {
+ mime = java2ipp(flavor).getMimeType();
+ }
+ if (attributes == null || attributes.isEmpty()) {
+ document = new IppDocument("Qwerty", mime, "");
+ agroupset = new IppAttributeGroupSet();
+ agroupset.setAttribute(aname, Ipp2Java.getIppByJava(attribute));
+ response = printer.requestValidateJob(aname, document,
+ agroupset);
+ agroup = response
+ .getGroup(IppAttributeGroup.TAG_UNSUPPORTED_ATTRIBUTES);
+
+ if (agroup == null) {
+ supported = true;
+ } else if (agroup != null && agroup.findAttribute(aname) < 0) {
+ supported = true;
+ }
+ } else {
+ document = new IppDocument("Qwerty", mime, "");
+ agroupset = new IppAttributeGroupSet();
+ agroupset.setAttribute(aname, Ipp2Java.getIppByJava(attribute));
+ attrs = attributes.toArray();
+ for (int i = 0, ii = attrs.length; i < ii; i++) {
+ agroupset.setAttribute(Ipp2Java.getIppAttributeNameByClass(
+ attrs[i].getClass(), -1), Ipp2Java
+ .getIppByJava(attrs[i]));
+ }
+
+ response = printer.requestValidateJob(aname, document,
+ agroupset);
+ agroup = response
+ .getGroup(IppAttributeGroup.TAG_UNSUPPORTED_ATTRIBUTES);
+
+ if (agroup == null) {
+ supported = true;
+ } else if (agroup != null && agroup.findAttribute(aname) < 0) {
+ supported = true;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ return supported;
+ }
+
+ /*
+ * If attribute was processed - return boolean[1]
+ * Else return null
+ */
+ private boolean[] isAttributeValueSupportedEx(Attribute avalue,
+ DocFlavor flavor) {
+ if (Destination.class.isAssignableFrom(avalue.getCategory())) {
+ String ms = (flavor != null ? flavor.getMediaSubtype() : "");
+ Class cls = (flavor != null ? flavor.getClass() : null);
+
+ if (ms.equalsIgnoreCase("gif") || ms.equalsIgnoreCase("jpeg")
+ || ms.equalsIgnoreCase("png")
+ || ms.equalsIgnoreCase("postscript") || flavor == null
+ || cls == DocFlavor.SERVICE_FORMATTED.class) {
+ if (!canPrintToFile()) {
+ return new boolean[] { false };
+ }
+
+ URI uri = ((Destination) avalue).getURI();
+ try {
+ File file = new File(uri);
+
+ if (file.isFile()) {
+ if (file.canWrite()) {
+ return new boolean[] { true };
+ }
+ return new boolean[] { false };
+ }
+
+ String path = file.getParent();
+ File parent = new File(path);
+ if (parent.isDirectory()) {
+ if (parent.canWrite()) {
+ return new boolean[] { true };
+ }
+ return new boolean[] { false };
+ }
+ } catch (Exception e) {
+ return new boolean[] { false };
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * @see org.apache.harmony.x.print.PrintClient#getSupportedAttributeValues(java.lang.Class,
+ * javax.print.DocFlavor, javax.print.attribute.AttributeSet)
+ */
+ public Object getSupportedAttributeValues(Class category, DocFlavor flavor,
+ AttributeSet attributes) {
+ if (category == null) {
+ throw new NullPointerException("Argument is null");
+ }
+ if (!(Attribute.class.isAssignableFrom(category))) {
+ throw new IllegalArgumentException(
+ "Argument must implement interface Attribute");
+ }
+ if (flavor != null && !isDocFlavorSupported(flavor)) {
+ throw new IllegalArgumentException("DocFlavor '" + flavor
+ + "' is not supported by the print service");
+ }
+
+ Object vals = null;
+
+ // SPECIAL attributes processing
+ vals = getSupportedAttributeValuesEx(category, flavor);
+ if (vals != null) {
+ if (((Object[]) vals).length == 0) {
+ return null;
+ }
+ return ((Object[]) vals)[0];
+ }
+
+ // General attributes
+ try {
+ String aname = Ipp2Java.getIppAttributeNameByClass(category, 0)
+ + "-supported";
+ doVerbose(2,
+ "CUPSClient.java: getSupportedAttributeValues(): ipp attribute: "
+ + aname);
+ IppResponse response = printer.requestPrinterAttributes(aname,
+ (flavor == null ? null : java2ipp(flavor).getMimeType()));
+ doVerbose(2,
+ "CUPSClient.java: getSupportedAttributeValues(): response: "
+ + response.toString());
+ IppAttributeGroup agroup = response
+ .getGroup(IppAttributeGroup.TAG_GET_PRINTER_ATTRIBUTES);
+ doVerbose(1,
+ "CUPSClient.java: getSupportedAttributeValues(): agroup: "
+ + agroup.toString());
+ if (agroup != null) {
+ int aind = agroup.findAttribute(aname);
+ if (aind >= 0) {
+ IppAttribute attr = (IppAttribute) agroup.get(aind);
+ vals = Ipp2Java.getJavaByIpp(attr);
+ }
+ }
+ doVerbose(1, "CUPSClient.java: getSupportedAttributeValues(): 1");
+ // Make right type/value for return
+ if (vals != null && vals.getClass().isArray()) {
+ Object[] ara = (Object[]) vals;
+ if (ara.length == 1 && ara[0].getClass() != category) {
+ vals = ara[0];
+ }
+ }
+ doVerbose(1, "CUPSClient.java: getSupportedAttributeValues(): 2");
+ if (vals != null && vals.getClass().isArray()) {
+ int asize = ((Object[]) vals).length;
+ if (asize > 0) {
+ Class c = ((Object[]) vals)[0].getClass();
+ /* SPECIAL case for Media* attributes
+ *
+ * Special case for Media* attributes.
+ * vals[] contains all type of Media classes
+ * So, c must be Media type, not a[0] type
+ */
+ if (Media.class.isAssignableFrom(c)) {
+ c = Media.class;
+ }
+ doVerbose(1,
+ "CUPSClient.java: getSupportedAttributeValues(): 3");
+ Object[] a = (Object[]) Array.newInstance(c, asize);
+ System.arraycopy(vals, 0, a, 0, a.length);
+
+ vals = a;
+ } else {
+ vals = null;
+ }
+ }
+ doVerbose(1, "CUPSClient.java: getSupportedAttributeValues(): 4");
+ if (vals != null && vals.getClass().isArray()) {
+ for (int i = 0, ii = ((Attribute[]) vals).length; i < ii; i++) {
+ if (!isAttributeValueSupported(((Attribute[]) vals)[i],
+ flavor, attributes)) {
+ ((Attribute[]) vals)[i] = null;
+ }
+ }
+ doVerbose(1,
+ "CUPSClient.java: getSupportedAttributeValues(): 5");
+ int newvalslength = 0;
+ for (int i = 0, ii = ((Attribute[]) vals).length; i < ii; i++) {
+ if (((Attribute[]) vals)[i] != null) {
+ newvalslength++;
+ }
+ }
+ doVerbose(1,
+ "CUPSClient.java: getSupportedAttributeValues(): 6");
+ if (newvalslength != ((Attribute[]) vals).length) {
+ Object[] newvals = new Object[newvalslength];
+ for (int j = 0, i = 0, ii = ((Attribute[]) vals).length; i < ii; i++) {
+ if (((Attribute[]) vals)[i] != null) {
+ newvals[j++] = ((Attribute[]) vals)[i];
+ }
+ }
+
+ vals = newvals;
+ }
+ } else if (vals != null) {
+ if (!isAttributeValueSupported((Attribute) vals, flavor,
+ attributes)) {
+ vals = null;
+ }
+ }
+ doVerbose(1, "CUPSClient.java: getSupportedAttributeValues(): 7");
+ return vals;
+ } catch (Exception e) {
+ // IGNORE exception
+ e.printStackTrace();
+ }
+ doVerbose(1, "CUPSClient.java: getSupportedAttributeValues(): 8");
+ return null;
+ } /*
+ * If category processed - return non-null value
+ */
+
+ private Object[] getSupportedAttributeValuesEx(Class category,
+ DocFlavor flavor) {
+ if (Destination.class.isAssignableFrom(category)) {
+ String ms = flavor.getMediaSubtype();
+
+ if (ms.equalsIgnoreCase("gif") || ms.equalsIgnoreCase("jpeg")
+ || ms.equalsIgnoreCase("png")
+ || ms.equalsIgnoreCase("postscript")
+ || flavor.getClass() == DocFlavor.SERVICE_FORMATTED.class) {
+ try {
+ return new Object[] { new Destination(new URI(
+ "file:///foo/bar")) };
+ } catch (URISyntaxException e) {
+ // return empty array - values are not supported
+ return new Object[0];
+ }
+ }
+ } else if (RequestingUserName.class.isAssignableFrom(category)) {
+ return new Object[] { new RequestingUserName("I.A.Muser", Locale.US) };
+ } else if (JobName.class.isAssignableFrom(category)) {
+ return new Object[] { new JobName("Foo print job", Locale.US) };
+ } else if (DocumentName.class.isAssignableFrom(category)) {
+ return new Object[] { new DocumentName("Foo document", Locale.US) };
+ }
+ return null;
+ }
+
+ /*
+ * @see org.apache.harmony.x.print.PrintClient#print(javax.print.Doc,
+ * javax.print.attribute.PrintRequestAttributeSet)
+ */
+ public void print(Doc doc, PrintRequestAttributeSet attributes)
+ throws PrintException {
+ synchronized (this) {
+ doVerbose(1, "Print " + doc.toString());
+ try {
+ DocFlavor df = doc.getDocFlavor();
+ if (!(df instanceof DocFlavor.INPUT_STREAM
+ || df instanceof DocFlavor.BYTE_ARRAY
+ || df instanceof DocFlavor.CHAR_ARRAY
+ || df instanceof DocFlavor.STRING
+ || df instanceof DocFlavor.READER || df instanceof DocFlavor.URL)) {
+ throw new PrintException("Doc flavor "
+ + df.getRepresentationClassName()
+ + " is not supported yet");
+ }
+
+ HashAttributeSet as = new HashAttributeSet();
+ DocAttributeSet das;
+ das = doc.getAttributes();
+
+ // construct attributes
+ if (das != null) {
+ as.addAll(das);
+ }
+ if (attributes != null) {
+ as.addAll(attributes);
+ }
+ as.addAll(attributeset);
+
+ // print
+ if (as.containsKey(Destination.class)) {
+ print2destination(doc, (Destination) as
+ .get(Destination.class));
+ } else {
+ printsimple(doc, as);
+ }
+ } catch (PrintException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new PrintException(e);
+ }
+ }
+ }
+
+ /*
+ * printing to Destination
+ */
+ private void print2destination(Doc doc, Destination destination)
+ throws PrintException {
+
+ try {
+ DataOutputStream bw = new DataOutputStream(
+ new BufferedOutputStream(new FileOutputStream(new File(
+ destination.getURI()))));
+
+ if (doc != null) {
+ if (doc.getDocFlavor() instanceof DocFlavor.INPUT_STREAM) {
+ InputStream stream = (InputStream) doc.getPrintData();
+ byte[] buf = new byte[1024 * 8];
+ int count = 0;
+
+ while ((count = stream.read(buf, 0, buf.length)) != -1) {
+ bw.write(buf, 0, count);
+ }
+ stream.close();
+ } else if (doc.getDocFlavor() instanceof DocFlavor.URL) {
+ BufferedInputStream stream = new BufferedInputStream(
+ ((URL) doc.getPrintData()).openStream());
+ byte[] buf = new byte[1024 * 8];
+ int count = 0;
+ while ((count = stream.read(buf, 0, buf.length)) != -1) {
+ if (count > 0) {
+ bw.write(buf, 0, count);
+ }
+ }
+ stream.close();
+ } else if (doc.getDocFlavor() instanceof DocFlavor.BYTE_ARRAY) {
+ InputStream stream = new ByteArrayInputStream((byte[]) doc
+ .getPrintData());
+ byte[] buf = new byte[1024 * 8];
+ int count = 0;
+
+ while ((count = stream.read(buf, 0, buf.length)) != -1) {
+ bw.write(buf, 0, count);
+ }
+ stream.close();
+ } else if (doc.getDocFlavor() instanceof DocFlavor.SERVICE_FORMATTED) {
+ // TODO - print DocFlavor.SERVICE_FORMATTED
+ }
+ }
+
+ bw.flush();
+ bw.close();
+ } catch (Exception e) {
+ throw new PrintException(e);
+ }
+ }
+
+ /*
+ * request IppPrinter printer to print document
+ */
+ private void printsimple(Doc doc, HashAttributeSet as)
+ throws PrintException {
+ IppDocument document;
+ IppResponse response;
+ IppAttributeGroupSet agroupset;
+ Attribute[] attrs;
+ DocFlavor df = doc.getDocFlavor();
+ String docname = doc.toString();
+
+ try {
+ document = new IppDocument(docname, java2ipp(df).getMimeType(), doc
+ .getPrintData());
+
+ agroupset = new IppAttributeGroupSet();
+ attrs = as.toArray();
+ for (int i = 0, ii = attrs.length; i < ii; i++) {
+ agroupset.setAttribute(Ipp2Java.getIppAttributeNameByClass(
+ attrs[i].getClass(), -1), Ipp2Java
+ .getIppByJava(attrs[i]));
+ }
+ document.setAgroups(agroupset);
+
+ doVerbose(1, "Validating print job...");
+ response = printer.requestValidateJob(docname, document, agroupset);
+ doVerbose(1, response.toString());
+ checkResponseIsZero(response, "IPP Validate Job: \n");
+ doVerbose(1, "Validate OK");
+
+ doVerbose(1, "Printing " + docname + "...");
+ response = printer.requestPrintJob(docname, document, agroupset);
+ doVerbose(1, response.toString());
+ checkResponseIsZero(response, "IPP Print Job: \n");
+ doVerbose(1, "Printing OK");
+ } catch (PrintException e) {
+ throw e;
+ } catch (Exception e) {
+ if (getVerbose() > 1) {
+ e.printStackTrace();
+ }
+ throw new PrintException(e);
+ }
+ }
+
+ /*
+ * just check that IppResponse is OK
+ */
+ private void checkResponseIsZero(IppResponse response, String prefix)
+ throws PrintException {
+ if (response.getStatusCode() != 0) {
+ String status = Integer.toHexString(response.getStatusCode());
+ String id = Integer.toHexString(response.getRequestId());
+
+ throw new PrintException(prefix
+ + "\n================ IPP response id: 0x" + id
+ + " =====================" + "\nresponse status code: 0x"
+ + status + "\n" + response.toString()
+ + "\n================ end IPP response 0x" + id
+ + " =====================");
+ }
+ }
+
+ /*
+ * convert DocFlavor to DocFlavor ;-)
+ *
+ * some printers support application/ps instead of application/postscript
+ * So:
+ * if mimetype==application/postscript
+ * && printer does not support mimetype application/postscript
+ * && printer supports mimetype application/ps
+ * then
+ * we change mimetype of docflavor to application/ps
+ */
+ private DocFlavor java2ipp(DocFlavor pDocFlavor) {
+ DocFlavor ippDocFlavor = pDocFlavor;
+ String mime = pDocFlavor.getMimeType();
+
+ /*
+ * SPECIAL processing application/ps
+ */
+ if (mime.equals("application/postscript")) {
+ try {
+ IppDocument document = new IppDocument("Qwerty",
+ "application/postscript", "");
+ IppResponse response = printer.requestValidateJob("Qwerty",
+ document, null);
+ if (response.getStatusCode() != 0) {
+ document = new IppDocument("Qwerty", "application/ps", "");
+ response = printer.requestValidateJob("Qwerty", document,
+ null);
+ if (response.getStatusCode() == 0) {
+ if (pDocFlavor instanceof DocFlavor.INPUT_STREAM) {
+ ippDocFlavor = new DocFlavor.INPUT_STREAM(
+ "application/ps");
+ } else if (ippDocFlavor instanceof DocFlavor.BYTE_ARRAY) {
+ ippDocFlavor = new DocFlavor.BYTE_ARRAY(
+ "application/ps");
+ } else if (ippDocFlavor instanceof DocFlavor.URL) {
+ ippDocFlavor = new DocFlavor.URL("application/ps");
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ return ippDocFlavor;
+ }
+
+ /*
+ * opposite to java2ipp() method
+ */
+ private DocFlavor ipp2java(DocFlavor ippDocFlavor) {
+ DocFlavor pDocFlavor = ippDocFlavor;
+ String mime = ippDocFlavor.getMimeType();
+
+ /*
+ * SPECIAL processing application/ps
+ */
+ if (mime.equals("application/ps")) {
+ if (ippDocFlavor instanceof DocFlavor.INPUT_STREAM) {
+ pDocFlavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
+ } else if (ippDocFlavor instanceof DocFlavor.BYTE_ARRAY) {
+ pDocFlavor = DocFlavor.BYTE_ARRAY.POSTSCRIPT;
+ } else if (ippDocFlavor instanceof DocFlavor.URL) {
+ pDocFlavor = DocFlavor.URL.POSTSCRIPT;
+ }
+ }
+
+ return pDocFlavor;
+ }
+
+ /*
+ * the method's name is saying all
+ */
+ private boolean isDocFlavorSupported(DocFlavor flavor) {
+ if (flavor == null) {
+ throw new NullPointerException("DocFlavor flavor is null");
+ }
+
+ DocFlavor clientFlavors[] = getSupportedDocFlavors();
+ for (int i = 0; i < clientFlavors.length; i++) {
+ if (clientFlavors[i].equals(flavor)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * check permission to read/write to any file
+ */
+ private boolean canPrintToFile() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ try {
+ sm.checkPermission(new FilePermission("<<ALL FILES>>",
+ "read,write"));
+ return true;
+ } catch (SecurityException e) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * just list of all doc flavors from specification
+ * it is used in getSupportedDocFlavors() method
+ */
+ private static DocFlavor[] ALLDOCFLAVORS = { DocFlavor.BYTE_ARRAY.TEXT_PLAIN_HOST,
+ DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_8,
+ DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16,
+ DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16BE,
+ DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16LE,
+ DocFlavor.BYTE_ARRAY.TEXT_PLAIN_US_ASCII,
+ DocFlavor.BYTE_ARRAY.TEXT_HTML_HOST,
+ DocFlavor.BYTE_ARRAY.TEXT_HTML_UTF_8,
+ DocFlavor.BYTE_ARRAY.TEXT_HTML_UTF_16,
+ DocFlavor.BYTE_ARRAY.TEXT_HTML_UTF_16BE,
+ DocFlavor.BYTE_ARRAY.TEXT_HTML_UTF_16LE,
+ DocFlavor.BYTE_ARRAY.TEXT_HTML_US_ASCII,
+ DocFlavor.BYTE_ARRAY.PDF,
+ DocFlavor.BYTE_ARRAY.POSTSCRIPT,
+ DocFlavor.BYTE_ARRAY.PCL,
+ DocFlavor.BYTE_ARRAY.GIF,
+ DocFlavor.BYTE_ARRAY.JPEG,
+ DocFlavor.BYTE_ARRAY.PNG,
+ DocFlavor.BYTE_ARRAY.AUTOSENSE,
+
+ DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST,
+ DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_8,
+ DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16,
+ DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16BE,
+ DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16LE,
+ DocFlavor.INPUT_STREAM.TEXT_PLAIN_US_ASCII,
+ DocFlavor.INPUT_STREAM.TEXT_HTML_HOST,
+ DocFlavor.INPUT_STREAM.TEXT_HTML_UTF_8,
+ DocFlavor.INPUT_STREAM.TEXT_HTML_UTF_16,
+ DocFlavor.INPUT_STREAM.TEXT_HTML_UTF_16BE,
+ DocFlavor.INPUT_STREAM.TEXT_HTML_UTF_16LE,
+ DocFlavor.INPUT_STREAM.TEXT_HTML_US_ASCII,
+ DocFlavor.INPUT_STREAM.PDF,
+ DocFlavor.INPUT_STREAM.POSTSCRIPT,
+ DocFlavor.INPUT_STREAM.PCL,
+ DocFlavor.INPUT_STREAM.GIF,
+ DocFlavor.INPUT_STREAM.JPEG,
+ DocFlavor.INPUT_STREAM.PNG,
+ DocFlavor.INPUT_STREAM.AUTOSENSE,
+
+ DocFlavor.URL.TEXT_PLAIN_HOST,
+ DocFlavor.URL.TEXT_PLAIN_UTF_8,
+ DocFlavor.URL.TEXT_PLAIN_UTF_16,
+ DocFlavor.URL.TEXT_PLAIN_UTF_16BE,
+ DocFlavor.URL.TEXT_PLAIN_UTF_16LE,
+ DocFlavor.URL.TEXT_PLAIN_US_ASCII,
+ DocFlavor.URL.TEXT_HTML_HOST,
+ DocFlavor.URL.TEXT_HTML_UTF_8,
+ DocFlavor.URL.TEXT_HTML_UTF_16,
+ DocFlavor.URL.TEXT_HTML_UTF_16BE,
+ DocFlavor.URL.TEXT_HTML_UTF_16LE,
+ DocFlavor.URL.TEXT_HTML_US_ASCII,
+ DocFlavor.URL.PDF,
+ DocFlavor.URL.POSTSCRIPT,
+ DocFlavor.URL.PCL,
+ DocFlavor.URL.GIF,
+ DocFlavor.URL.JPEG,
+ DocFlavor.URL.PNG,
+ DocFlavor.URL.AUTOSENSE,
+
+ DocFlavor.CHAR_ARRAY.TEXT_PLAIN,
+ DocFlavor.CHAR_ARRAY.TEXT_HTML,
+
+ DocFlavor.STRING.TEXT_PLAIN,
+ DocFlavor.STRING.TEXT_HTML,
+
+ DocFlavor.READER.TEXT_PLAIN,
+ DocFlavor.READER.TEXT_HTML,
+
+ DocFlavor.SERVICE_FORMATTED.RENDERABLE_IMAGE,
+ DocFlavor.SERVICE_FORMATTED.PRINTABLE,
+ DocFlavor.SERVICE_FORMATTED.PAGEABLE,
+
+ /*
+ * Some printers accept "application/ps" instead of "application/postscript"
+ * So, we have special processing for those DocFlavor
+ * See comments with phrase:
+ * SPECIAL processing application/ps
+ */
+ new DocFlavor.INPUT_STREAM("application/ps"),
+ new DocFlavor.URL("application/ps"),
+ new DocFlavor.BYTE_ARRAY("application/ps") };
+
+ public static int getVerbose() {
+ return verbose;
+ }
+
+ public static void setVerbose(int newverbose) {
+ verbose = newverbose;
+ IppPrinter.setVerbose(verbose);
+ }
+
+ public static void doVerbose(String v) {
+ System.out.println(v);
+ }
+
+ public static void doVerbose(int level, String v) {
+ if (verbose >= level) {
+ System.out.println(v);
+ }
+ }
+
+}
\ No newline at end of file
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSClient.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSPrintServiceProvider.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSPrintServiceProvider.java?view=auto&rev=454289
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSPrintServiceProvider.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSPrintServiceProvider.java Sun Oct 8 22:33:09 2006
@@ -0,0 +1,552 @@
+/*
+ * Copyright 2005 - 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Igor A. Pyankov
+ * @version $Revision: 1.3 $
+ */
+
+package org.apache.harmony.x.print.cups;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Vector;
+
+import javax.print.DocFlavor;
+import javax.print.MultiDocPrintService;
+import javax.print.PrintException;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.attribute.AttributeSet;
+
+import org.apache.harmony.x.print.DefaultPrintService;
+import org.apache.harmony.x.print.ipp.IppAttribute;
+import org.apache.harmony.x.print.ipp.IppAttributeGroup;
+import org.apache.harmony.x.print.ipp.IppClient;
+import org.apache.harmony.x.print.ipp.IppOperation;
+import org.apache.harmony.x.print.ipp.IppPrinter;
+import org.apache.harmony.x.print.ipp.IppRequest;
+import org.apache.harmony.x.print.ipp.IppResponse;
+
+
+/*
+ * The class extends PrintServiceLookup and is intended for
+ * looking up CUPS/IPP printers
+ *
+ * 1. The class allways looks printers on http://localhost:631
+ * This URL is default URL for default installation of CUPS server
+ * 2. The class accepts two properties:
+ * print.cups.servers - a list of CUPS servers
+ * print.ipp.printers - a list of IPP printers
+ * (note, that CUPS printer is IPP printer too)
+ */
+public class CUPSPrintServiceProvider extends PrintServiceLookup {
+ private static String cupsdefault = "http://localhost:631";
+ private static ArrayList services = new ArrayList();
+ /*
+ * 0 - no
+ * 1 - more
+ * 2 - more and more
+ * ...
+ */
+ private static int verbose = 0;
+
+ static {
+ String verbose_property = (String) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty("print.cups.verbose");
+ }
+ });
+ if (verbose_property != null) {
+ try {
+ Integer v = new Integer(verbose_property);
+ setVerbose(v.intValue());
+ } catch (NumberFormatException e) {
+ setVerbose(0);
+ }
+
+ }
+ }
+
+ public CUPSPrintServiceProvider() {
+ super();
+ }
+
+ /*
+ * The method returns array of URLs of CUPS servers
+ */
+ private static String[] getCUPSServersByProperty() {
+ ArrayList cupslist = new ArrayList();
+ cupslist.add(cupsdefault);
+
+ String cupspath = (String) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty("print.cups.servers");
+ }
+ });
+ String pathsep = ",";
+ if (cupspath != null && !cupspath.equals("")) {
+ String[] cupss = cupspath.split(pathsep);
+ for (int i = 0, ii = cupss.length; i < ii; i++) {
+ if (!cupss[i].equals("")) {
+ try {
+ URI cupsuri = new URI(cupss[i]);
+ cupslist.add(cupsuri.toString());
+ } catch (URISyntaxException e) {
+ if (verbose > 0) {
+ System.err.println("CUPS url: " + cupss[i]);
+ e.printStackTrace();
+ } else {
+ // IGNORE bad URI exception
+ }
+ }
+ }
+ }
+ }
+
+ return (String[]) cupslist.toArray(new String[0]);
+ }
+
+ /*
+ * The method returns array of URLs of IPP printers
+ */
+ private static String[] getIppPrintersByProperty() {
+ ArrayList ipplist = new ArrayList();
+
+ String ipppath = (String) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty("print.ipp.printers");
+ }
+ });
+ String pathsep = ","; //System.getProperty("path.separator");
+ if (ipppath != null && !ipppath.equals("")) {
+ String[] ipps = ipppath.split(pathsep);
+ for (int i = 0, ii = ipps.length; i < ii; i++) {
+ if (!ipps[i].equals("")) {
+ try {
+ URI cupsuri = new URI(ipps[i]);
+ ipplist.add(cupsuri.toString());
+ } catch (URISyntaxException e) {
+ if (verbose > 0) {
+ System.err.println("IPP url: " + ipps[i]);
+ e.printStackTrace();
+ } else {
+ // IGNORE bad URI exception
+ }
+ }
+ }
+ }
+ }
+
+ return (String[]) ipplist.toArray(new String[0]);
+ }
+
+ /*
+ * @see javax.print.PrintServiceLookup#getDefaultPrintService()
+ */
+ public PrintService getDefaultPrintService() {
+ synchronized (this) {
+ String defaultService = findDefaultPrintService();
+
+ if (defaultService != null) {
+ PrintService service = getServiceStored(defaultService,
+ services);
+ if (service != null) {
+ return service;
+ }
+
+ CUPSClient client;
+ try {
+ client = new CUPSClient(defaultService);
+ service = new DefaultPrintService(defaultService, client);
+ services.add(service);
+ return service;
+ } catch (PrintException e) {
+ // just ignore
+ e.printStackTrace();
+ }
+ }
+
+ if (services.size() == 0) {
+ getPrintServices();
+ }
+ if (services.size() > 0) {
+ return (PrintService) services.get(0);
+ }
+
+ }
+ return null;
+ }
+
+ /*
+ * @see javax.print.PrintServiceLookup#getPrintServices()
+ */
+ public PrintService[] getPrintServices() {
+ synchronized (this) {
+ String[] serviceNames = findPrintServices();
+ if (serviceNames == null || serviceNames.length == 0) {
+ services.clear();
+ return new PrintService[0];
+ }
+
+ ArrayList newServices = new ArrayList();
+ for (int i = 0; i < serviceNames.length; i++) {
+ PrintService service = getServiceStored(serviceNames[i],
+ services);
+ if (service != null) {
+ newServices.add(service);
+ } else if (getServiceStored(serviceNames[i], newServices) == null) {
+ try {
+ CUPSClient client = new CUPSClient(serviceNames[i]);
+
+ service = new DefaultPrintService(serviceNames[i],
+ client);
+ newServices.add(service);
+ } catch (PrintException e) {
+ // just ignore
+ e.printStackTrace();
+ }
+ }
+ }
+
+ services.clear();
+ services = newServices;
+ return (services.size() == 0) ? new PrintService[0]
+ : (PrintService[]) services.toArray(new PrintService[0]);
+ }
+ }
+
+ /*
+ * find printers on particular CUPS server
+ */
+ private PrintService[] getCUPSPrintServices(String cups) {
+ synchronized (this) {
+ // just update static field 'services'
+ findPrintServices();
+
+ // next find services on server 'cups'
+ String[] serviceNames = (String[]) findCUPSPrintServices(cups)
+ .toArray(new String[0]);
+ if (serviceNames == null || serviceNames.length == 0) {
+ return new PrintService[0];
+ }
+
+ // return only those are stored in field 'services'
+ ArrayList newServices = new ArrayList();
+ for (int i = 0; i < serviceNames.length; i++) {
+ PrintService service = getServiceStored(serviceNames[i],
+ services);
+ if (service != null) {
+ newServices.add(service);
+ }
+ }
+
+ return (newServices.size() == 0) ? new PrintService[0]
+ : (PrintService[]) services.toArray(new PrintService[0]);
+ }
+ }
+
+ /*
+ * find printers on localhost only
+ */
+ public PrintService[] getPrintServicesOnLocalHost() {
+ return getCUPSPrintServices(cupsdefault);
+ }
+
+ /*
+ * find service which name is same as serviceName
+ */
+ private PrintService getServiceStored(String serviceName,
+ ArrayList servicesList) {
+ for (int i = 0; i < servicesList.size(); i++) {
+ PrintService service = (PrintService) servicesList.get(i);
+ if (service.getName().equals(serviceName)) {
+ return service;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * @see javax.print.PrintServiceLookup#getPrintServices(javax.print.DocFlavor
+ * , javax.print.attribute.AttributeSet)
+ */
+ public PrintService[] getPrintServices(DocFlavor flavor,
+ AttributeSet attributes) {
+ PrintService[] cupsservices = getPrintServices();
+ if (flavor == null && attributes == null) {
+ return cupsservices;
+ }
+
+ ArrayList requestedServices = new ArrayList();
+ for (int i = 0; i < cupsservices.length; i++) {
+ try {
+ AttributeSet unsupportedSet = cupsservices[i]
+ .getUnsupportedAttributes(flavor, attributes);
+ if (unsupportedSet == null) {
+ requestedServices.add(cupsservices[i]);
+ }
+ } catch (IllegalArgumentException iae) {
+ // DocFlavor not supported by service, skiping.
+ }
+ }
+ return (requestedServices.size() == 0) ? new PrintService[0]
+ : (PrintService[]) requestedServices
+ .toArray(new PrintService[0]);
+ }
+
+ /*
+ * @see javax.print.PrintServiceLookup#getMultiDocPrintServices(javax.print.DocFlavor[]
+ * , javax.print.attribute.AttributeSet)
+ */
+ public MultiDocPrintService[] getMultiDocPrintServices(DocFlavor[] flavors,
+ AttributeSet attributes) {
+ // No multidoc print services available, yet.
+ return new MultiDocPrintService[0];
+ }
+
+ /*
+ * find all printers
+ */
+ private static String[] findPrintServices() {
+ ArrayList ippservices = new ArrayList();
+
+ /*
+ * First, find on localhost and servers from print.cups.servers property
+ * and add them to full list
+ */
+ String[] cupses = CUPSPrintServiceProvider.getCUPSServersByProperty();
+ for (int j = 0; j < cupses.length; j++) {
+ ippservices.addAll(findCUPSPrintServices(cupses[j]));
+ }
+
+ /*
+ * Then, check URLs from print.ipp.printers property and
+ * if is valid ipp printer add them to full list
+ */
+ String[] ippp = CUPSPrintServiceProvider.getIppPrintersByProperty();
+ for (int j = 0; j < ippp.length; j++) {
+ try {
+ URI ippuri = new URI(ippp[j]);
+ IppPrinter printer = new IppPrinter(ippuri);
+ IppResponse response;
+
+ response = printer.requestPrinterAttributes(
+ "printer-uri-supported", null);
+
+ Vector gg = response
+ .getGroupVector(IppAttributeGroup.TAG_GET_PRINTER_ATTRIBUTES);
+ if (gg != null) {
+ for (int i = 0, ii = gg.size(); i < ii; i++) {
+ IppAttributeGroup g = (IppAttributeGroup) gg.get(i);
+ int ai = g.findAttribute("printer-uri-supported");
+
+ if (ai >= 0) {
+ IppAttribute a = (IppAttribute) g.get(ai);
+ Vector v = a.getValue();
+ if (v.size() > 0) {
+ ippservices.add(new String((byte[]) v.get(0)));
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ if (verbose > 0) {
+ System.err.println("IPP url: " + ippp[j]);
+ e.printStackTrace();
+ } else {
+ // IGNORE - connection refused due to no server, etc.
+ }
+ }
+ }
+
+ // retun array of printers
+ return (String[]) ippservices.toArray(new String[0]);
+ }
+
+ /*
+ * find ipp printers on CUPS server 'cups'
+ */
+ public static ArrayList findCUPSPrintServices(String cups) {
+ ArrayList ippservices = new ArrayList();
+
+ URI cupsuri = null;
+ IppClient c = null;
+ IppRequest request;
+ IppResponse response;
+ IppAttributeGroup agroup;
+ Vector va = new Vector();
+
+ request = new IppRequest(1, 1, IppOperation.TAG_CUPS_GET_PRINTERS,
+ "utf-8", "en-us");
+ agroup = request.getGroup(IppAttributeGroup.TAG_OPERATION_ATTRIBUTES);
+ va.add("printer-uri-supported".getBytes());
+ agroup.add(new IppAttribute(IppAttribute.TAG_KEYWORD,
+ "requested-attributes", va));
+
+ try {
+ cupsuri = new URI(cups);
+ c = new IppClient(cupsuri);
+
+ response = c.request(request.getBytes());
+
+ Vector gg = response
+ .getGroupVector(IppAttributeGroup.TAG_GET_PRINTER_ATTRIBUTES);
+ if (gg != null) {
+ for (int i = 0, ii = gg.size(); i < ii; i++) {
+ IppAttributeGroup g = (IppAttributeGroup) gg.get(i);
+ int ai = g.findAttribute("printer-uri-supported");
+
+ if (ai >= 0) {
+ IppAttribute a = (IppAttribute) g.get(ai);
+ Vector v = a.getValue();
+ if (v.size() > 0) {
+ ippservices.add(new String((byte[]) v.get(0)));
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ if (verbose > 0) {
+ System.err.println("CUPS url: " + cups);
+ System.err.println("CUPS uri: " + cupsuri);
+ System.err.println("Ipp client: " + c);
+ System.err.println(request.toString());
+ e.printStackTrace();
+ } else {
+ // IGNORE - connection refused due to no server, etc.
+ }
+ }
+
+ return ippservices;
+ }
+
+ /*
+ * find default printer
+ * At first, try to find default printer on CUPS servers and return first found
+ * If failed, return first found IPP printer
+ * If failed return null
+ */
+ private static String findDefaultPrintService() {
+ String serviceName = null;
+
+ String[] cupses = CUPSPrintServiceProvider.getCUPSServersByProperty();
+ for (int i = 0; i < cupses.length; i++) {
+ try {
+ URI cupsuri = new URI(cupses[i]);
+ IppClient c = new IppClient(cupsuri);
+ IppRequest request;
+ IppResponse response;
+ IppAttributeGroup agroup;
+ Vector va = new Vector();
+
+ request = new IppRequest(1, 1,
+ IppOperation.TAG_CUPS_GET_DEFAULT, "utf-8", "en-us");
+ agroup = request
+ .getGroup(IppAttributeGroup.TAG_OPERATION_ATTRIBUTES);
+ va.add("printer-uri-supported".getBytes());
+ agroup.add(new IppAttribute(IppAttribute.TAG_KEYWORD,
+ "requested-attributes", va));
+
+ response = c.request(request.getBytes());
+
+ IppAttributeGroup g = response
+ .getGroup(IppAttributeGroup.TAG_GET_PRINTER_ATTRIBUTES);
+ if (g != null) {
+ int ai = g.findAttribute("printer-uri-supported");
+
+ if (ai >= 0) {
+ IppAttribute a = (IppAttribute) g.get(ai);
+ Vector v = a.getValue();
+ if (v.size() > 0) {
+ serviceName = new String((byte[]) v.get(0));
+ break;
+ }
+ }
+ }
+ } catch (URISyntaxException e) {
+ //e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ //e.printStackTrace();
+ }
+ }
+ if (serviceName != null && !serviceName.equals("")) {
+ return serviceName;
+ }
+
+ String[] ippp = CUPSPrintServiceProvider.getIppPrintersByProperty();
+ for (int i = 0; i < ippp.length; i++) {
+ try {
+ URI ippuri = new URI(ippp[i]);
+ IppClient c = new IppClient(ippuri);
+ IppRequest request;
+ IppResponse response;
+ IppAttributeGroup agroup;
+ Vector va = new Vector();
+
+ request = new IppRequest(1, 1,
+ IppOperation.GET_PRINTER_ATTRIBUTES, "utf-8", "en-us");
+ agroup = request
+ .getGroup(IppAttributeGroup.TAG_OPERATION_ATTRIBUTES);
+ va.add("printer-uri-supported".getBytes());
+ agroup.add(new IppAttribute(IppAttribute.TAG_KEYWORD,
+ "requested-attributes", va));
+
+ response = c.request(request.getBytes());
+
+ IppAttributeGroup g = response
+ .getGroup(IppAttributeGroup.TAG_GET_PRINTER_ATTRIBUTES);
+ if (g != null) {
+ int ai = g.findAttribute("printer-uri-supported");
+
+ if (ai >= 0) {
+ IppAttribute a = (IppAttribute) g.get(ai);
+ Vector v = a.getValue();
+ if (v.size() > 0) {
+ serviceName = new String((byte[]) v.get(0));
+ break;
+ }
+ }
+ }
+ } catch (URISyntaxException e) {
+ //e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ //e.printStackTrace();
+ }
+ }
+
+ return serviceName;
+ }
+
+ public static int isVerbose() {
+ return verbose;
+ }
+
+ public static void setVerbose(int newverbose) {
+ CUPSPrintServiceProvider.verbose = newverbose;
+ CUPSClient.setVerbose(newverbose);
+ }
+}
\ No newline at end of file
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/H-1609/modules/print/src/main/java/common/org/apache/harmony/x/print/cups/CUPSPrintServiceProvider.java
------------------------------------------------------------------------------
svn:executable = *