/* IppPrintService.java -- 
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.javax.print.ipp;

import gnu.classpath.SystemProperties;
import gnu.classpath.debug.Component;
import gnu.classpath.debug.SystemLogger;
import gnu.javax.print.ipp.attribute.DefaultValueAttribute;
import gnu.javax.print.ipp.attribute.RequestedAttributes;
import gnu.javax.print.ipp.attribute.defaults.CopiesDefault;
import gnu.javax.print.ipp.attribute.defaults.FinishingsDefault;
import gnu.javax.print.ipp.attribute.defaults.JobHoldUntilDefault;
import gnu.javax.print.ipp.attribute.defaults.JobPriorityDefault;
import gnu.javax.print.ipp.attribute.defaults.JobSheetsDefault;
import gnu.javax.print.ipp.attribute.defaults.MediaDefault;
import gnu.javax.print.ipp.attribute.defaults.MultipleDocumentHandlingDefault;
import gnu.javax.print.ipp.attribute.defaults.NumberUpDefault;
import gnu.javax.print.ipp.attribute.defaults.OrientationRequestedDefault;
import gnu.javax.print.ipp.attribute.defaults.PrintQualityDefault;
import gnu.javax.print.ipp.attribute.defaults.PrinterResolutionDefault;
import gnu.javax.print.ipp.attribute.defaults.SidesDefault;
import gnu.javax.print.ipp.attribute.printer.DocumentFormat;
import gnu.javax.print.ipp.attribute.supported.CompressionSupported;
import gnu.javax.print.ipp.attribute.supported.DocumentFormatSupported;
import gnu.javax.print.ipp.attribute.supported.FinishingsSupported;
import gnu.javax.print.ipp.attribute.supported.JobHoldUntilSupported;
import gnu.javax.print.ipp.attribute.supported.JobSheetsSupported;
import gnu.javax.print.ipp.attribute.supported.MediaSupported;
import gnu.javax.print.ipp.attribute.supported.MultipleDocumentHandlingSupported;
import gnu.javax.print.ipp.attribute.supported.OperationsSupported;
import gnu.javax.print.ipp.attribute.supported.OrientationRequestedSupported;
import gnu.javax.print.ipp.attribute.supported.PageRangesSupported;
import gnu.javax.print.ipp.attribute.supported.PrintQualitySupported;
import gnu.javax.print.ipp.attribute.supported.PrinterResolutionSupported;
import gnu.javax.print.ipp.attribute.supported.PrinterUriSupported;
import gnu.javax.print.ipp.attribute.supported.SidesSupported;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

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.HashAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.Compression;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.Finishings;
import javax.print.attribute.standard.JobHoldUntil;
import javax.print.attribute.standard.JobImpressions;
import javax.print.attribute.standard.JobImpressionsSupported;
import javax.print.attribute.standard.JobKOctets;
import javax.print.attribute.standard.JobKOctetsSupported;
import javax.print.attribute.standard.JobMediaSheets;
import javax.print.attribute.standard.JobMediaSheetsSupported;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.JobPriority;
import javax.print.attribute.standard.JobPrioritySupported;
import javax.print.attribute.standard.JobSheets;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MultipleDocumentHandling;
import javax.print.attribute.standard.NumberUp;
import javax.print.attribute.standard.NumberUpSupported;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.PrinterURI;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.Sides;
import javax.print.event.PrintServiceAttributeListener;


/**
 * Implementation of the PrintService interface
 * for IPP based printers.
 * 
 * @author Wolfgang Baer (WBaer@gmx.de)
 */
public class IppPrintService implements PrintService
{
  /** 
   * A Map with sets of attributes.
   * key: A attribute category
   * value: A set with values
   * 
   * IPP may return sets of attributes e.g. for supported
   * compression methods so we need to map to sets here.
   */
  private Map printerAttr;
    
  /** The set of listeners.*/
  private HashSet printServiceAttributeListener;
  
  /** The username. */
  private transient String user;
  
  /** The password of the user. */
  private transient String passwd;
  
  /** The name of this print service. */
  private String name;
  
  /** The list of supported document flavors. */
  private List flavors;
  
  /** The standard printer URI. */
  private PrinterURI printerUri;
  
  /** The list of all supported printer URIs. */
  private ArrayList printerUris;
    
  /**
   * Logger for tracing - enable by passing
   * -Dgnu.classpath.debug.components=ipp to the vm.
   */
  static final Logger logger = SystemLogger.SYSTEM;
  
  /** 
   * requesting-user-name defaults to the executing user.
   */
  public static final RequestingUserName REQUESTING_USER_NAME;
  
  /** 
   * job-name defaults to "Java Printing".
   */
  public static final JobName JOB_NAME;
  
  static
  {
    JOB_NAME = new JobName("Java Printing", null);
    REQUESTING_USER_NAME = new RequestingUserName(
      SystemProperties.getProperty("user.name", ""), null);    
  }
  
  // TODO Implement service listener notification and change detection.
  
  /**
   * Creates a <code>IppPrintService</code> object.
   * 
   * @param uri the URI of the IPP printer.
   * @param username the user of this print service.
   * @param password the password of the user.
   * 
   * @throws IppException if an error during connection occurs.
   */
  public IppPrintService(URI uri, String username, String password) 
    throws IppException
  {
    printerUri = new PrinterURI(uri);
    user = username;
    passwd = password;
    
    printServiceAttributeListener = new HashSet();
        
    printerAttr = getPrinterAttributes();
    processResponse();
  }
  
  /**
   * Fetches all printer attributes from the IPP printer.
   * 
   * @return The Map with the printer attributes.
   * @throws IppException if an error occurs.
   */
  private Map getPrinterAttributes() throws IppException
  {
    IppResponse response = null;
    
    try
      {
        IppRequest request = new IppRequest(printerUri.getURI(), user, passwd);    
        
        int operation = OperationsSupported.GET_PRINTER_ATTRIBUTES.getValue();
        request.setOperationID((short) operation);        
        request.setOperationAttributeDefaults();  
        request.addOperationAttribute(printerUri);
        
        response = request.send();
      }   
    catch (IOException e)
      {
        throw new IppException("IOException in IPP request/response.", e);
      }   
     
    return (Map) response.getPrinterAttributes().get(0);   
  }
  
  /**
   * Extracts the set of attribute values for a given 
   * attribute category from the printer attributes map.
   * 
   * @param attributeClass the category
   * @return The set of attributes of the category.
   */
  private Set getPrinterAttributeSet(Class attributeClass)
  {
    return (Set) printerAttr.get(attributeClass);
  }
  
  /**
   * Extracts the default attribute value for the given 
   * default attribute category from the printer attributes map.
   * 
   * @param attributeClass the category
   * @return The default attribute.
   * 
   * @throws ClassCastException if attributClass is not an
   * instance of <code>DefaultValueAttribute</code>.
   */
  private Attribute getPrinterDefaultAttribute(Class attributeClass)
  {
    Set set = (Set) printerAttr.get(attributeClass);
    return ((DefaultValueAttribute) set.toArray()[0]).getAssociatedAttribute();
  }
  
  /**
   * Processes the response, sorts and splits the attributes.
   */
  private void processResponse()
  {
    // printer name
    PrinterName[] tmp = (PrinterName[]) getPrinterAttributeSet(
                         PrinterName.class).toArray(new PrinterName[1]);
    name = tmp[0].getValue();
    
    // supported flavors
    // TODO Check if charsets-supported are charsets that are actually supported
    // for text doc flavors as cups doesn't send charset parameters
    
    // utf-8 is supported at least - so we go with this only for now
    flavors = new ArrayList();
    Set flavorAttributes = getPrinterAttributeSet(DocumentFormatSupported.class);
    if (flavorAttributes != null)
      {
        for (Iterator it = flavorAttributes.iterator(); it.hasNext();)
          {
            String mimeType = ((DocumentFormatSupported) it.next()).getValue();
                        
            if (mimeType.equals("text/plain"))
              {
                flavors.add(DocFlavor.CHAR_ARRAY.TEXT_PLAIN);
                flavors.add(DocFlavor.READER.TEXT_PLAIN);
                flavors.add(DocFlavor.STRING.TEXT_PLAIN);
                
                // add utf-8
                mimeType = mimeType + "; charset=utf-8";
              }
            else if (mimeType.equals("text/html"))
              {
                flavors.add(DocFlavor.CHAR_ARRAY.TEXT_HTML);
                flavors.add(DocFlavor.READER.TEXT_HTML);
                flavors.add(DocFlavor.STRING.TEXT_HTML);
                
                // add utf-8
                mimeType = mimeType + "; charset=utf-8";
              }
            
            // Process the predefined DocFlavors and if mimetype is
            // equal put them into the flavors array - otherwise
            // just build them as binarie class representation.
            boolean changed = false;
            try
              {
                Class[] clazzes = new Class[] { DocFlavor.BYTE_ARRAY.class,
                                                DocFlavor.INPUT_STREAM.class,
                                                DocFlavor.URL.class };                
                 
                for (int j = 0; j < clazzes.length; j++)
                  {
                    Field[] fields = clazzes[j].getDeclaredFields();
                    for (int i = 0; i < fields.length; i++)
                      {
                        if (fields[i].getType().equals(clazzes[j]))
                          {
                            DocFlavor flavor = (DocFlavor) fields[i].get(null);
                            if (flavor.getMimeType().equals(mimeType))
                              changed = flavors.add(flavor);
                          }
                      }
                  }
                if (!changed) // not in predefined constants of DocFlavor
                  {                    
                    // everything should be supported as binary stuff
                    flavors.add(new DocFlavor(mimeType, "[B"));
                    flavors.add(new DocFlavor(mimeType, "java.io.InputStream"));
                    flavors.add(new DocFlavor(mimeType, "java.net.URL"));
                  }
              }
            catch (SecurityException e)
              {
                // should not happen
              }
            catch (IllegalArgumentException e)
              {
                // should not happen
              }
            catch (IllegalAccessException e)
              {
                // should not happen, all fields are public
              }
          }
      }
    
    // printer uris
    Set uris = getPrinterAttributeSet(PrinterUriSupported.class);
    printerUris = new ArrayList(uris.size());
    Iterator it = uris.iterator();
    while (it.hasNext())
      {
        PrinterUriSupported uri = (PrinterUriSupported) it.next();
        printerUris.add( new PrinterURI(uri.getURI()));
      }
  }

  /**
   * We always return a implementation implementing CancelablePrintJob.
   * 
   * @see javax.print.PrintService#createPrintJob()
   */
  public DocPrintJob createPrintJob()
  {
    return new DocPrintJobImpl(this, user, passwd);
  }
  

  /**
   * @see javax.print.PrintService#getAttribute(java.lang.Class)
   */
  public PrintServiceAttribute getAttribute(Class category)
  {
    if (category == null)
      throw new NullPointerException("category may not be null");
    
    if (! PrintServiceAttribute.class.isAssignableFrom(category))
      throw new IllegalArgumentException(
         "category must be of type PrintServiceAttribute");
    
    Set set = getPrinterAttributeSet(category);
    if (set != null && set.size() > 0)     
        return (PrintServiceAttribute) set.toArray()[0];
        
    return null;
  }

  /**
   * @see javax.print.PrintService#getAttributes()
   */
  public PrintServiceAttributeSet getAttributes()
  {
    PrintServiceAttributeSet set = new HashPrintServiceAttributeSet();
    
    Iterator it = printerAttr.values().iterator();
    while (it.hasNext())
      {        
        Iterator it2 = ((Set) it.next()).iterator();
        while (it2.hasNext())
          {
            Attribute attr = (Attribute) it2.next();
            if (attr instanceof PrintServiceAttribute)
              set.add(attr);
          }
      }
    
    return AttributeSetUtilities.unmodifiableView(set);
  }

  /**
   * @see javax.print.PrintService#getDefaultAttributeValue(java.lang.Class)
   */
  public Object getDefaultAttributeValue(Class category)
  { 
    // required attributes
    if (category.equals(Fidelity.class))
      return Fidelity.FIDELITY_FALSE;    
    if (category.equals(JobName.class))
      return JOB_NAME;
    if (category.equals(RequestingUserName.class))
      return REQUESTING_USER_NAME;
    
    // optional attributes
    if (category.equals(JobPriority.class) 
        && printerAttr.containsKey(JobPriorityDefault.class))
      return getPrinterDefaultAttribute(JobPriorityDefault.class);
    if (category.equals(JobHoldUntil.class) 
        && printerAttr.containsKey(JobHoldUntilDefault.class))
      return getPrinterDefaultAttribute(JobHoldUntilDefault.class);
    if (category.equals(JobSheets.class) 
        && printerAttr.containsKey(JobSheetsDefault.class))
      return getPrinterDefaultAttribute(JobSheetsDefault .class);
    if (category.equals(MultipleDocumentHandling.class) 
        && printerAttr.containsKey(MultipleDocumentHandlingDefault.class))
      return getPrinterDefaultAttribute(MultipleDocumentHandlingDefault.class);
    if (category.equals(Copies.class) 
        && printerAttr.containsKey(CopiesDefault.class))
      return getPrinterDefaultAttribute(CopiesDefault.class);
    if (category.equals(Finishings.class) 
        && printerAttr.containsKey(FinishingsDefault.class))
      return getPrinterDefaultAttribute(FinishingsDefault.class);
    if (category.equals(Sides.class) 
        && printerAttr.containsKey(SidesDefault.class))
      return getPrinterDefaultAttribute(SidesDefault.class);
    if (category.equals(NumberUp.class) 
        && printerAttr.containsKey(NumberUpDefault.class))
      return getPrinterDefaultAttribute(NumberUpDefault.class);
    if (category.equals(OrientationRequested.class) 
        && printerAttr.containsKey(OrientationRequestedDefault.class))
      return getPrinterDefaultAttribute(OrientationRequestedDefault.class);
    if (category.equals(Media.class) 
        && printerAttr.containsKey(MediaDefault.class))
      return getPrinterDefaultAttribute(MediaDefault.class);
    if (category.equals(PrinterResolution.class) 
        && printerAttr.containsKey(PrinterResolutionDefault.class))
      return getPrinterDefaultAttribute(PrinterResolutionDefault.class);
    if (category.equals(PrintQuality.class) 
        && printerAttr.containsKey(PrintQualityDefault.class))
      return getPrinterDefaultAttribute(PrintQualityDefault.class);
    if (category.equals(Compression.class) 
        && printerAttr.containsKey(CompressionSupported.class))
      return Compression.NONE;
    if (category.equals(PageRanges.class))
      return new PageRanges(1, Integer.MAX_VALUE);

    return null; 
  }
  
  /**
   * We return the value of <code>PrinterName</code> here.
   * @see javax.print.PrintService#getName()
   */
  public String getName()
  {
    return name;
  }

  /**
   * We currently provide no factories - just returns null.
   * @see javax.print.PrintService#getServiceUIFactory()
   */
  public ServiceUIFactory getServiceUIFactory()
  {
    // SUN does not provide any service factory for
    // print services (tested on linux/windows)
    
    // for the moment we do the same - just return null
    // later on we could provide at least the about UI dialog
    return null;
  }

  /**
   * @see javax.print.PrintService#getSupportedAttributeCategories()
   */
  public Class[] getSupportedAttributeCategories()
  {
    Set categories = new HashSet();
    
    // Should only be job template attributes as of section 4.2    
    if (printerAttr.containsKey(JobPrioritySupported.class))
      categories.add(JobPriority.class);
    if (printerAttr.containsKey(JobHoldUntilSupported.class))
      categories.add(JobHoldUntil.class);
    if (printerAttr.containsKey(JobSheetsSupported.class))
      categories.add(JobSheets.class);
    if (printerAttr.containsKey(MultipleDocumentHandlingSupported.class))
      categories.add(MultipleDocumentHandling.class);    
    if (printerAttr.containsKey(CopiesSupported.class))
      categories.add(Copies.class);
    if (printerAttr.containsKey(FinishingsSupported.class))
      {
        // if only none finishing is supported - it does not count as supported
        Set set = getPrinterAttributeSet(FinishingsSupported.class);        
        if (! (set.size() == 1 && set.contains(FinishingsSupported.NONE)))          
          categories.add(Finishings.class);
      }
    if (printerAttr.containsKey(PageRangesSupported.class))
      categories.add(PageRanges.class);
    if (printerAttr.containsKey(SidesSupported.class))
      categories.add(Sides.class);
    if (printerAttr.containsKey(NumberUpSupported.class))
      categories.add(NumberUp.class);
    if (printerAttr.containsKey(OrientationRequestedSupported.class))
      categories.add(OrientationRequested.class);
    if (printerAttr.containsKey(MediaSupported.class))
      categories.add(Media.class);
    if (printerAttr.containsKey(PrinterResolutionSupported.class))
      categories.add(PrinterResolution.class);
    if (printerAttr.containsKey(PrintQualitySupported.class))
      categories.add(PrintQuality.class);
      
    // Chromaticity, Destination, MediaPrintableArea, 
    // SheetCollate, PresentationDirection - not IPP attributes
    
    // attributes outside section 4.2   
    if (printerAttr.containsKey(CompressionSupported.class))
      categories.add(Compression.class);
    if (printerAttr.containsKey(JobImpressionsSupported.class))
      categories.add(JobImpressions.class);
    if (printerAttr.containsKey(JobKOctetsSupported.class))
      categories.add(JobKOctets.class);
    if (printerAttr.containsKey(JobMediaSheetsSupported.class))
      categories.add(JobMediaSheets.class);
    
    // always supported as required by IPP specification
    categories.add(Fidelity.class);
    categories.add(JobName.class);
    categories.add(RequestingUserName.class);

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

  /**
   * Implemented by a GetPrinterAttributes request. Subclasses providing supported
   * attribute values totally different may override this methods. Subclass only in
   * need of handling the response differently may override the method
   * <code>handleSupportedAttributeValuesResponse(IppResponse, Class)</code> only.
   * 
   * @see PrintService#getSupportedAttributeValues(Class, DocFlavor, AttributeSet)
   * @see #handleSupportedAttributeValuesResponse(IppResponse, Class)
   */
  public Object getSupportedAttributeValues(Class category, DocFlavor flavor,
                                            AttributeSet attributes)
  {
    // We currently ignore the attribute set - there is nothing in the IPP
    // specification which would come closer to what we do here.

    if (category == null)
      throw new NullPointerException("category may not be null");

    if (!Attribute.class.isAssignableFrom(category))
      throw new IllegalArgumentException("category must be of type Attribute");

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

    if (!isAttributeCategorySupported(category))
      return null;

    // always supported
    if (category.equals(Fidelity.class))
      return new Fidelity[] { Fidelity.FIDELITY_FALSE, Fidelity.FIDELITY_TRUE };
    if (category.equals(JobName.class))
      return JOB_NAME;
    if (category.equals(RequestingUserName.class))
      return REQUESTING_USER_NAME;

    // map category to category-supported
    String categoryName = IppUtilities.getSupportedAttrName(category);

    IppResponse response = null;
    try
      {
        IppRequest request = new IppRequest(printerUri.getURI(), user, passwd);
        request.setOperationID(
          (short) OperationsSupported.GET_PRINTER_ATTRIBUTES.getValue());
        request.setOperationAttributeDefaults();
        request.addOperationAttribute(new RequestedAttributes(categoryName));
        request.addOperationAttribute(printerUri);
        
        if (flavor != null)
          {
            DocumentFormat f = DocumentFormat.createDocumentFormat(flavor);
            request.addOperationAttribute(f);
          }

        response = request.send();
        
        int status = response.getStatusCode();
        if (! (status == IppStatusCode.SUCCESSFUL_OK
             || status == IppStatusCode.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUED_ATTRIBUTES
             || status == IppStatusCode.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) )
          {
            logger.log(Component.IPP, "Statuscode not OK - got:" + status);
          }
      }
    catch (IOException e)
      {
        // method cannot throw exception - just log
        logger.log(Component.IPP, "IOException", e);
      }
    catch (IppException e)
      {
        // method cannot throw exception - just log
        logger.log(Component.IPP, "IPPException", e);
      }
    
    return handleSupportedAttributeValuesResponse(response, category);
  }
  
  /**
   * Called to handle the supported attribute values response for the given
   * category. This might be overridden by subclasses with different requirements
   * for parsing/handling the response from the GetPrinterAttributes.
   * 
   * @param response the response of the GetPrinterAttributes IPP request
   * @param category the category for which the supported values are requested
   * @return A object indicating the supported values for the given attribute 
   * category, or <code>null</code> if this print service doesn't support the 
   * given attribute category at all.
   * 
   * @see #getSupportedAttributeValues(Class, DocFlavor, AttributeSet)
   */
  protected Object handleSupportedAttributeValuesResponse(IppResponse response, 
    Class category)
  {
    List printerAtts = response.getPrinterAttributes();
   
    // only one will be returned
    Map printerAttribute = (Map) printerAtts.get(0);
    Class suppCategory = IppUtilities.getSupportedCategory(category);
    Set attr = (Set) printerAttribute.get(suppCategory);
    
    // We sometime assume its a single instance with arbritrary value just indicating 
    // support or an array which is returned. This is because I sometimes just choosed
    // what sounds right to me - as I have yet to find a printer which supports every 
    // special category in the SUN implementation to see what they return :-)
    
    //  Map whats in the JSP API
    if (suppCategory.equals(JobPrioritySupported.class))
      return (JobPrioritySupported) attr.toArray(new JobPrioritySupported[1])[0];
    if (suppCategory.equals(JobHoldUntilSupported.class))
      return new JobHoldUntil(new Date());
    if (suppCategory.equals(JobSheetsSupported.class))
      return JobSheetsSupported.getAssociatedAttributeArray(attr);
    if (suppCategory.equals(MultipleDocumentHandlingSupported.class))
      return MultipleDocumentHandlingSupported.getAssociatedAttributeArray(attr);
    if (suppCategory.equals(CopiesSupported.class))
      return (CopiesSupported) attr.toArray(new CopiesSupported[1])[0];
    if (suppCategory.equals(FinishingsSupported.class))
      return FinishingsSupported.getAssociatedAttributeArray(attr);
    if (suppCategory.equals(PageRangesSupported.class))
      return new PageRanges[] { new PageRanges(1, Integer.MAX_VALUE) };    
    if (suppCategory.equals(OrientationRequestedSupported.class))
      return OrientationRequestedSupported.getAssociatedAttributeArray(attr);
    if (suppCategory.equals(MediaSupported.class))
      return MediaSupported.getAssociatedAttributeArray(attr);
    if (suppCategory.equals(PrinterResolutionSupported.class))
      return PrinterResolutionSupported.getAssociatedAttributeArray(attr);
    if (suppCategory.equals(PrintQualitySupported.class))
      return PrintQualitySupported.getAssociatedAttributeArray(attr);
    if (suppCategory.equals(CompressionSupported.class))
      return CompressionSupported.getAssociatedAttributeArray(attr);
    // Special handling as it might also be in range of integers
    if (suppCategory.equals(NumberUpSupported.class))
      {
        NumberUpSupported[] tmp = (NumberUpSupported[]) 
          attr.toArray(new NumberUpSupported[attr.size()]);

        if (attr.size() == 1) // number-up maybe in rangeofintegers
          return tmp[0];

        int[][] members = new int[attr.size()][2];
        for (int j = 0; j < attr.size(); j++)
          {
            int value = tmp[j].getMembers()[0][0];
            members[j] = new int[] { value, value };
          }

        NumberUpSupported supported = new NumberUpSupported(members);
        return supported;
      }
        
    return null;
  }  
  
  /**
   * @see javax.print.PrintService#getSupportedDocFlavors()
   */
  public DocFlavor[] getSupportedDocFlavors()
  {
    return (DocFlavor[]) flavors.toArray(new DocFlavor[flavors.size()]);
  }

  /**
   * This is done by a validate-job operation and actually implemented in 
   * this generic IPP reference implementation. Subclasses which does
   * not correctly support Validate-Job operation might want to override this.
   *
   * @see PrintService#getUnsupportedAttributes(DocFlavor, AttributeSet)
   */
  public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
                                               AttributeSet attributes)
  {    
    if (flavor != null && !isDocFlavorSupported(flavor))
      throw new IllegalArgumentException("flavor is not supported");

    IppResponse response = null;
    try
      {
        IppRequest request = new IppRequest(printerUri.getURI(), user, passwd);
        short operationId = (short) OperationsSupported.VALIDATE_JOB.getValue();
        request.setOperationID(operationId);
        request.setOperationAttributeDefaults();
        request.addOperationAttribute(printerUri);
        request.addOperationAttribute(Fidelity.FIDELITY_TRUE);
        
        if (attributes != null && attributes.size() > 0)
          {
            request.addAndFilterJobOperationAttributes(attributes);
            request.addAndFilterJobTemplateAttributes(attributes);
          }
        
        if (flavor != null)
          {
            DocumentFormat f = DocumentFormat.createDocumentFormat(flavor);
            request.addOperationAttribute(f);
          }
        
        response = request.send();
        
        int status = response.getStatusCode();
        if (! (status == IppStatusCode.SUCCESSFUL_OK
             || status == IppStatusCode.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUED_ATTRIBUTES
             || status == IppStatusCode.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) )
          {
            logger.log(Component.IPP, "Statuscode not OK - got:" + status);
          }
      }
    catch (IOException e)
      {
        // method cannot throw exception - just log
        logger.log(Component.IPP, "IOException", e);
      }
    catch (IppException e)
      {
        // method cannot throw exception - just log
        logger.log(Component.IPP, "IPPException", e);
      }

    // Validate Jobs returns only Unsupported and Operation  
    List unsupportedMaps = response.getUnsupportedAttributes();    
    if (unsupportedMaps.size() == 0)
      return  null;
    
    Map unsupportedAttr = (Map) unsupportedMaps.get(0);
    if (unsupportedAttr.size() == 0)
      return null;
    
    // Convert the return map with unsupported attributes 
    // into an AttribueSet instance
    HashAttributeSet set = new HashAttributeSet();
    Iterator it = unsupportedAttr.values().iterator();
    while (it.hasNext())
      {
        Set unsupported = (Set) it.next();
        Iterator it2 = unsupported.iterator();
        while (it2.hasNext())
          set.add((Attribute) it2.next());        
      }
    
    return set;
  }

  /**
   * @see PrintService#isAttributeCategorySupported(Class)
   */
  public boolean isAttributeCategorySupported(Class category)
  {
    if (category == null)
      throw new NullPointerException("category may not be null");
    
    if (! Attribute.class.isAssignableFrom(category))
      throw new IllegalArgumentException("category must be of type Attribute");
    
    return Arrays.asList(getSupportedAttributeCategories()).contains(category);
  }

  /**
   * @see PrintService#isAttributeValueSupported(Attribute, DocFlavor, AttributeSet)
   */
  public boolean isAttributeValueSupported(Attribute attrval, DocFlavor flavor,
                                           AttributeSet attributes)
  {
    // just redirect to getSupportedAttributeValues    
    Object values = getSupportedAttributeValues(attrval.getCategory(), 
                                                flavor, attributes);    
    // null means none supported
    if (values == null)
      return false;
    
    // object may be an array
    if (values.getClass().isArray())
      return Arrays.asList((Object[]) values).contains(attrval);
    
    // may be a single instance of the category (value is irrelevant)
    if (values.getClass().equals(attrval.getCategory()))
      return true;
       
    // a single instance of another class to give the bounds    
    // copies
    if (values.getClass().equals(CopiesSupported.class))
      return ((CopiesSupported) values).contains((IntegerSyntax) attrval);    
    // number up
    if (values.getClass().equals(NumberUpSupported.class))
      return ((NumberUpSupported) values).contains((IntegerSyntax) attrval);    
    // job priority
    if (values.getClass().equals(JobPrioritySupported.class))
      {
        JobPriority priority = (JobPriority) attrval;
        JobPrioritySupported maxSupported = (JobPrioritySupported) values;
        if (priority.getValue() < maxSupported.getValue())
          return true;
      }
    
    // I am unsure if these might also show up - not yet found a printer where 
    // Suns implementation supports them: 
    // JobImpressionsSupported, JobKOctetsSupported, JobMediaSheetsSupported
    
    return false;
  }

 
  /**
   * @see javax.print.PrintService#isDocFlavorSupported(DocFlavor)
   */
  public boolean isDocFlavorSupported(DocFlavor flavor)
  {
    if (flavor == null)
      throw new NullPointerException("DocFlavor may not be null.");
    
    return flavors.contains(flavor);
  }

  
  /**
   * @see PrintService#addPrintServiceAttributeListener(PrintServiceAttributeListener)
   */
  public void addPrintServiceAttributeListener(
    PrintServiceAttributeListener listener)
  {
    printServiceAttributeListener.add(listener);
  }
  
  /**
   * @see PrintService#removePrintServiceAttributeListener(PrintServiceAttributeListener)
   */
  public void removePrintServiceAttributeListener(
    PrintServiceAttributeListener listener)
  {
    printServiceAttributeListener.remove(listener);
  }
  
  /**
   * Returns "IppPrinter: " + <code>getName()</code>
   * @return The string representation.
   */
  public String toString()
  {
    return "IppPrinter: " + getName();
  } 
  
  /**
   * Returns the printer-uri of this print service.
   * 
   * @return The printer-uri attribute.
   */
  public PrinterURI getPrinterURI()
  {
    return printerUri;
  }  
}
