/* IppRequest.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.debug.Component;
import gnu.classpath.debug.SystemLogger;
import gnu.javax.print.ipp.attribute.CharsetSyntax;
import gnu.javax.print.ipp.attribute.NaturalLanguageSyntax;
import gnu.javax.print.ipp.attribute.RequestedAttributes;
import gnu.javax.print.ipp.attribute.job.AttributesCharset;
import gnu.javax.print.ipp.attribute.job.AttributesNaturalLanguage;
import gnu.javax.print.ipp.attribute.job.JobId;
import gnu.javax.print.ipp.attribute.job.JobUri;
import gnu.javax.print.ipp.attribute.printer.DocumentFormat;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.logging.Logger;

import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.DateTimeSyntax;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.ResolutionSyntax;
import javax.print.attribute.SetOfIntegerSyntax;
import javax.print.attribute.TextSyntax;
import javax.print.attribute.URISyntax;
import javax.print.attribute.standard.Compression;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.DocumentName;
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.JobKOctets;
import javax.print.attribute.standard.JobMediaSheets;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.JobOriginatingUserName;
import javax.print.attribute.standard.JobPriority;
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.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.PrinterURI;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;

/**
 * <code>IppRequest</code> models a request to an IPP compatible
 * server as described in RFC 2910 - IPP/1.1: Encoding and Transport.
 * <p>
 * The byte stream is structured as follows (for an official description
 * please have a look at the RFC document mentioned above):
 * <ul>
 * <li>version-number          - 2 bytes - required</li>
 * <li>operation-id            - 2 bytes - required</li>
 * <li>request-id              - 4 bytes - required</li>
 * <li>attribute-group         - n bytes - 0 or more</li>
 * <li>end-of-attributes-tag   - 1 byte  - required</li>
 * <li>data                    - q bytes - optional</li>
 * </ul>
 * </p>
 *
 * @author Wolfgang Baer (WBaer@gmx.de)
 */
public class IppRequest
{

  /**
   * The printer-poll timeout.
   */
  private static final int timeout = 1000;

  /**
   * Helper class used to write the attributes of a request
   * into the supplied data output stream in the correct way.
   *
   * @author Wolfgang Baer (WBaer@gmx.de)
   */
  class RequestWriter
  {
    private DataOutputStream out;

    /**
     * Creates a RequestWriter.
     *
     * @param stream the stream to write to.
     */
    RequestWriter(DataOutputStream stream)
    {
      out = stream;
    }

    /**
     * Writes an attribute in IntegerSyntax into the stream.
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(IntegerSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.INTEGER);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(4); // length, integer is 4 bytes
      out.writeInt(attribute.getValue());
    }

    /**
     * Writes an attribute in EnumSyntax into the stream.
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(EnumSyntax attribute) throws IOException
    {
      // in JPS API enum syntax is used for enums, keyword and boolean types
      String name = ((Attribute) attribute).getName();

      // the enum value types
      if (attribute instanceof Finishings
          || attribute instanceof OrientationRequested
          || attribute instanceof PrintQuality)
        {
          out.writeByte(IppValueTag.ENUM);
          out.writeShort(name.length());
          out.write(name.getBytes());
          out.writeShort(4); // length, enum is 4 bytes
          out.writeInt(attribute.getValue());
        }
      // the boolean value type
      else if (attribute instanceof Fidelity)
        {
          out.writeByte(IppValueTag.BOOLEAN);
          out.writeShort(name.length());
          out.write(name.getBytes());
          out.writeShort(1); // length, boolean is 1 bytes
          out.writeByte(attribute.getValue() == 0 ? 0x00 : 0x01);
        }
      // the keyword value types
      else
        {
          String keyword = attribute.toString();
          out.writeByte(IppValueTag.KEYWORD);
          out.writeShort(name.length());
          out.write(name.getBytes());
          out.writeShort(keyword.length());
          out.write(keyword.getBytes());
        }
    }

    /**
     * Writes an attribute in SetOfIntegerSyntax into the stream.
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(SetOfIntegerSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      int[][] ranges = attribute.getMembers();
      for (int i = 0; i < ranges.length; i++)
        {
          out.writeByte(IppValueTag.RANGEOFINTEGER);
          if (i == 0)
            {
              out.writeShort(name.length());
              out.write(name.getBytes());
            }
          else
            out.writeShort(0x0000); // only name-length

          out.writeShort(8); // range is 8 bytes
          out.writeInt(ranges[i][0]);
          out.writeInt(ranges[i][1]);
        }
    }

    /**
     * Writes an attribute in ResolutionSyntax into the stream.
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(ResolutionSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.RESOLUTION);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(9); // length fixed to 9
      out.writeInt(attribute.getCrossFeedResolution(ResolutionSyntax.DPI));
      out.writeInt(attribute.getFeedResolution(ResolutionSyntax.DPI));
      out.writeByte(ResolutionSyntax.DPI);
    }

    /**
     * Writes an attribute in DateTimeSyntax into the stream.
     * <p>
     * The syntax value is defined as 11 octets follwing the
     * DateAndTime format of RFC 1903. (see IppResponse)
     * </p>
     *
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(DateTimeSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.DATETIME);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(11); // length fixed to 11

      Date date = attribute.getValue();
      Calendar cal = new GregorianCalendar();
      cal.setTime(date);

      out.writeShort(cal.get(Calendar.YEAR));
      out.writeByte(cal.get(Calendar.MONTH));
      out.writeByte(cal.get(Calendar.DAY_OF_MONTH));
      out.writeByte(cal.get(Calendar.HOUR_OF_DAY));
      out.writeByte(cal.get(Calendar.MINUTE));
      int second = cal.get(Calendar.SECOND);
      out.writeByte(second == 0 ? 60 : second);
      out.writeByte(cal.get(Calendar.MILLISECOND) / 100);

      int offsetInMillis = cal.get(Calendar.ZONE_OFFSET);
      char directionFromUTC = '+';
      if (offsetInMillis < 0)
        {
          directionFromUTC = '-';
          offsetInMillis = offsetInMillis * (-1);
        }

      out.writeByte(directionFromUTC);
      out.writeByte(offsetInMillis / 3600000); // hours
      out.writeByte((offsetInMillis % 3600000) / 60000); // minutes
    }

    /**
     * Writes an attribute in TextSyntax into the stream.
     * <p>
     * By default attributes are qritten as TEXT_WITHOUT_LANGUAGE value-tag.
     * As some attributes in the JPS are TextSyntax attributes but actually
     * of NAME value-tag in IPP this method checks for these attributes and
     * writes them as NAME_WITHOUT_LANGUAGE value-tag into the stream.
     * </p>
     *
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(TextSyntax attribute) throws IOException
    {
      // We only use *WithoutLanguage, correct according to spec.
      String name = ((Attribute) attribute).getName();

      if (attribute instanceof RequestingUserName
          || attribute instanceof JobName
          || attribute instanceof DocumentName
          || attribute instanceof JobOriginatingUserName)
        out.writeByte(IppValueTag.NAME_WITHOUT_LANGUAGE);
      else if (attribute instanceof DocumentFormat)
        out.writeByte(IppValueTag.MIME_MEDIA_TYPE);
      else
        out.writeByte(IppValueTag.TEXT_WITHOUT_LANGUAGE);

      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(attribute.getValue().length());
      out.write(attribute.getValue().getBytes());
    }

    /**
     * Writes an attribute in URISyntax into the stream.
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(URISyntax attribute) throws IOException
    {
      // only uriScheme syntax type should not appear
      // in a request (reference-uri-schemes-supported)
      String name = ((Attribute) attribute).getName();
      String uriAscii = attribute.getURI().toASCIIString();
      out.writeByte(IppValueTag.URI);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(uriAscii.length());
      out.write(uriAscii.getBytes());
    }

    /**
     * Writes an attribute in CharsetSyntax into the stream.
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(CharsetSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.CHARSET);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(attribute.getValue().length());
      out.write(attribute.getValue().getBytes());
    }

    /**
     * Writes an attribute in NaturalLanguageSyntax into the stream.
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(NaturalLanguageSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.NATURAL_LANGUAGE);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(attribute.getValue().length());
      out.write(attribute.getValue().getBytes());
    }

    /**
     * Writes an attribute in RequestedAttributes into the stream.
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(RequestedAttributes attribute) throws IOException
    {
      String[] values = attribute.getValues();

      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.KEYWORD);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(values[0].length());
      out.write(values[0].getBytes());

      for (int i=1; i < values.length; i++)
        {
          out.writeByte(IppValueTag.KEYWORD);
          out.writeShort(0x0000); // length for additional value
          out.writeShort(values[i].length());
          out.write(values[i].getBytes());
        }
    }


    /**
     * Writes the given operation attribute group of the given map instance
     * (key=group, values=set of attributes) into the supplied data
     * output stream.
     *
     * @param attributes the set with the attributes.
     *
     * @throws IOException if thrown by the used DataOutputStream.
     * @throws IppException if unknown attributes occur.
     */
    public void writeOperationAttributes(AttributeSet attributes)
        throws IOException, IppException
    {
      out.write(IppDelimiterTag.OPERATION_ATTRIBUTES_TAG);

      // its essential to write these two in this order and as first ones
      Attribute att = attributes.get(AttributesCharset.class);
      write((CharsetSyntax) att);

      logger.log(Component.IPP, "Attribute: Name: <"
        + att.getCategory().getName() + "> Value: <" + att.toString() + ">");

      attributes.remove(AttributesCharset.class);

      att = attributes.get(AttributesNaturalLanguage.class);
      write((NaturalLanguageSyntax) att);
      attributes.remove(AttributesNaturalLanguage.class);

      logger.log(Component.IPP, "Attribute: Name: <"
        + att.getCategory().getName() + "> Value: <" + att.toString() + ">");

      // furthermore its essential to now write out the target attribute
      PrinterURI printerUri = (PrinterURI) attributes.get(PrinterURI.class);
      JobUri jobUri = (JobUri) attributes.get(JobUri.class);
      JobId jobId = (JobId) attributes.get(JobId.class);
      RequestedAttributes reqAttrs
        = (RequestedAttributes)attributes.get(RequestedAttributes.class);
      if (printerUri != null && jobId == null && jobUri == null)
        {
          write(printerUri);
          attributes.remove(PrinterURI.class);
          logger.log(Component.IPP, "Attribute: Name: <" + printerUri
            .getCategory().getName() + "> Value: <" + printerUri.toString() + ">");
        }
      else if (jobUri != null && jobId == null && printerUri == null)
        {
          write(jobUri);
          attributes.remove(JobUri.class);
          logger.log(Component.IPP, "Attribute: Name: <" + jobUri
            .getCategory().getName() + "> Value: <" + jobUri.toString() + ">");
        }
      else if (printerUri != null && jobId != null && jobUri == null)
        {
          write(printerUri); // must be third
          write(jobId);
          attributes.remove(PrinterURI.class);
          attributes.remove(JobId.class);
          logger.log(Component.IPP, "Attribute: Name: <" + printerUri
            .getCategory().getName() + "> Value: <" + printerUri.toString() + ">");
          logger.log(Component.IPP, "Attribute: Name: <" + jobId.getCategory()
            .getName() + "> Value: <" + jobId.toString() + ">");
        }
      else if (jobUri != null && jobId != null)
        {
          write(jobUri);
          attributes.remove(JobUri.class);
          attributes.remove(JobId.class); // MUST NOT redundant
          logger.log(Component.IPP, "Attribute: Name: <" + jobUri.getCategory()
            .getName() + "> Value: <" + jobUri.toString() + ">");
        }
      else if (reqAttrs != null)
        {
          write(reqAttrs);
          attributes.remove(RequestedAttributes.class);
          logger.log(Component.IPP, "RequestedAttributes: <" + reqAttrs + ">");
        }
      else
        {
          throw new IppException("Unknown target operation attribute combination.");
        }

      writeAttributes(attributes);
    }

    /**
     * Writes the given attribute groups of the given map instance
     * (key=group, values=set of attributes) into the supplied data
     * output stream.
     *
     * @param attributes the set with the attributes.
     *
     * @throws IOException if thrown by the used DataOutputStream.
     * @throws IppException if unknown attributes occur.
     */
    public void writeAttributes(AttributeSet attributes)
        throws IOException, IppException
    {
      Attribute[] attributeArray = attributes.toArray();
      for (int i = 0; i < attributeArray.length; i++)
        {
          logger.log(Component.IPP, "Attribute: Name: <" + attributeArray[i]
            .getCategory().getName() + "> Value: <"
            + attributeArray[i].toString() + ">");

          if (attributeArray[i] instanceof IntegerSyntax)
            write((IntegerSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof TextSyntax)
            write((TextSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof DateTimeSyntax)
            write((DateTimeSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof ResolutionSyntax)
            write((ResolutionSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof SetOfIntegerSyntax)
            write((SetOfIntegerSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof EnumSyntax)
            write((EnumSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof URISyntax)
            write((URISyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof CharsetSyntax)
            write((CharsetSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof NaturalLanguageSyntax)
            write((NaturalLanguageSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof RequestedAttributes)
            write((RequestedAttributes) attributeArray[i]);
          else
            throw new IppException("Unknown syntax type");
        }
    }

  }

  /**
   * Logger for tracing - enable by passing
   * -Dgnu.classpath.debug.components=ipp to the vm.
   */
  static final Logger logger = SystemLogger.SYSTEM;

  /**
   * The request id counter simply counts up
   * to give unique request ids per JVM instance.
   */
  private static int requestIdCounter = 1;

  /** The IPP version defaults to 1.1 */
  private static final short VERSION = 0x0101;

  /** Signals if the request is already on its way */
  private boolean alreadySent = false;

  /** The operation type of this request. */
  private short operation_id;

  /**
   * The request id of this request. This is
   * assigned automatically by the constructor.
   */
  private final int request_id;

  private AttributeSet operationAttributes;

  private AttributeSet printerAttributes;

  private AttributeSet jobAttributes;

  private Object data;

  private URI requestUri;

  /** The underlying connection - IPP is http based */
  private HttpURLConnection  connection;

  /**
   * Creates an IPPRequest instance.
   *
   * @param uri the URI of the request
   * @param user the user if any
   * @param password the password of the supplied user
   */
  public IppRequest(URI uri, String user, String password)
  {
    request_id = incrementRequestIdCounter();
    requestUri = uri;

    try
      {
        URL url = new URL("http",
                      user == null
                      ? uri.getHost() : user + ":"
                      + password + "@" + uri.getHost(),
                      uri.getPort(), uri.getPath());

        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);

        connection.setRequestProperty("Content-type", "application/ipp");
        connection.setRequestProperty("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2");
      }
    catch (IOException e)
      {
        // MalformedURLException - uri is already checked
        // ProtocolException - POST is correct method type
        // IOException -HTTPURLConnection constructor actually
        // does never throw this exception.
        logger.log(Component.IPP, "Unexpected IOException", e);
      }

    logger.log(Component.IPP, "[IppConnection] Host: " + uri.getHost()
                              + " Port: " + uri.getPort() + " Path: "
                              + uri.getPath());
  }

  /**
   * Synchronized method to be called by the constructor
   * to assign a unique request id to this request.
   *
   * @return The unique request id.
   */
  private synchronized int incrementRequestIdCounter()
  {
    return IppRequest.requestIdCounter++;
  }

  /**
   * Returns the id of this request.
   *
   * @return The request ID.
   */
  public int getRequestID()
  {
    return request_id;
  }

  /**
   * Sets the data of the request. The data used in this
   * request will be the one of the supplied inputstream
   * instead of the alternative byte array possibility.
   *
   * @param stream the input stream to use for the data.
   */
  public void setData(InputStream stream)
  {
    data = stream;
  }

  /**
   * Sets the data of the request. The data used in this
   * request will be the one of the supplied byte[]
   * instead of the alternative input stream possibility.
   *
   * @param bytes the byte[] to use for the data.
   */
  public void setData(byte[] bytes)
  {
    data = bytes;
  }

  /**
   * Sets the operation id for this request.
   *
   * @param id the operation id.
   */
  public void setOperationID(short id)
  {
    operation_id = id;
  }

  /**
   * Adds the default values for the operation
   * attributes "attributes-charset" and
   * "attributes-natural-language"
   */
  public void setOperationAttributeDefaults()
  {
    if (operationAttributes == null)
      operationAttributes = new HashAttributeSet();

    operationAttributes.add(AttributesCharset.UTF8);
    operationAttributes.add(AttributesNaturalLanguage.EN);
  }

  /**
   * Add the job attribute of this request to the given
   * attribute set.
   *
   * @param attribute the job attribute.
   */
  public void addJobAttribute(Attribute attribute)
  {
    if (jobAttributes == null)
      jobAttributes = new HashAttributeSet();

    jobAttributes.add(attribute);
  }

  /**
   * Sets the printer attribute of this request to the given
   * attribute set.
   *
   * @param attribute the printer attribute.
   */
  public void addPrinterAttributes(Attribute attribute)
  {
    if (printerAttributes == null)
      printerAttributes = new HashAttributeSet();

    printerAttributes.add(attribute);
  }

  /**
   * Adds the given attribute to the operation attributes set.
   *
   * @param attribute the operation attribute to add.
   */
  public void addOperationAttribute(Attribute attribute)
  {
    if (operationAttributes == null)
      operationAttributes = new HashAttributeSet();

    operationAttributes.add(attribute);
  }

  /**
   * Filters from the given attribute set the job operation out
   * and adds them to the operation attributes set.
   *
   * @param set the attributes to filter, may not be <code>null</code>.
   */
  public void addAndFilterJobOperationAttributes(AttributeSet set)
  {
    if (operationAttributes == null)
      operationAttributes = new HashAttributeSet();

    // document-natural-language - not defined in JPS attributes
    // document-format - specified outside, special treatment
    Attribute[] tmp = set.toArray();
    for (int i = 0; i < tmp.length; i++)
      {
        if (tmp[i].getCategory().equals(JobName.class)
            || tmp[i].getCategory().equals(Fidelity.class)
            || tmp[i].getCategory().equals(JobImpressions.class)
            || tmp[i].getCategory().equals(JobKOctets.class)
            || tmp[i].getCategory().equals(JobMediaSheets.class)
            || tmp[i].getCategory().equals(Compression.class)
            || tmp[i].getCategory().equals(DocumentName.class)
            || tmp[i].getCategory().equals(RequestingUserName.class))

          operationAttributes.add(tmp[i]);
      }
  }

  /**
   * Filters from the given attribute set the job template attributes
   * out and adds them to the job attributes set.
   *
   * @param set the attributes to filter, may not be <code>null</code>.
   */
  public void addAndFilterJobTemplateAttributes(AttributeSet set)
  {
    if (jobAttributes == null)
      jobAttributes = new HashAttributeSet();

    // document-natural-language - not defined in JPS attributes
    // document-format - specified outside, special treatment
    Attribute[] tmp = set.toArray();
    for (int i = 0; i < tmp.length; i++)
      {
        if (tmp[i].getCategory().equals(JobPriority.class)
            || tmp[i].getCategory().equals(JobHoldUntil.class)
            || tmp[i].getCategory().equals(JobSheets.class)
            || tmp[i].getCategory().equals(MultipleDocumentHandling.class)
            || tmp[i].getCategory().equals(Copies.class)
            || tmp[i].getCategory().equals(Finishings.class)
            || tmp[i].getCategory().equals(PageRanges.class)
            || tmp[i].getCategory().equals(NumberUp.class)
            || tmp[i].getCategory().equals(OrientationRequested.class)
            || tmp[i].getCategory().equals(Media.class)
            || tmp[i].getCategory().equals(PrinterResolution.class)
            || tmp[i].getCategory().equals(PrintQuality.class)
            || tmp[i].getCategory().equals(SheetCollate.class)
            || tmp[i].getCategory().equals(Sides.class))

          jobAttributes.add(tmp[i]);
      }
  }

  /**
   * Does some validation of the supplied parameters and then
   * sends the request to the ipp server or service.
   *
   * @return The response if any.
   *
   * @throws IllegalStateException if request is already sent
   * @throws IppException if connection or request failed.
   * @throws IOException if writing of the header, attributes or footer fails.
   */
  public IppResponse send() throws IppException, IOException
  {
    if (alreadySent)
      throw new IllegalStateException("Request is already sent");

    alreadySent = true;

    OutputStream stream = connection.getOutputStream();
    DataOutputStream out = new DataOutputStream(stream);

    //  the header 8 bytes long
    out.writeShort(VERSION);
    out.writeShort(operation_id);
    out.writeInt(request_id);

    logger.log(Component.IPP, "OperationID: " + Integer.toHexString(operation_id)
      + " RequestID: " + request_id);

    // Pass stuff the the attribute writer which knows how to
    // write the attributes in correct order
    logger.log(Component.IPP, "Operation Attributes");

    RequestWriter writer = new RequestWriter(out);
    writer.writeOperationAttributes(operationAttributes);

    if (jobAttributes != null)
      {
        logger.log(Component.IPP, "Job Attributes");
        out.write(IppDelimiterTag.JOB_ATTRIBUTES_TAG);
        writer.writeAttributes(jobAttributes);
      }
    if (printerAttributes != null)
      {
        logger.log(Component.IPP, "Printer Attributes");
        out.write(IppDelimiterTag.PRINTER_ATTRIBUTES_TAG);
        writer.writeAttributes(printerAttributes);
      }

    // write the delimiter to the data
    out.write(IppDelimiterTag.END_OF_ATTRIBUTES_TAG);

    // check if data is byte[] or inputstream
    if (data instanceof InputStream)
      {
        byte[] readbuf = new byte[2048];
        int len = 0;
        while( (len = ((InputStream) data).read(readbuf)) > 0)
          out.write(readbuf, 0, len);
      }
    else if (data != null)
      {
        out.write((byte[]) data);
      }

    out.flush();
    stream.flush();

    // Set the connection timeout, for if the printer is offline.
    // FIXME: The print services polling should probably be done in its
    // own thread.
    connection.setConnectTimeout( timeout );

    int responseCode = connection.getResponseCode();

    if (responseCode == HttpURLConnection.HTTP_OK)
      {
        IppResponse response = new IppResponse(requestUri, operation_id);
        response.setResponseData(connection.getInputStream());
        return response;
      }

    logger.log(Component.IPP, "HTTP-Statuscode: " + responseCode);

    throw new IppException("Request failed got HTTP status code "
                           + responseCode);
  }

}
