Package sun.print

Source Code of sun.print.Win32PrintService

/*
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (C) 2009 Volker Berlin (i-net software)
* Copyright (C) 2010, 2011 Karsten Heinrich (i-net software)
* 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.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

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.HashPrintServiceAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.ColorSupported;
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.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.MediaTray;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.PrinterState;
import javax.print.attribute.standard.PrinterStateReasons;
import javax.print.attribute.standard.QueuedJobCount;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;
import javax.print.event.PrintServiceAttributeListener;

import cli.System.NewsStyleUriParser;
import cli.System.Type;
import cli.System.Collections.IEnumerator;
import cli.System.Drawing.RectangleF;
import cli.System.Drawing.Printing.Duplex;
import cli.System.Drawing.Printing.PaperKind;
import cli.System.Drawing.Printing.PaperSize;
import cli.System.Drawing.Printing.PaperSource;
import cli.System.Drawing.Printing.PrintDocument;
import cli.System.Drawing.Printing.PrinterSettings;
import cli.System.Drawing.Printing.PrinterSettings.PaperSizeCollection;
import cli.System.Drawing.Printing.PrinterSettings.PaperSourceCollection;
import cli.System.Net.Mime.MediaTypeNames;

/**
* @author Volker Berlin
*/
public class Win32PrintService implements PrintService {
  // note: the Win32PrintService is implemented as foreign service (doesn't implement SunPrinterJobService)
  // to avoid implementing the WPrinterJob

    private static final DocFlavor[] supportedFlavors = {
        DocFlavor.SERVICE_FORMATTED.PAGEABLE,
        DocFlavor.SERVICE_FORMATTED.PRINTABLE,
    };
   
    /** Mapping for PageSize.RawKind to predefined MediaSizeName */
    private static final MediaSizeName[] MEDIA_NAMES = new MediaSizeName[44];
   
    /*  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
    };

    // conversion from 1/100 Inch (.NET) to �m (Java)
    private static final int INCH100_TO_MYM = 254;
    private static final int  MATCH_DIFF = 500; // 0.5 mm
   
    static {
      MEDIA_NAMES[0] = MediaSizeName.NA_LETTER;
      MEDIA_NAMES[1] =  MediaSizeName.NA_LETTER ;
      MEDIA_NAMES[2] =  MediaSizeName.TABLOID ;
      MEDIA_NAMES[3] =  MediaSizeName.LEDGER ;
      MEDIA_NAMES[4] =  MediaSizeName.NA_LEGAL ;
      MEDIA_NAMES[5] =  MediaSizeName.INVOICE ; // Statement
      MEDIA_NAMES[6] =  MediaSizeName.EXECUTIVE ;
      MEDIA_NAMES[7] =  MediaSizeName.ISO_A3 ;
      MEDIA_NAMES[8] =  MediaSizeName.ISO_A4 ;
      MEDIA_NAMES[9] =  MediaSizeName.ISO_A4 ; // A4Small, 10
      MEDIA_NAMES[10] =  MediaSizeName.ISO_A5 ;
      MEDIA_NAMES[11] =  MediaSizeName.JIS_B4 ;
      MEDIA_NAMES[12] =  MediaSizeName.JIS_B5 ;
      MEDIA_NAMES[13] =  MediaSizeName.FOLIO ;
      MEDIA_NAMES[14] =  MediaSizeName.QUARTO ;
      MEDIA_NAMES[15] =  MediaSizeName.NA_10X14_ENVELOPE ;
      MEDIA_NAMES[16] =  MediaSizeName.B ; // 10x17 Envelope
      MEDIA_NAMES[17] =  MediaSizeName.NA_LETTER ; // Note
      MEDIA_NAMES[18] =  MediaSizeName.NA_NUMBER_9_ENVELOPE ;
      MEDIA_NAMES[19] =  MediaSizeName.NA_NUMBER_10_ENVELOPE ; // 20
      MEDIA_NAMES[20] =  MediaSizeName.NA_NUMBER_11_ENVELOPE ;
      MEDIA_NAMES[21] =  MediaSizeName.NA_NUMBER_12_ENVELOPE ;
      MEDIA_NAMES[22] =  MediaSizeName.NA_NUMBER_14_ENVELOPE ;
      MEDIA_NAMES[23] =  MediaSizeName.C ;
      MEDIA_NAMES[24] =  MediaSizeName.D ;
      MEDIA_NAMES[25] =  MediaSizeName.E ;
      MEDIA_NAMES[26] =  MediaSizeName.ISO_DESIGNATED_LONG ;
      MEDIA_NAMES[27] =  MediaSizeName.ISO_C5 ;
      MEDIA_NAMES[28] =  MediaSizeName.ISO_C3 ;
      MEDIA_NAMES[29] =  MediaSizeName.ISO_C4 ; // 30
      MEDIA_NAMES[30] =  MediaSizeName.ISO_C6 ;
      MEDIA_NAMES[31] =  MediaSizeName.ITALY_ENVELOPE ;
      MEDIA_NAMES[32] =  MediaSizeName.ISO_B4 ;
      MEDIA_NAMES[33] =  MediaSizeName.ISO_B5 ;
      MEDIA_NAMES[34] =  MediaSizeName.ISO_B6 ;
      MEDIA_NAMES[35] =  MediaSizeName.ITALY_ENVELOPE ;
      MEDIA_NAMES[36] =  MediaSizeName.MONARCH_ENVELOPE ;
      MEDIA_NAMES[37] =  MediaSizeName.PERSONAL_ENVELOPE ;
      MEDIA_NAMES[38] =  MediaSizeName.NA_10X15_ENVELOPE ; // USStandardFanfold
      MEDIA_NAMES[39] =  MediaSizeName.NA_9X12_ENVELOPE ; // GermanStandardFanfold, 40
      MEDIA_NAMES[40] =  MediaSizeName.FOLIO ; // GermanLegalFanfold
      MEDIA_NAMES[41] =  MediaSizeName.ISO_B4 ;
      MEDIA_NAMES[42] =  MediaSizeName.JAPANESE_POSTCARD ;
      MEDIA_NAMES[43] =  MediaSizeName.NA_9X11_ENVELOPE ;

//      // augment the media size with the .NET default sizes available on the printer
//      PrinterSettings ps = new PrinterSettings();
//      IEnumerator printers = PrinterSettings.get_InstalledPrinters().GetEnumerator();
//      printers.Reset();
//      while( printers.MoveNext() ){
//        ps.set_PrinterName( (String) printers.get_Current() );
//        IEnumerator sizes = ps.get_PaperSizes().GetEnumerator();
//        sizes.Reset();
//        while( sizes.MoveNext() ){
//          PaperSize size = (PaperSize) sizes.get_Current();
//          int kind = size.get_RawKind();
//        if( kind >= 0  && kind < MEDIA_NAMES.length && MEDIA_NAMES[kind] == null ){
//          MEDIA_NAMES[kind] = new CustomMediaSizeName( size.get_PaperName() );         
//          int x = size.get_Width();
//          int y = size.get_Height();
//          if( x > y ){ // not allowed by MediaSize
//            int tmp = x;
//            x = y;
//            y = tmp;
//          }
//          new MediaSize(x, y, INCH100_TO_MYM, MEDIA_NAMES[kind]); // cache entry in map
//          }
//        }
//      }
    }
   
    private final PrintPeer peer;
   
    private final String printer;
    private final PrinterSettings settings;
    private PrinterName name;

    private MediaTray[] mediaTrays;
   
    transient private ServiceNotifier notifier = null;

    public Win32PrintService(String name, PrintPeer peer){
        if(name == null){
            throw new IllegalArgumentException("null printer name");
        }
        this.peer = peer;
        printer = name;
        settings = new PrintDocument().get_PrinterSettings();
        settings.set_PrinterName(printer);
    }


    @Override
    public String getName(){
        return printer;
    }


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


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

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


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


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


    @Override
    public <T extends PrintServiceAttribute>T getAttribute(Class<T> category){
        if(category == null){
            throw new NullPointerException("category");
        }
        if(!(PrintServiceAttribute.class.isAssignableFrom(category))){
            throw new IllegalArgumentException("The categhory '" + category + "' is not a valid PrintServiceAttribute");
        }
        if(category == ColorSupported.class){
          // works better than settings.get_SupportsColor();
            if(settings.get_DefaultPageSettings().get_Color()){
                return (T)ColorSupported.SUPPORTED;
            }else{
                return (T)ColorSupported.NOT_SUPPORTED;
            }
        }else if(category == PrinterName.class){
            return (T)getPrinterName();
        } else {
            // QueuedJobCount and PrinterIsAcceptingJobs
            return (T)peer.getPrinterStatus(printer, category);
        }
    }


    @Override
    public PrintServiceAttributeSet getAttributes(){
        PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
        attrs.add(getPrinterName());
        PrinterIsAcceptingJobs acptJobs = getAttribute(PrinterIsAcceptingJobs.class);
        if(acptJobs != null){
            attrs.add(acptJobs);
        }
        PrinterState prnState = getAttribute(PrinterState.class);
        if(prnState != null){
            attrs.add(prnState);
        }
        PrinterStateReasons prnStateReasons = getAttribute(PrinterStateReasons.class);
        if(prnStateReasons != null){
            attrs.add(prnStateReasons);
        }
        QueuedJobCount jobCount = getAttribute(QueuedJobCount.class);
        if(jobCount != null){
            attrs.add(jobCount);
        }
        // TODO: Seems to be more accurate than settings.get_SupportsColor(), which doesn't work for CutePDF
        if(settings.get_DefaultPageSettings().get_Color()){
            attrs.add(ColorSupported.SUPPORTED);
        }else{
            attrs.add(ColorSupported.NOT_SUPPORTED);
        }

        return AttributeSetUtilities.unmodifiableView(attrs);
    }


    @Override
    public Object getDefaultAttributeValue(Class<? extends Attribute> category){
      if (category == null) {
        throw new NullPointerException("category must not be null");
      }
      if ( !Attribute.class.isAssignableFrom( category ) ) {
        throw new IllegalArgumentException( category +" has to be an " + Attribute.class.getName() );
      }
      if ( !isAttributeCategorySupported( category ) ) {
        return null;
      }
      if (category == Copies.class) {
        short copies = settings.get_Copies();
        return new Copies( copies > 0 ? copies : 1 );
      }
      if (category == Chromaticity.class) {
        // NOTE: this works for CutePDF, settings.get_SupportsColor() does not
        return settings.get_DefaultPageSettings().get_Color() ? Chromaticity.COLOR : Chromaticity.MONOCHROME;
      }
      if (category == JobName.class) {
        return new JobName( "Java Printing", null ); // TODO this is Java-Default, use another one for IKVM?
      }
      if (category == OrientationRequested.class) {
        return settings.get_DefaultPageSettings().get_Landscape() ? OrientationRequested.LANDSCAPE : OrientationRequested.PORTRAIT;
      }
      if (category == PageRanges.class) {
        return new PageRanges(1, Integer.MAX_VALUE );
      }
      if (category == Media.class) {
        int rawKind = settings.get_DefaultPageSettings().get_PaperSize().get_RawKind();
        if( rawKind > MEDIA_NAMES.length || rawKind < 1 || MEDIA_NAMES[ rawKind - 1 ] == null ){ // custom page format
          return settings.get_DefaultPageSettings().get_PaperSize().get_PaperName();
        } else {
          return MEDIA_NAMES[ rawKind - 1 ];
        }
      }
      if (category == MediaPrintableArea.class) {
        RectangleF area = settings.get_DefaultPageSettings().get_PrintableArea();
        // get_PrintableArea is in 1/100 inch, see http://msdn.microsoft.com/de-de/library/system.drawing.printing.pagesettings.printablearea(v=VS.90).aspx
        return new MediaPrintableArea(area.get_X()/100, area.get_Y()/100, area.get_Width()/100, area.get_Height()/100, MediaPrintableArea.INCH);
      }
      if (category == Destination.class) {
        String path = "out.prn";
        try {
          return new Destination( ( new File( path ) ).toURI() );
        } catch (SecurityException se) {
          try {
            return new Destination( new URI( "file:" + path) );
          } catch (URISyntaxException e) {
            return null;
          }
        }
      }
      if (category == Sides.class) {
        switch( settings.get_Duplex().Value ){
          case cli.System.Drawing.Printing.Duplex.Default: // MSDN: 'The printer's default duplex setting.' - what ever that might be
          case cli.System.Drawing.Printing.Duplex.Simplex:
            return Sides.ONE_SIDED;
          case cli.System.Drawing.Printing.Duplex.Horizontal:
            return Sides.TWO_SIDED_LONG_EDGE;
          case cli.System.Drawing.Printing.Duplex.Vertical:
            return Sides.TWO_SIDED_SHORT_EDGE;
        }
      }
      if (category == PrinterResolution.class) {
        cli.System.Drawing.Printing.PrinterResolution res = settings.get_DefaultPageSettings().get_PrinterResolution();
        return new PrinterResolution( res.get_X(), res.get_Y(), PrinterResolution.DPI);
      }
      if (category == ColorSupported.class) {
        if ( settings.get_SupportsColor() ) {
          return ColorSupported.SUPPORTED;
        } else {
          return ColorSupported.NOT_SUPPORTED;
        }
      }
      if( category == PrintQuality.class ){
        return PrintQuality.NORMAL; // TODO not correct, only available when using a PrintServer instance?
      }
      if (category == RequestingUserName.class) {
        try{
          return new RequestingUserName( System.getProperty("user.name", ""), null);
        } catch( SecurityException e ){
          return new RequestingUserName( "", null);
        }
      }
      if (category == SheetCollate.class){
        return settings.get_Collate() ? SheetCollate.COLLATED : SheetCollate.UNCOLLATED;
      }
      if (category == Fidelity.class) {
        return Fidelity.FIDELITY_FALSE;
      }
        return null;
    }


    @Override
    public ServiceUIFactory getServiceUIFactory(){
        return null;
    }


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

        if (settings.get_CanDuplex()) {
            categList.add(Sides.class);
        }

        if (settings.get_PrinterResolutions().get_Count() > 0) {
            categList.add(PrinterResolution.class);
        }

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


    @Override
    public Object getSupportedAttributeValues(Class<? extends Attribute> category, DocFlavor flavor, AttributeSet attributes){
      if ( category == null || !Attribute.class.isAssignableFrom( category ) ) {
        throw new IllegalArgumentException( "The category '" + category + "' is not an Attribute" );
      }
        if( !isAttributeCategorySupported(category) ){
          return null;
        }
        if (category == JobName.class || category == RequestingUserName.class || category == ColorSupported.class
            || category == Destination.class ) {
          return getDefaultAttributeValue(category);
        }
        if( category == Copies.class ){
          return new CopiesSupported(1, settings.get_MaximumCopies() );
        }
        if( category == Media.class ){
          PaperSizeCollection sizes = settings.get_PaperSizes();
          List<Media> medias = new ArrayList<Media>();
          for( int i = 0; i < sizes.get_Count(); i++ ){
            PaperSize media = sizes.get_Item(i);       
            MediaSizeName mediaName = findMatchingMedia( sizes.get_Item(i) );
          if( mediaName != null
              && !medias.contains( mediaName )){ // slow but better than creating a HashSet here
            medias.add( mediaName);
            }
          }
          // add media trays
          MediaTray[] trays = getMediaTrays();
          for( MediaTray tray : trays ){
            medias.add( tray );
          }
          return medias.size() > 0 ? medias.toArray( new Media[medias.size() ] ) : null;
        }
        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;
          }
        }
        if (category == Fidelity.class) {
          return new Fidelity[]{ Fidelity.FIDELITY_FALSE, Fidelity.FIDELITY_TRUE};
        }
        if (category == PrintQuality.class) {
          return new PrintQuality[]{ PrintQuality.DRAFT, PrintQuality.HIGH, PrintQuality.NORMAL };
        }
       
        boolean printPageAble = flavor == null|| flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
                  || flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE);
        if (category == Sides.class) {
          if ( printPageAble ) {
            return new Sides[]{ Sides.ONE_SIDED, Sides.TWO_SIDED_LONG_EDGE, Sides.TWO_SIDED_SHORT_EDGE};
          } else {
            return null;
          }
        }
        if (category == SheetCollate.class) {
          if ( printPageAble ) {
            return new SheetCollate[]{ SheetCollate.COLLATED, SheetCollate.UNCOLLATED} ;
          } else {
            return null;
          }
        }
        boolean imageBased =  printPageAble || 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);
        if (category == OrientationRequested.class) {
          if( imageBased ){
            return new OrientationRequested[]{ OrientationRequested.PORTRAIT, OrientationRequested.LANDSCAPE, OrientationRequested.REVERSE_LANDSCAPE };
          } else {
            return null;
          }
        }
        if (category == Chromaticity.class) {
          if( imageBased ){
            if( settings.get_DefaultPageSettings().get_Color() ){
              return new Chromaticity[]{ Chromaticity.MONOCHROME, Chromaticity.COLOR };
            } else {
              return new Chromaticity[]{ Chromaticity.MONOCHROME };
            }
          } else {
            return null;
          }
        }
        return null;
    }
   
    private MediaTray[] getMediaTrays(){
      if( mediaTrays  != null ){
        // the print service is a singleton per printer so we only do this once
        return mediaTrays;
      }
      PaperSourceCollection trays = settings.get_PaperSources();
      int count = trays.get_Count();
      List<MediaTray> trayList = new ArrayList<MediaTray>();
      for( int i=0; i < count; i++ ){
        PaperSource tray = trays.get_Item(i);
        MediaTray javaTray = getDefaultTray(tray);
        if( javaTray != null ){
          trayList.add( javaTray );
        } else {
          trayList.add( new NetMediaTray( tray ) );
        }
      }
      mediaTrays = trayList.toArray( new MediaTray[trayList.size()]);
      return mediaTrays;
    }


    @Override
    public DocFlavor[] getSupportedDocFlavors(){
        int len = supportedFlavors.length;
        DocFlavor[] result = new DocFlavor[len];
        System.arraycopy(supportedFlavors, 0, result, 0, len);
        return result;
    }


    @Override
    public AttributeSet getUnsupportedAttributes(DocFlavor flavor, AttributeSet attributes){
        // TODO Auto-generated method stub
        return null;
    }


    @Override
    public boolean isAttributeCategorySupported(Class<? extends Attribute> category){
      if ( category == null || !Attribute.class.isAssignableFrom( category ) ) {
        throw new IllegalArgumentException( "The category '" + category + "' is not an Attribute" );
      }
        Class<?>[] supported = getSupportedAttributeCategories();
        for( int i=0; i < supported.length; i++ ){
          if( category == supported[i] ){
            return true;
          }
        }
        return false;
    }


    @Override
    public boolean isAttributeValueSupported(Attribute attrval, DocFlavor flavor, AttributeSet attributes){
        // TODO Auto-generated method stub
        return false;
    }


    @Override
    public boolean isDocFlavorSupported(DocFlavor flavor){
        for (int f=0; f<supportedFlavors.length; f++) {
            if (flavor.equals(supportedFlavors[f])) {
                return true;
            }
        }
        return false;
    }


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


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


    @Override
    public int hashCode(){
        return this.getClass().hashCode() + getName().hashCode();
    }
   
    /**
     * Tries to find a matching {@link MediaSizeName} for a paper by it's size
     * @param paper
     * @return
     */
    private MediaSizeName findMatchingMedia( PaperSize paper ){
      if( paper.get_RawKind() > 0 && paper.get_RawKind() <= MEDIA_NAMES.length ){
        // match to predefined size
        return MEDIA_NAMES[ paper.get_RawKind() - 1 ];
      }
      int x = paper.get_Width() * INCH100_TO_MYM;
      int y = paper.get_Height() * INCH100_TO_MYM;
      if( x > y ){ // MediaSizes are always portrait!
        int tmp = x;
        x = y;
        y = tmp;
      }
      for( MediaSizeName name : MEDIA_NAMES ){
        MediaSize media = MediaSize.getMediaSizeForName(name);
        if( media != null ){
          if( Math.abs( x - media.getX(1) ) < MATCH_DIFF && Math.abs( y - media.getY(1) ) < MATCH_DIFF ){
            return name;
          }
        }
      }
      return null;
    }
   
    /**
     * Returns the Java-default {@link MediaTray} for a paper source. This is required since these default
     * trays are public constants which can be used without checking for the actually present media trays
     * @param source the .NET paper source to get the predefined source for
     * @return the media tray or null, in case there is no mapping for the paper source
     */
    private MediaTray getDefaultTray( PaperSource source ){
      // convert from .NET kind to java's pre defined MediaTrays
      switch( source.get_RawKind() ){
        case 1 : return MediaTray.TOP;
        case 2 : return MediaTray.BOTTOM;
        case 3 : return MediaTray.MIDDLE;
        case 4 : return MediaTray.MANUAL;
        case 5 : return MediaTray.ENVELOPE;
        case 6 : return Win32MediaTray.ENVELOPE_MANUAL;
        case 7 : return Win32MediaTray.AUTO;
        case 8 : return Win32MediaTray.TRACTOR;
        case 9 : return Win32MediaTray.SMALL_FORMAT;
        case 10 : return Win32MediaTray.LARGE_FORMAT;
        case 11 : return MediaTray.LARGE_CAPACITY;
        case 14 : return MediaTray.MAIN;
        case 15 : return Win32MediaTray.FORMSOURCE;
        // FIXME which PaperSourceKind is MediaTray.SIDE ???
      }
      return null;
    }
   
    /**
     * Returns the .NET {@link PaperSource} for a media tray. This will be done either by mapping or
     * directly in case the tray is a {@link NetMediaTray}
     * @param tray the tray to get the paper source for, must not be null
     * @return the selected {@link PaperSource} or null, in case there is no matching {@link PaperSource}
     */
    public PaperSource getPaperSourceForTray( MediaTray tray ){
      if( tray instanceof NetMediaTray ){
      return ((NetMediaTray)tray).getPaperSource( this );
    }
      // try to find the appropriate paper source for the Java-Defined tray
      PaperSourceCollection trays = settings.get_PaperSources();
      int count = trays.get_Count();
      for( int i=0; i < count; i++ ){
        PaperSource paperSource = trays.get_Item(i);
      if( getDefaultTray( paperSource ) == tray ){
          return paperSource;
        }
      }
      return null;
    }
   
    public static class NetMediaTray extends MediaTray{
     
    private static final long serialVersionUID = 1L;

    /** Not really used but required by the EnumSyntax super class */
      private static AtomicInteger idCounter = new AtomicInteger(8);
     
      private int rawKind;
      private String name;
      private transient PaperSource netSource;

    public NetMediaTray( PaperSource netSource ) {
      super( idCounter.getAndIncrement() );
      this.rawKind = netSource.get_RawKind();
      this.name = netSource.get_SourceName();
      this.netSource = netSource;
    }
     
    public PaperSource getPaperSource( Win32PrintService service ){
      if( netSource == null ){
        PaperSourceCollection sources = service.settings.get_PaperSources();
        int count = sources.get_Count();
        for( int i=0; i < count; i++ ){
          PaperSource source = sources.get_Item(i);
          if( source.get_RawKind() == rawKind ){
            netSource = source;
            break;
          }
        }
      }
      return netSource;
    }
   
    @Override
    public String toString() {
      return netSource != null ? netSource.get_SourceName() : name;
    }
    }
}
TOP

Related Classes of sun.print.Win32PrintService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.