alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Win32PrintService.java)

This example Java source code file (Win32PrintService.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

arraylist, attribute, awt, class, devcap_color, docflavor, illegalargumentexception, mediaprintablearea, mediasizename, mediatray, net, network, print, printerresolution, printing, printserviceattributeset, string, util, win32mediasize, win32mediatray

The Win32PrintService.java Java example source code

/*
 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.print;

import java.awt.Window;
import java.awt.print.PrinterJob;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.ServiceUIFactory;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
import javax.print.attribute.standard.QueuedJobCount;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrinterState;
import javax.print.attribute.standard.PrinterStateReason;
import javax.print.attribute.standard.PrinterStateReasons;
import javax.print.attribute.standard.Severity;
import javax.print.attribute.standard.Sides;
import javax.print.attribute.standard.ColorSupported;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.SheetCollate;
import javax.print.event.PrintServiceAttributeListener;
import sun.awt.windows.WPrinterJob;

public class Win32PrintService implements PrintService, AttributeUpdater,
                                          SunPrinterJobService {

    public static MediaSize[] predefMedia = Win32MediaSize.getPredefMedia();

    private static final DocFlavor[] supportedFlavors = {
        DocFlavor.BYTE_ARRAY.GIF,
        DocFlavor.INPUT_STREAM.GIF,
        DocFlavor.URL.GIF,
        DocFlavor.BYTE_ARRAY.JPEG,
        DocFlavor.INPUT_STREAM.JPEG,
        DocFlavor.URL.JPEG,
        DocFlavor.BYTE_ARRAY.PNG,
        DocFlavor.INPUT_STREAM.PNG,
        DocFlavor.URL.PNG,
        DocFlavor.SERVICE_FORMATTED.PAGEABLE,
        DocFlavor.SERVICE_FORMATTED.PRINTABLE,
        DocFlavor.BYTE_ARRAY.AUTOSENSE,
        DocFlavor.URL.AUTOSENSE,
        DocFlavor.INPUT_STREAM.AUTOSENSE
    };

    /* let's try to support a few of these */
    private static final Class[] serviceAttrCats = {
        PrinterName.class,
        PrinterIsAcceptingJobs.class,
        QueuedJobCount.class,
        ColorSupported.class,
    };

    /*  it turns out to be inconvenient to store the other categories
     *  separately because many attributes are in multiple categories.
     */
    private static Class[] otherAttrCats = {
        JobName.class,
        RequestingUserName.class,
        Copies.class,
        Destination.class,
        OrientationRequested.class,
        PageRanges.class,
        Media.class,
        MediaPrintableArea.class,
        Fidelity.class,
        // We support collation on 2D printer jobs, even if the driver can't.
        SheetCollate.class,
        SunAlternateMedia.class,
        Chromaticity.class
    };


    /*
     * This table together with methods findWin32Media and
     * findMatchingMediaSizeNameMM are declared public as these are also
     * used in WPrinterJob.java.
     */
    public static final MediaSizeName[] dmPaperToPrintService = {
      MediaSizeName.NA_LETTER, MediaSizeName.NA_LETTER,
      MediaSizeName.TABLOID, MediaSizeName.LEDGER,
      MediaSizeName.NA_LEGAL, MediaSizeName.INVOICE,
      MediaSizeName.EXECUTIVE, MediaSizeName.ISO_A3,
      MediaSizeName.ISO_A4, MediaSizeName.ISO_A4,
      MediaSizeName.ISO_A5, MediaSizeName.JIS_B4,
      MediaSizeName.JIS_B5, MediaSizeName.FOLIO,
      MediaSizeName.QUARTO, MediaSizeName.NA_10X14_ENVELOPE,
      MediaSizeName.B, MediaSizeName.NA_LETTER,
      MediaSizeName.NA_NUMBER_9_ENVELOPE, MediaSizeName.NA_NUMBER_10_ENVELOPE,
      MediaSizeName.NA_NUMBER_11_ENVELOPE, MediaSizeName.NA_NUMBER_12_ENVELOPE,
      MediaSizeName.NA_NUMBER_14_ENVELOPE, MediaSizeName.C,
      MediaSizeName.D, MediaSizeName.E,
      MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.ISO_C5,
      MediaSizeName.ISO_C3, MediaSizeName.ISO_C4,
      MediaSizeName.ISO_C6, MediaSizeName.ITALY_ENVELOPE,
      MediaSizeName.ISO_B4, MediaSizeName.ISO_B5,
      MediaSizeName.ISO_B6, MediaSizeName.ITALY_ENVELOPE,
      MediaSizeName.MONARCH_ENVELOPE, MediaSizeName.PERSONAL_ENVELOPE,
      MediaSizeName.NA_10X15_ENVELOPE, MediaSizeName.NA_9X12_ENVELOPE,
      MediaSizeName.FOLIO, MediaSizeName.ISO_B4,
      MediaSizeName.JAPANESE_POSTCARD, MediaSizeName.NA_9X11_ENVELOPE,
    };

    private static final MediaTray[] dmPaperBinToPrintService = {
      MediaTray.TOP, MediaTray.BOTTOM, MediaTray.MIDDLE,
      MediaTray.MANUAL, MediaTray.ENVELOPE, Win32MediaTray.ENVELOPE_MANUAL,
      Win32MediaTray.AUTO, Win32MediaTray.TRACTOR,
      Win32MediaTray.SMALL_FORMAT, Win32MediaTray.LARGE_FORMAT,
      MediaTray.LARGE_CAPACITY, null, null,
      MediaTray.MAIN, Win32MediaTray.FORMSOURCE,
    };

    // from wingdi.h
    private static int DM_PAPERSIZE = 0x2;
    private static int DM_PRINTQUALITY = 0x400;
    private static int DM_YRESOLUTION = 0x2000;
    private static final int DMRES_MEDIUM = -3;
    private static final int DMRES_HIGH = -4;
    private static final int DMORIENT_LANDSCAPE = 2;
    private static final int DMDUP_VERTICAL = 2;
    private static final int DMDUP_HORIZONTAL = 3;
    private static final int DMCOLLATE_TRUE = 1;
    private static final int DMCOLOR_MONOCHROME = 1;
    private static final int DMCOLOR_COLOR = 2;


    // media sizes with indices above dmPaperToPrintService' length
    private static final int DMPAPER_A2 = 66;
    private static final int DMPAPER_A6 = 70;
    private static final int DMPAPER_B6_JIS = 88;


    // Bit settings for getPrinterCapabilities which matches that
    // of native getCapabilities in WPrinterJob.cpp
    private static final int DEVCAP_COLOR = 0x0001;
    private static final int DEVCAP_DUPLEX = 0x0002;
    private static final int DEVCAP_COLLATE = 0x0004;
    private static final int DEVCAP_QUALITY = 0x0008;
    private static final int DEVCAP_POSTSCRIPT = 0x0010;

    private String printer;
    private PrinterName name;
    private String port;

    transient private PrintServiceAttributeSet lastSet;
    transient private ServiceNotifier notifier = null;

    private MediaSizeName[] mediaSizeNames;
    private MediaPrintableArea[] mediaPrintables;
    private MediaTray[] mediaTrays;
    private PrinterResolution[] printRes;
    private HashMap mpaMap;
    private int nCopies;
    private int prnCaps;
    private int[] defaultSettings;

    private boolean gotTrays;
    private boolean gotCopies;
    private boolean mediaInitialized;
    private boolean mpaListInitialized;

    private ArrayList idList;
    private MediaSize[] mediaSizes;

    private boolean isInvalid;

    Win32PrintService(String name) {
        if (name == null) {
            throw new IllegalArgumentException("null printer name");
        }
        printer = name;

        // initialize flags
        mediaInitialized = false;
        gotTrays = false;
        gotCopies = false;
        isInvalid = false;
        printRes = null;
        prnCaps = 0;
        defaultSettings = null;
        port = null;
    }

    public void invalidateService() {
        isInvalid = true;
    }

    public String getName() {
        return printer;
    }

    private PrinterName getPrinterName() {
        if (name == null) {
            name = new PrinterName(printer, null);
        }
        return name;
    }

    public int findPaperID(MediaSizeName msn) {
        if (msn instanceof Win32MediaSize) {
            Win32MediaSize winMedia = (Win32MediaSize)msn;
            return winMedia.getDMPaper();
        } else {
            for (int id=0; id<dmPaperToPrintService.length;id++) {
                if (dmPaperToPrintService[id].equals(msn)) {
                    return id+1; // DMPAPER_LETTER == 1
                }
            }
            if (msn.equals(MediaSizeName.ISO_A2)) {
                return DMPAPER_A2;
            }
            else if (msn.equals(MediaSizeName.ISO_A6)) {
                return DMPAPER_A6;
            }
            else if (msn.equals(MediaSizeName.JIS_B6)) {
                return DMPAPER_B6_JIS;
            }
        }

        // If not found in predefined Windows ID, then we search through
        // the returned IDs of the driver because they can define their own
        // unique IDs.
        initMedia();

        if ((idList != null) && (mediaSizes != null) &&
            (idList.size() == mediaSizes.length)) {
            for (int i=0; i< idList.size(); i++) {
                if (mediaSizes[i].getMediaSizeName() == msn) {
                    return ((Integer)idList.get(i)).intValue();
                }
            }
        }
        return 0;
    }

    public int findTrayID(MediaTray tray) {

        getMediaTrays(); // make sure they are initialised.

        if (tray instanceof Win32MediaTray) {
            Win32MediaTray winTray = (Win32MediaTray)tray;
            return winTray.getDMBinID();
        }
        for (int id=0; id<dmPaperBinToPrintService.length; id++) {
            if (tray.equals(dmPaperBinToPrintService[id])) {
                return id+1; // DMBIN_FIRST = 1;
            }
        }
        return 0; // didn't find the tray
    }

    public MediaTray findMediaTray(int dmBin) {
        if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {
            return dmPaperBinToPrintService[dmBin-1];
        }
        MediaTray[] trays = getMediaTrays();
        if (trays != null) {
            for (int i=0;i<trays.length;i++) {
                if(trays[i] instanceof Win32MediaTray) {
                    Win32MediaTray win32Tray = (Win32MediaTray)trays[i];
                    if (win32Tray.winID == dmBin) {
                        return win32Tray;
                    }
                }
            }
        }
        return Win32MediaTray.AUTO;
    }

    public MediaSizeName findWin32Media(int dmIndex) {
        if (dmIndex >= 1 && dmIndex <= dmPaperToPrintService.length) {
            return dmPaperToPrintService[dmIndex - 1];
        }
        switch(dmIndex) {
            /* matching media sizes with indices beyond
               dmPaperToPrintService's length */
            case DMPAPER_A2:
                return MediaSizeName.ISO_A2;
            case DMPAPER_A6:
                return MediaSizeName.ISO_A6;
            case DMPAPER_B6_JIS:
                return MediaSizeName.JIS_B6;
            default:
                return null;
        }
    }

    private boolean addToUniqueList(ArrayList msnList, MediaSizeName mediaName) {
        MediaSizeName msn;
        for (int i=0; i< msnList.size(); i++) {
            msn = (MediaSizeName)msnList.get(i);
            if (msn == mediaName) {
                return false;
            }
        }
        msnList.add(mediaName);
        return true;
    }

    private synchronized void initMedia() {
        if (mediaInitialized == true) {
            return;
        }
        mediaInitialized = true;
        int[] media = getAllMediaIDs(printer, getPort());
        if (media == null) {
            return;
        }

        ArrayList msnList = new ArrayList();
        ArrayList<Win32MediaSize> trailingWmsList = new ArrayList();
        ArrayList printableList = new ArrayList();
        MediaSizeName mediaName;
        boolean added;
        boolean queryFailure = false;
        float[] prnArea;

        // Get all mediaSizes supported by the printer.
        // We convert media to ArrayList idList and pass this to the
        // function for getting mediaSizes.
        // This is to ensure that mediaSizes and media IDs have 1-1 correspondence.
        // We remove from ID list any invalid mediaSize.  Though this is rare,
        // it happens in HP 4050 German driver.

        idList = new ArrayList();
        for (int i=0; i < media.length; i++) {
            idList.add(Integer.valueOf(media[i]));
        }

        ArrayList<String> dmPaperNameList = new ArrayList();
        mediaSizes = getMediaSizes(idList, media, dmPaperNameList);
        for (int i = 0; i < idList.size(); i++) {

            // match Win ID with our predefined ID using table
            mediaName = findWin32Media(((Integer)idList.get(i)).intValue());
            // Verify that this standard size is the same size as that
            // reported by the driver. This should be the case except when
            // the driver is mis-using a standard windows paper ID.
            if (mediaName != null &&
                idList.size() == mediaSizes.length) {
                MediaSize win32Size = MediaSize.getMediaSizeForName(mediaName);
                MediaSize driverSize = mediaSizes[i];
                int error = 2540; // == 1/10"
                if (Math.abs(win32Size.getX(1)-driverSize.getX(1)) > error ||
                    Math.abs(win32Size.getY(1)-driverSize.getY(1)) > error)
                {
                   mediaName = null;
                }
            }
            boolean dmPaperIDMatched = (mediaName != null);

            // No match found, then we get the MediaSizeName out of the MediaSize
            // This requires 1-1 correspondence, lengths must be checked.
            if ((mediaName == null) && (idList.size() == mediaSizes.length)) {
                mediaName = mediaSizes[i].getMediaSizeName();
            }

            // Add mediaName to the msnList
            added = false;
            if (mediaName != null) {
                added = addToUniqueList(msnList, mediaName);
            }
            if ((!dmPaperIDMatched || !added) && (idList.size() == dmPaperNameList.size())) {
                /* The following block allows to add such media names to the list, whose sizes
                 * matched with media sizes predefined in JDK, while whose paper IDs did not,
                 * or whose sizes and paper IDs both did not match with any predefined in JDK.
                 */
                Win32MediaSize wms = Win32MediaSize.findMediaName(dmPaperNameList.get(i));
                if ((wms == null) && (idList.size() == mediaSizes.length)) {
                    wms = new Win32MediaSize(dmPaperNameList.get(i), (Integer)idList.get(i));
                    mediaSizes[i] = new MediaSize(mediaSizes[i].getX(MediaSize.MM),
                        mediaSizes[i].getY(MediaSize.MM), MediaSize.MM, wms);
                }
                if ((wms != null) && (wms != mediaName)) {
                    if (!added) {
                        added = addToUniqueList(msnList, mediaName = wms);
                    } else {
                        trailingWmsList.add(wms);
                    }
                }
            }
        }
        for (Win32MediaSize wms : trailingWmsList) {
            added = addToUniqueList(msnList, wms);
        }

        // init mediaSizeNames
        mediaSizeNames = new MediaSizeName[msnList.size()];
        msnList.toArray(mediaSizeNames);
    }


    /*
     * Gets a list of MediaPrintableAreas using a call to native function.
     *  msn is MediaSizeName used to get a specific printable area.  If null,
     *  it will get all the supported MediPrintableAreas.
     */
    private synchronized MediaPrintableArea[] getMediaPrintables(MediaSizeName msn)
    {
        if (msn == null)  {
            if (mpaListInitialized == true) {
                return mediaPrintables;
            }
        } else {
            // get from cached mapping of MPAs
            if (mpaMap != null && (mpaMap.get(msn) != null)) {
                MediaPrintableArea[] mpaArr = new MediaPrintableArea[1];
                mpaArr[0] = (MediaPrintableArea)mpaMap.get(msn);
                return mpaArr;
            }
        }

        initMedia();

        if ((mediaSizeNames == null) || (mediaSizeNames.length == 0)) {
            return null;
        }

        MediaSizeName[] loopNames;
        if (msn != null) {
            loopNames = new MediaSizeName[1];
            loopNames[0] = msn;
        } else {
            loopNames = mediaSizeNames;
        }

        if (mpaMap == null) {
            mpaMap = new HashMap();
        }

        for (int i=0; i < loopNames.length; i++) {
            MediaSizeName mediaName = loopNames[i];

            if (mpaMap.get(mediaName) != null) {
                continue;
             }

            if (mediaName != null) {
                int defPaper = findPaperID(mediaName);
                float[] prnArea = (defPaper != 0) ? getMediaPrintableArea(printer, defPaper) : null;
                MediaPrintableArea printableArea = null;
                if (prnArea != null) {
                    try {
                        printableArea = new MediaPrintableArea(prnArea[0],
                                                               prnArea[1],
                                                               prnArea[2],
                                                               prnArea[3],
                                                 MediaPrintableArea.INCH);

                        mpaMap.put(mediaName, printableArea);
                    }
                    catch (IllegalArgumentException e) {
                    }
                } else {
                    // if getting  MPA failed, we use MediaSize
                    MediaSize ms =
                        MediaSize.getMediaSizeForName((MediaSizeName)mediaName);

                    if (ms != null) {
                        try {
                            printableArea = new MediaPrintableArea(0, 0,
                                                     ms.getX(MediaSize.INCH),
                                                     ms.getY(MediaSize.INCH),
                                                     MediaPrintableArea.INCH);
                            mpaMap.put(mediaName, printableArea);
                        } catch (IllegalArgumentException e) {
                        }
                    }
                }
            } //mediaName != null
        }

       if (mpaMap.size() == 0) {
           return null;
       }

       if (msn != null) {
           if (mpaMap.get(msn) == null) {
               return null;
           }
           MediaPrintableArea[] mpaArr = new MediaPrintableArea[1];
           // by this time, we've already gotten the desired MPA
           mpaArr[0] = (MediaPrintableArea)mpaMap.get(msn);
           return mpaArr;
       } else {
           mediaPrintables = (MediaPrintableArea[])mpaMap.values().toArray(new MediaPrintableArea[0]);
           mpaListInitialized = true;
           return mediaPrintables;
       }
    }


    private synchronized MediaTray[] getMediaTrays() {
        if (gotTrays == true && mediaTrays != null) {
            return mediaTrays;
        }
        String prnPort = getPort();
        int[] mediaTr = getAllMediaTrays(printer, prnPort);
        String[] winMediaTrayNames = getAllMediaTrayNames(printer, prnPort);

        if ((mediaTr == null) || (winMediaTrayNames == null)){
            return null;
        }

        /* first count how many valid bins there are so we can allocate
         * an array of the correct size
         */
        int nTray = 0;
        for (int i=0; i < mediaTr.length ; i++) {
            if (mediaTr[i] > 0) nTray++;
        }

        MediaTray[] arr = new MediaTray[nTray];
        int dmBin;

        /* Some drivers in Win 7 don't have the same length for DC_BINS and
         * DC_BINNAMES so there is no guarantee that lengths of mediaTr and
         * winMediaTrayNames are equal. To avoid getting ArrayIndexOutOfBounds,
         * we need to make sure we get the minimum of the two.
         */

        for (int i = 0, j=0; i < Math.min(mediaTr.length, winMediaTrayNames.length); i++) {
            dmBin = mediaTr[i];
            if (dmBin > 0) {
                // check for unsupported DMBINs and create new Win32MediaTray
                if ((dmBin > dmPaperBinToPrintService.length)
                    || (dmPaperBinToPrintService[dmBin-1] == null)) {
                    arr[j++] = new Win32MediaTray(dmBin, winMediaTrayNames[i]);
                } else {
                    arr[j++] = dmPaperBinToPrintService[dmBin-1];
                }
            }
            // no else - For invalid ids, just ignore it because assigning a "default"
            // value may result in duplicate trays.
        }
        mediaTrays = arr;
        gotTrays = true;
        return mediaTrays;
    }

    private boolean isSameSize(float w1, float h1, float w2, float h2) {
        float diffX = w1 - w2;
        float diffY = h1 - h2;
        // Get diff of reverse dimensions
        // EPSON Stylus COLOR 860 reverses envelope's width & height
        float diffXrev = w1 - h2;
        float diffYrev = h1 - w2;

        if (((Math.abs(diffX)<=1) && (Math.abs(diffY)<=1)) ||
            ((Math.abs(diffXrev)<=1) && (Math.abs(diffYrev)<=1))){
          return true;
        } else {
          return false;
        }
    }

    public MediaSizeName findMatchingMediaSizeNameMM (float w, float h){
        if (predefMedia != null) {
            for (int k=0; k<predefMedia.length;k++) {
                if (predefMedia[k] == null) {
                    continue;
                }

                if (isSameSize(predefMedia[k].getX(MediaSize.MM),
                               predefMedia[k].getY(MediaSize.MM),
                               w, h)) {
                  return predefMedia[k].getMediaSizeName();
                }
            }
        }
        return null;
    }


    private MediaSize[] getMediaSizes(ArrayList idList, int[] media, ArrayList<String> dmPaperNameList) {
        if (dmPaperNameList == null) {
            dmPaperNameList = new ArrayList<String>();
        }

        String prnPort = getPort();
        int[] mediaSz = getAllMediaSizes(printer, prnPort);
        String[] winMediaNames = getAllMediaNames(printer, prnPort);
        MediaSizeName msn = null;
        MediaSize ms = null;
        float wid, ht;

        if ((mediaSz == null) || (winMediaNames == null)) {
            return null;
        }

        int nMedia = mediaSz.length/2;
        ArrayList msList = new ArrayList();

        for (int i = 0; i < nMedia; i++, ms=null) {
            wid = mediaSz[i*2]/10f;
            ht = mediaSz[i*2+1]/10f;

            // Make sure to validate wid & ht.
            // HP LJ 4050 (german) causes IAE in Sonderformat paper, wid & ht
            // returned is not constant.
            if ((wid <= 0) || (ht <= 0)) {
                //Remove corresponding ID from list
                if (nMedia == media.length) {
                    Integer remObj = Integer.valueOf(media[i]);
                    idList.remove(idList.indexOf(remObj));
                }
                continue;
            }
            // Find matching media using dimensions.
            // This call matches only with our own predefined sizes.
            msn = findMatchingMediaSizeNameMM(wid, ht);
            if (msn != null) {
                ms = MediaSize.getMediaSizeForName(msn);
            }

            if (ms != null) {
                msList.add(ms);
                dmPaperNameList.add(winMediaNames[i]);
            } else {
                Win32MediaSize wms = Win32MediaSize.findMediaName(winMediaNames[i]);
                if (wms == null) {
                    wms = new Win32MediaSize(winMediaNames[i], media[i]);
                }
                try {
                    ms = new MediaSize(wid, ht, MediaSize.MM, wms);
                    msList.add(ms);
                    dmPaperNameList.add(winMediaNames[i]);
                } catch(IllegalArgumentException e) {
                    if (nMedia == media.length) {
                        Integer remObj = Integer.valueOf(media[i]);
                        idList.remove(idList.indexOf(remObj));
                    }
                }
            }
        }

        MediaSize[] arr2 = new MediaSize[msList.size()];
        msList.toArray(arr2);

        return arr2;
    }

    private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
        if (getJobStatus(printer, 2) != 1) {
            return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
        }
        else {
            return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
        }
    }

    private PrinterState getPrinterState() {
        if (isInvalid) {
            return PrinterState.STOPPED;
        } else {
            return null;
        }
    }

    private PrinterStateReasons getPrinterStateReasons() {
        if (isInvalid) {
            PrinterStateReasons psr = new PrinterStateReasons();
            psr.put(PrinterStateReason.SHUTDOWN, Severity.ERROR);
            return psr;
        } else {
            return null;
        }
    }

    private QueuedJobCount getQueuedJobCount() {

        int count = getJobStatus(printer, 1);
        if (count != -1) {
            return new QueuedJobCount(count);
        }
        else {
            return new QueuedJobCount(0);
        }
    }

    private boolean isSupportedCopies(Copies copies) {
        synchronized (this) {
            if (gotCopies == false) {
                nCopies = getCopiesSupported(printer, getPort());
                gotCopies = true;
            }
        }
        int numCopies = copies.getValue();
        return (numCopies > 0 && numCopies <= nCopies);
    }

    private boolean isSupportedMedia(MediaSizeName msn) {

        initMedia();

        if (mediaSizeNames != null) {
            for (int i=0; i<mediaSizeNames.length; i++) {
                if (msn.equals(mediaSizeNames[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isSupportedMediaPrintableArea(MediaPrintableArea mpa) {

        getMediaPrintables(null);

        if (mediaPrintables != null) {
            for (int i=0; i<mediaPrintables.length; i++) {
                if (mpa.equals(mediaPrintables[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isSupportedMediaTray(MediaTray msn) {
        MediaTray[] trays = getMediaTrays();

        if (trays != null) {
            for (int i=0; i<trays.length; i++) {
                if (msn.equals(trays[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    private int getPrinterCapabilities() {
        if (prnCaps == 0) {
            prnCaps = getCapabilities(printer, getPort());
        }
        return prnCaps;
    }

    private String getPort() {
        if (port == null) {
            port = getPrinterPort(printer);
        }
        return port;
    }

   /*
    * NOTE: defaults indices must match those in WPrinterJob.cpp
    */
    private int[] getDefaultPrinterSettings() {
        if (defaultSettings == null) {
            defaultSettings = getDefaultSettings(printer, getPort());
        }
        return defaultSettings;
    }

    private PrinterResolution[] getPrintResolutions() {
        if (printRes == null) {
            int[] prnRes = getAllResolutions(printer, getPort());
            if (prnRes == null) {
                printRes = new PrinterResolution[0];
            } else {
                int nRes = prnRes.length/2;

                ArrayList arrList = new ArrayList();
                PrinterResolution pr;

                for (int i=0; i<nRes; i++) {
                  try {
                        pr = new PrinterResolution(prnRes[i*2],
                                       prnRes[i*2+1], PrinterResolution.DPI);
                        arrList.add(pr);
                    } catch (IllegalArgumentException e) {
                    }
                }

                printRes = (PrinterResolution[])arrList.toArray(
                                        new PrinterResolution[arrList.size()]);
            }
        }
        return printRes;
    }

    private boolean isSupportedResolution(PrinterResolution res) {
        PrinterResolution[] supportedRes = getPrintResolutions();
        if (supportedRes != null) {
            for (int i=0; i<supportedRes.length; i++) {
                if (res.equals(supportedRes[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    public DocPrintJob createPrintJob() {
      SecurityManager security = System.getSecurityManager();
      if (security != null) {
        security.checkPrintJobAccess();
      }
        return new Win32PrintJob(this);
    }

    private PrintServiceAttributeSet getDynamicAttributes() {
        PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
        attrs.add(getPrinterIsAcceptingJobs());
        attrs.add(getQueuedJobCount());
        return attrs;
    }

    public PrintServiceAttributeSet getUpdatedAttributes() {
        PrintServiceAttributeSet currSet = getDynamicAttributes();
        if (lastSet == null) {
            lastSet = currSet;
            return AttributeSetUtilities.unmodifiableView(currSet);
        } else {
            PrintServiceAttributeSet updates =
                new HashPrintServiceAttributeSet();
            Attribute []attrs =  currSet.toArray();
            for (int i=0; i<attrs.length; i++) {
                Attribute attr = attrs[i];
                if (!lastSet.containsValue(attr)) {
                    updates.add(attr);
                }
            }
            lastSet = currSet;
            return AttributeSetUtilities.unmodifiableView(updates);
        }
    }

    public void wakeNotifier() {
        synchronized (this) {
            if (notifier != null) {
                notifier.wake();
            }
        }
    }

    public void addPrintServiceAttributeListener(PrintServiceAttributeListener
                                                 listener) {
        synchronized (this) {
            if (listener == null) {
                return;
            }
            if (notifier == null) {
                notifier = new ServiceNotifier(this);
            }
            notifier.addListener(listener);
        }
    }

    public void removePrintServiceAttributeListener(
                                      PrintServiceAttributeListener listener) {
        synchronized (this) {
            if (listener == null || notifier == null ) {
                return;
            }
            notifier.removeListener(listener);
            if (notifier.isEmpty()) {
                notifier.stopNotifier();
                notifier = null;
            }
        }
    }

    public <T extends PrintServiceAttribute> T
        getAttribute(Class<T> category)
    {
        if (category == null) {
            throw new NullPointerException("category");
        }
        if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {
            throw new IllegalArgumentException("Not a PrintServiceAttribute");
        }
        if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return (T)ColorSupported.SUPPORTED;
            } else {
                return (T)ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == PrinterName.class) {
            return (T)getPrinterName();
        } else if (category == PrinterState.class) {
            return (T)getPrinterState();
        } else if (category == PrinterStateReasons.class) {
            return (T)getPrinterStateReasons();
        } else if (category == QueuedJobCount.class) {
            return (T)getQueuedJobCount();
        } else if (category == PrinterIsAcceptingJobs.class) {
            return (T)getPrinterIsAcceptingJobs();
        } else {
            return null;
        }
    }

    public PrintServiceAttributeSet getAttributes() {

        PrintServiceAttributeSet attrs = new  HashPrintServiceAttributeSet();
        attrs.add(getPrinterName());
        attrs.add(getPrinterIsAcceptingJobs());
        PrinterState prnState = getPrinterState();
        if (prnState != null) {
            attrs.add(prnState);
        }
        PrinterStateReasons prnStateReasons = getPrinterStateReasons();
        if (prnStateReasons != null) {
            attrs.add(prnStateReasons);
        }
        attrs.add(getQueuedJobCount());
        int caps = getPrinterCapabilities();
        if ((caps & DEVCAP_COLOR) != 0) {
            attrs.add(ColorSupported.SUPPORTED);
        } else {
            attrs.add(ColorSupported.NOT_SUPPORTED);
        }

        return AttributeSetUtilities.unmodifiableView(attrs);
    }

    public DocFlavor[] getSupportedDocFlavors() {
        int len = supportedFlavors.length;
        DocFlavor[] supportedDocFlavors;
        int caps = getPrinterCapabilities();
        // doc flavors supported
        // if PostScript is supported
        if ((caps & DEVCAP_POSTSCRIPT) != 0) {
            supportedDocFlavors = new DocFlavor[len+3];
            System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);
            supportedDocFlavors[len] = DocFlavor.BYTE_ARRAY.POSTSCRIPT;
            supportedDocFlavors[len+1] = DocFlavor.INPUT_STREAM.POSTSCRIPT;
            supportedDocFlavors[len+2] = DocFlavor.URL.POSTSCRIPT;
        } else {
            supportedDocFlavors = new DocFlavor[len];
            System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);
        }
        return supportedDocFlavors;
    }

    public boolean isDocFlavorSupported(DocFlavor flavor) {
        /* To avoid a native query which may be time-consuming
         * do not invoke native unless postscript support is being queried.
         * Instead just check the ones we 'always' support
         */
        DocFlavor[] supportedDocFlavors;
        if (isPostScriptFlavor(flavor)) {
            supportedDocFlavors = getSupportedDocFlavors();
        } else {
            supportedDocFlavors = supportedFlavors;
        }
        for (int f=0; f<supportedDocFlavors.length; f++) {
            if (flavor.equals(supportedDocFlavors[f])) {
                return true;
            }
        }
        return false;
    }

    public Class<?>[] getSupportedAttributeCategories() {
        ArrayList categList = new ArrayList(otherAttrCats.length+3);
        for (int i=0; i < otherAttrCats.length; i++) {
            categList.add(otherAttrCats[i]);
        }

        int caps = getPrinterCapabilities();

        if ((caps & DEVCAP_DUPLEX) != 0) {
            categList.add(Sides.class);
        }

        if ((caps & DEVCAP_QUALITY) != 0) {
            int[] defaults = getDefaultPrinterSettings();
            // Added check: if supported, we should be able to get the default.
            if ((defaults[3] >= DMRES_HIGH) && (defaults[3] < 0)) {
                categList.add(PrintQuality.class);
            }
        }

        PrinterResolution[] supportedRes = getPrintResolutions();
        if ((supportedRes!=null) && (supportedRes.length>0)) {
            categList.add(PrinterResolution.class);
        }

        return (Class[])categList.toArray(new Class[categList.size()]);
    }

    public boolean
        isAttributeCategorySupported(Class<? extends Attribute> category)
    {

        if (category == null) {
            throw new NullPointerException("null category");
        }

        if (!(Attribute.class.isAssignableFrom(category))) {
            throw new IllegalArgumentException(category +
                                               " is not an Attribute");
        }

        Class[] classList = getSupportedAttributeCategories();
        for (int i = 0; i < classList.length; i++) {
            if (category.equals(classList[i])) {
                return true;
            }
        }

        return false;
    }

    public Object
        getDefaultAttributeValue(Class<? extends Attribute> category)
    {
        if (category == null) {
            throw new NullPointerException("null category");
        }
        if (!Attribute.class.isAssignableFrom(category)) {
            throw new IllegalArgumentException(category +
                                               " is not an Attribute");
        }

        if (!isAttributeCategorySupported(category)) {
            return null;
        }

        int[] defaults = getDefaultPrinterSettings();
        // indices must match those in WPrinterJob.cpp
        int defPaper = defaults[0];
        int defYRes = defaults[2];
        int defQuality = defaults[3];
        int defCopies = defaults[4];
        int defOrient = defaults[5];
        int defSides = defaults[6];
        int defCollate = defaults[7];
        int defColor = defaults[8];

        if (category == Copies.class) {
            if (defCopies > 0) {
                return new Copies(defCopies);
            } else {
                return new Copies(1);
            }
        } else if (category == Chromaticity.class) {
            if (defColor == DMCOLOR_COLOR) {
                return Chromaticity.COLOR;
            } else {
                return Chromaticity.MONOCHROME;
            }
        } else if (category == JobName.class) {
            return new JobName("Java Printing", null);
        } else if (category == OrientationRequested.class) {
            if (defOrient == DMORIENT_LANDSCAPE) {
                return OrientationRequested.LANDSCAPE;
            } else {
                return OrientationRequested.PORTRAIT;
            }
        } else if (category == PageRanges.class) {
            return new PageRanges(1, Integer.MAX_VALUE);
        } else if (category == Media.class) {
            MediaSizeName msn = findWin32Media(defPaper);
            if (msn != null) {
                if (!isSupportedMedia(msn) && mediaSizeNames != null) {
                    msn = mediaSizeNames[0];
                    defPaper = findPaperID(msn);
                }
                return msn;
             } else {
                 initMedia();
                 if ((mediaSizeNames != null) && (mediaSizeNames.length > 0)) {
                     // if 'mediaSizeNames' is not null, idList and mediaSizes
                     // cannot be null but to be safe, add a check
                     if ((idList != null) && (mediaSizes != null) &&
                         (idList.size() == mediaSizes.length)) {
                         Integer defIdObj = Integer.valueOf(defPaper);
                         int index = idList.indexOf(defIdObj);
                         if (index>=0 && index<mediaSizes.length) {
                             return mediaSizes[index].getMediaSizeName();
                         }
                     }

                     return mediaSizeNames[0];
                 }
             }
        } else if (category == MediaPrintableArea.class) {
            /* Verify defPaper */
            MediaSizeName msn = findWin32Media(defPaper);
            if (msn != null &&
                !isSupportedMedia(msn) && mediaSizeNames != null) {
                defPaper = findPaperID(mediaSizeNames[0]);
            }
            float[] prnArea = getMediaPrintableArea(printer, defPaper);
            if (prnArea != null) {
                MediaPrintableArea printableArea = null;
                try {
                    printableArea = new MediaPrintableArea(prnArea[0],
                                                           prnArea[1],
                                                           prnArea[2],
                                                           prnArea[3],
                                                           MediaPrintableArea.INCH);
                } catch (IllegalArgumentException e) {
                }
                return printableArea;
            }
            return null;
        } else if (category == SunAlternateMedia.class) {
            return null;
        } else if (category == Destination.class) {
            try {
                return new Destination((new File("out.prn")).toURI());
            } catch (SecurityException se) {
                try {
                    return new Destination(new URI("file:out.prn"));
                } catch (URISyntaxException e) {
                    return null;
                }
            }
        } else if (category == Sides.class) {
            switch(defSides) {
            case DMDUP_VERTICAL :
                return Sides.TWO_SIDED_LONG_EDGE;
            case DMDUP_HORIZONTAL :
                return Sides.TWO_SIDED_SHORT_EDGE;
            default :
                return Sides.ONE_SIDED;
            }
        } else if (category == PrinterResolution.class) {
            int yRes = defYRes;
            int xRes = defQuality;
            if ((xRes < 0) || (yRes < 0)) {
                int res = (yRes > xRes) ? yRes : xRes;
                if (res > 0) {
                 return new PrinterResolution(res, res, PrinterResolution.DPI);
                }
            }
            else {
               return new PrinterResolution(xRes, yRes, PrinterResolution.DPI);
            }
        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return ColorSupported.SUPPORTED;
            } else {
                return ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == PrintQuality.class) {
            if ((defQuality < 0) && (defQuality >= DMRES_HIGH)) {
                switch (defQuality) {
                case DMRES_HIGH:
                    return PrintQuality.HIGH;
                case DMRES_MEDIUM:
                    return PrintQuality.NORMAL;
                default:
                    return PrintQuality.DRAFT;
                }
            }
        } else if (category == RequestingUserName.class) {
            String userName = "";
            try {
              userName = System.getProperty("user.name", "");
            } catch (SecurityException se) {
            }
            return new RequestingUserName(userName, null);
        } else if (category == SheetCollate.class) {
            if (defCollate == DMCOLLATE_TRUE) {
                return SheetCollate.COLLATED;
            } else {
                return SheetCollate.UNCOLLATED;
            }
        } else if (category == Fidelity.class) {
            return Fidelity.FIDELITY_FALSE;
        }
        return null;
    }

    private boolean isPostScriptFlavor(DocFlavor flavor) {
        if (flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT) ||
            flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) ||
            flavor.equals(DocFlavor.URL.POSTSCRIPT)) {
            return true;
        }
        else {
            return false;
        }
    }

    private boolean isPSDocAttr(Class category) {
        if (category == OrientationRequested.class || category == Copies.class) {
                return true;
        }
        else {
            return false;
        }
    }

    private boolean isAutoSense(DocFlavor flavor) {
        if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE) ||
            flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE) ||
            flavor.equals(DocFlavor.URL.AUTOSENSE)) {
            return true;
        }
        else {
            return false;
        }
    }

    public Object
        getSupportedAttributeValues(Class<? extends Attribute> category,
                                    DocFlavor flavor,
                                    AttributeSet attributes)
    {
        if (category == null) {
            throw new NullPointerException("null category");
        }
        if (!Attribute.class.isAssignableFrom(category)) {
            throw new IllegalArgumentException(category +
                                             " does not implement Attribute");
        }
        if (flavor != null) {
            if (!isDocFlavorSupported(flavor)) {
                throw new IllegalArgumentException(flavor +
                                                  " is an unsupported flavor");
                // if postscript & category is already specified within the
                //  PostScript data we return null
            } else if (isAutoSense(flavor) ||(isPostScriptFlavor(flavor) &&
                       (isPSDocAttr(category)))){
                return null;
            }
        }
        if (!isAttributeCategorySupported(category)) {
            return null;
        }

        if (category == JobName.class) {
            return new JobName("Java Printing", null);
        } else if (category == RequestingUserName.class) {
          String userName = "";
          try {
            userName = System.getProperty("user.name", "");
          } catch (SecurityException se) {
          }
            return new RequestingUserName(userName, null);
        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return ColorSupported.SUPPORTED;
            } else {
                return ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == Chromaticity.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                int caps = getPrinterCapabilities();
                if ((caps & DEVCAP_COLOR) == 0) {
                    Chromaticity []arr = new Chromaticity[1];
                    arr[0] = Chromaticity.MONOCHROME;
                    return (arr);
                } else {
                    Chromaticity []arr = new Chromaticity[2];
                    arr[0] = Chromaticity.MONOCHROME;
                    arr[1] = Chromaticity.COLOR;
                    return (arr);
                }
            } else {
                return null;
            }
        } else if (category == Destination.class) {
            try {
                return new Destination((new File("out.prn")).toURI());
            } catch (SecurityException se) {
                try {
                    return new Destination(new URI("file:out.prn"));
                } catch (URISyntaxException e) {
                    return null;
                }
            }
        } else if (category == OrientationRequested.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                OrientationRequested []arr = new OrientationRequested[3];
                arr[0] = OrientationRequested.PORTRAIT;
                arr[1] = OrientationRequested.LANDSCAPE;
                arr[2] = OrientationRequested.REVERSE_LANDSCAPE;
                return arr;
            } else {
                return null;
            }
        } else if ((category == Copies.class) ||
                   (category == CopiesSupported.class)) {
            synchronized (this) {
                if (gotCopies == false) {
                    nCopies = getCopiesSupported(printer, getPort());
                    gotCopies = true;
                }
            }
            return new CopiesSupported(1, nCopies);
        } else if (category == Media.class) {

            initMedia();

            int len = (mediaSizeNames == null) ? 0 : mediaSizeNames.length;

            MediaTray[] trays = getMediaTrays();

            len += (trays == null) ? 0 : trays.length;

            Media []arr = new Media[len];
            if (mediaSizeNames != null) {
                System.arraycopy(mediaSizeNames, 0, arr,
                                 0, mediaSizeNames.length);
            }
            if (trays != null) {
                System.arraycopy(trays, 0, arr,
                                 len - trays.length, trays.length);
            }
            return arr;
        } else if (category == MediaPrintableArea.class) {
            // if getting printable area for a specific media size
            Media mediaName = null;
            if ((attributes != null) &&
                ((mediaName =
                  (Media)attributes.get(Media.class)) != null)) {

                if (!(mediaName instanceof MediaSizeName)) {
                    // if an instance of MediaTray, fall thru returning
                    // all MediaPrintableAreas
                    mediaName = null;
                }
            }

            MediaPrintableArea[] mpas =
                                  getMediaPrintables((MediaSizeName)mediaName);
            if (mpas != null) {
                MediaPrintableArea[] arr = new MediaPrintableArea[mpas.length];
                System.arraycopy(mpas, 0, arr, 0, mpas.length);
                return arr;
            } else {
                return null;
            }
        } else if (category == SunAlternateMedia.class) {
            return new SunAlternateMedia(
                              (Media)getDefaultAttributeValue(Media.class));
        } else if (category == PageRanges.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
                PageRanges []arr = new PageRanges[1];
                arr[0] = new PageRanges(1, Integer.MAX_VALUE);
                return arr;
            } else {
                return null;
            }
        } else if (category == PrinterResolution.class) {
            PrinterResolution[] supportedRes = getPrintResolutions();
            if (supportedRes == null) {
                return null;
            }
            PrinterResolution []arr =
                new PrinterResolution[supportedRes.length];
            System.arraycopy(supportedRes, 0, arr, 0, supportedRes.length);
            return arr;
        } else if (category == Sides.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
                Sides []arr = new Sides[3];
                arr[0] = Sides.ONE_SIDED;
                arr[1] = Sides.TWO_SIDED_LONG_EDGE;
                arr[2] = Sides.TWO_SIDED_SHORT_EDGE;
                return arr;
            } else {
                return null;
            }
        } else if (category == PrintQuality.class) {
            PrintQuality []arr = new PrintQuality[3];
            arr[0] = PrintQuality.DRAFT;
            arr[1] = PrintQuality.HIGH;
            arr[2] = PrintQuality.NORMAL;
            return arr;
        } else if (category == SheetCollate.class) {
            if (flavor == null ||
                (flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                SheetCollate []arr = new SheetCollate[2];
                arr[0] = SheetCollate.COLLATED;
                arr[1] = SheetCollate.UNCOLLATED;
                return arr;
            } else {
                return null;
            }
        } else if (category == Fidelity.class) {
            Fidelity []arr = new Fidelity[2];
            arr[0] = Fidelity.FIDELITY_FALSE;
            arr[1] = Fidelity.FIDELITY_TRUE;
            return arr;
        } else {
            return null;
        }
    }

    public boolean isAttributeValueSupported(Attribute attr,
                                             DocFlavor flavor,
                                             AttributeSet attributes) {

        if (attr == null) {
            throw new NullPointerException("null attribute");
        }
        Class category = attr.getCategory();
        if (flavor != null) {
            if (!isDocFlavorSupported(flavor)) {
                throw new IllegalArgumentException(flavor +
                                                   " is an unsupported flavor");
                // if postscript & category is already specified within the PostScript data
                // we return false
            } else if (isAutoSense(flavor) || (isPostScriptFlavor(flavor) &&
                       (isPSDocAttr(category)))) {
                return false;
            }
        }

        if (!isAttributeCategorySupported(category)) {
            return false;
        }
        else if (category == Chromaticity.class) {
            if ((flavor == null) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                int caps = getPrinterCapabilities();
                if ((caps & DEVCAP_COLOR) != 0) {
                    return true;
                } else {
                    return attr == Chromaticity.MONOCHROME;
                }
            } else {
                return false;
            }
        } else if (category == Copies.class) {
            return isSupportedCopies((Copies)attr);

        } else if (category == Destination.class) {
            URI uri = ((Destination)attr).getURI();
            if ("file".equals(uri.getScheme()) &&
                !(uri.getSchemeSpecificPart().equals(""))) {
                return true;
            } else {
            return false;
            }

        } else if (category == Media.class) {
            if (attr instanceof MediaSizeName) {
                return isSupportedMedia((MediaSizeName)attr);
            }
            if (attr instanceof MediaTray) {
                return isSupportedMediaTray((MediaTray)attr);
            }

        } else if (category == MediaPrintableArea.class) {
            return isSupportedMediaPrintableArea((MediaPrintableArea)attr);

        } else if (category == SunAlternateMedia.class) {
            Media media = ((SunAlternateMedia)attr).getMedia();
            return isAttributeValueSupported(media, flavor, attributes);

        } else if (category == PageRanges.class ||
                   category == SheetCollate.class ||
                   category == Sides.class) {
            if (flavor != null &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                return false;
            }
        } else if (category == PrinterResolution.class) {
            if (attr instanceof PrinterResolution) {
                return isSupportedResolution((PrinterResolution)attr);
            }
        } else if (category == OrientationRequested.class) {
            if (attr == OrientationRequested.REVERSE_PORTRAIT ||
                (flavor != null) &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.URL.PNG))) {
                return false;
            }

        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            boolean isColorSup = ((caps & DEVCAP_COLOR) != 0);
            if  ((!isColorSup && (attr == ColorSupported.SUPPORTED)) ||
                (isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) {
                return false;
            }
        }
        return true;
    }

    public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
                                                 AttributeSet attributes) {

        if (flavor != null && !isDocFlavorSupported(flavor)) {
            throw new IllegalArgumentException("flavor " + flavor +
                                               "is not supported");
        }

        if (attributes == null) {
            return null;
        }

        Attribute attr;
        AttributeSet unsupp = new HashAttributeSet();
        Attribute []attrs = attributes.toArray();
        for (int i=0; i<attrs.length; i++) {
            try {
                attr = attrs[i];
                if (!isAttributeCategorySupported(attr.getCategory())) {
                    unsupp.add(attr);
                }
                else if (!isAttributeValueSupported(attr, flavor, attributes)) {
                    unsupp.add(attr);
                }
            } catch (ClassCastException e) {
            }
        }
        if (unsupp.isEmpty()) {
            return null;
        } else {
            return unsupp;
        }
    }

    private Win32DocumentPropertiesUI docPropertiesUI = null;

    private static class Win32DocumentPropertiesUI
        extends DocumentPropertiesUI {

        Win32PrintService service;

        private Win32DocumentPropertiesUI(Win32PrintService s) {
            service = s;
        }

        public PrintRequestAttributeSet
            showDocumentProperties(PrinterJob job,
                                   Window owner,
                                   PrintService service,
                                   PrintRequestAttributeSet aset) {

            if (!(job instanceof WPrinterJob)) {
                return null;
            }
            WPrinterJob wJob = (WPrinterJob)job;
            return wJob.showDocumentProperties(owner, service, aset);
        }
    }

    private synchronized DocumentPropertiesUI getDocumentPropertiesUI() {
        return new Win32DocumentPropertiesUI(this);
    }

    private static class Win32ServiceUIFactory extends ServiceUIFactory {

        Win32PrintService service;

        Win32ServiceUIFactory(Win32PrintService s) {
            service = s;
        }

        public Object getUI(int role, String ui) {
            if (role <= ServiceUIFactory.MAIN_UIROLE) {
                return null;
            }
            if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE &&
                DocumentPropertiesUI.DOCPROPERTIESCLASSNAME.equals(ui))
            {
                return service.getDocumentPropertiesUI();
            }
            throw new IllegalArgumentException("Unsupported role");
        }

        public String[] getUIClassNamesForRole(int role) {

            if (role <= ServiceUIFactory.MAIN_UIROLE) {
                return null;
            }
            if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE) {
                String[] names = new String[0];
                names[0] = DocumentPropertiesUI.DOCPROPERTIESCLASSNAME;
                return names;
            }
            throw new IllegalArgumentException("Unsupported role");
        }
    }

    private Win32ServiceUIFactory uiFactory = null;

    public synchronized ServiceUIFactory getServiceUIFactory() {
        if (uiFactory == null) {
            uiFactory = new Win32ServiceUIFactory(this);
        }
        return uiFactory;
    }

    public String toString() {
        return "Win32 Printer : " + getName();
    }

    public boolean equals(Object obj) {
        return  (obj == this ||
                 (obj instanceof Win32PrintService &&
                  ((Win32PrintService)obj).getName().equals(getName())));
    }

   public int hashCode() {
        return this.getClass().hashCode()+getName().hashCode();
    }

    public boolean usesClass(Class c) {
        return (c == sun.awt.windows.WPrinterJob.class);
    }

    private native int[] getAllMediaIDs(String printerName, String port);
    private native int[] getAllMediaSizes(String printerName, String port);
    private native int[] getAllMediaTrays(String printerName, String port);
    private native float[] getMediaPrintableArea(String printerName,
                                                 int paperSize);
    private native String[] getAllMediaNames(String printerName, String port);
    private native String[] getAllMediaTrayNames(String printerName, String port);
    private native int getCopiesSupported(String printerName, String port);
    private native int[] getAllResolutions(String printerName, String port);
    private native int getCapabilities(String printerName, String port);

    private native int[] getDefaultSettings(String printerName, String port);
    private native int getJobStatus(String printerName, int type);
    private native String getPrinterPort(String printerName);
}


class Win32MediaSize extends MediaSizeName {
    private static ArrayList winStringTable = new ArrayList();
    private static ArrayList winEnumTable = new ArrayList();
    private static MediaSize[] predefMedia;

    private int dmPaperID; // driver ID for this paper.

    private Win32MediaSize(int x) {
        super(x);

    }

    private synchronized static int nextValue(String name) {
      winStringTable.add(name);
      return (winStringTable.size()-1);
    }

    public static synchronized Win32MediaSize findMediaName(String name) {
        int nameIndex = winStringTable.indexOf(name);
        if (nameIndex != -1) {
            return (Win32MediaSize)winEnumTable.get(nameIndex);
        }
        return null;
    }

    public static MediaSize[] getPredefMedia() {
        return predefMedia;
    }

    public Win32MediaSize(String name, int dmPaper) {
        super(nextValue(name));
        dmPaperID = dmPaper;
        winEnumTable.add(this);
    }

    private MediaSizeName[] getSuperEnumTable() {
      return (MediaSizeName[])super.getEnumValueTable();
    }

    static {
         /* initialize predefMedia */
        {
            Win32MediaSize winMedia = new Win32MediaSize(-1);

            // cannot call getSuperEnumTable directly because of static context
            MediaSizeName[] enumMedia = winMedia.getSuperEnumTable();
            if (enumMedia != null) {
                predefMedia = new MediaSize[enumMedia.length];

                for (int i=0; i<enumMedia.length; i++) {
                    predefMedia[i] = MediaSize.getMediaSizeForName(enumMedia[i]);
                }
            }
        }
    }

    int getDMPaper() {
        return dmPaperID;
    }

    protected String[] getStringTable() {
      String[] nameTable = new String[winStringTable.size()];
      return (String[])winStringTable.toArray(nameTable);
    }

    protected EnumSyntax[] getEnumValueTable() {
      MediaSizeName[] enumTable = new MediaSizeName[winEnumTable.size()];
      return (MediaSizeName[])winEnumTable.toArray(enumTable);
    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java Win32PrintService.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.