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

package javax.print;

import java.io.ByteArrayInputStream;
import java.io.CharArrayReader;
import java.io.StringReader;
import java.io.InputStream;
import java.io.IOException;
import java.io.Reader;
import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.DocAttributeSet;

/**
 * This class is an implementation of interface <code>Doc</code> that can
 * be used in many common printing requests.
 * It can handle all of the presently defined "pre-defined" doc flavors
 * defined as static variables in the DocFlavor class.
 * <p>
 * In particular this class implements certain required semantics of the
 * Doc specification as follows:
 * <ul>
 * <li>constructs a stream for the service if requested and appropriate.
 * <li>ensures the same object is returned for each call on a method.
 * <li>ensures multiple threads can access the Doc
 * <li>performs some validation of that the data matches the doc flavor.
 * </ul>
 * Clients who want to re-use the doc object in other jobs,
 * or need a MultiDoc will not want to use this class.
 * <p>
 * If the print data is a stream, or a print job requests data as a
 * stream, then <code>SimpleDoc</code> does not monitor if the service
 * properly closes the stream after data transfer completion or job
 * termination.
 * Clients may prefer to use provide their own implementation of doc that
 * adds a listener to monitor job completion and to validate that
 * resources such as streams are freed (ie closed).
 */

public final class SimpleDoc implements Doc {

    private DocFlavor flavor;
    private DocAttributeSet attributes;
    private Object printData;
    private Reader reader;
    private InputStream inStream;

    /**
     * Constructs a <code>SimpleDoc</code> with the specified
     * print data, doc flavor and doc attribute set.
     * @param printData the print data object
     * @param flavor the <code>DocFlavor</code> object
     * @param attributes a <code>DocAttributeSet</code>, which can
     *                   be <code>null</code>
     * @throws IllegalArgumentException if <code>flavor</code> or
     *         <code>printData</code> is <code>null</code>, or the
     *         <code>printData</code> does not correspond
     *         to the specified doc flavor--for example, the data is
     *         not of the type specified as the representation in the
     *         <code>DocFlavor</code>.
     */
    public SimpleDoc(Object printData,
                     DocFlavor flavor, DocAttributeSet attributes) {

       if (flavor == null || printData == null) {
           throw new IllegalArgumentException("null argument(s)");
       }

       Class repClass = null;
       try {
            repClass = Class.forName(flavor.getRepresentationClassName());
       } catch (Throwable e) {
           throw new IllegalArgumentException("unknown representation class");
       }

       if (!repClass.isInstance(printData)) {
           throw new IllegalArgumentException("data is not of declared type");
       }

       this.flavor = flavor;
       if (attributes != null) {
           this.attributes = AttributeSetUtilities.unmodifiableView(attributes);
       }
       this.printData = printData;
    }

   /**
     * Determines the doc flavor in which this doc object will supply its
     * piece of print data.
     *
     * @return  Doc flavor.
     */
    public DocFlavor getDocFlavor() {
        return flavor;
    }

    /**
     * Obtains the set of printing attributes for this doc object. If the
     * returned attribute set includes an instance of a particular attribute
     * <I>X,</I> the printer must use that attribute value for this doc,
     * overriding any value of attribute <I>X</I> in the job's attribute set.
     * If the returned attribute set does not include an instance
     * of a particular attribute <I>X</I> or if null is returned, the printer
     * must consult the job's attribute set to obtain the value for
     * attribute <I>X,</I> and if not found there, the printer must use an
     * implementation-dependent default value. The returned attribute set is
     * unmodifiable.
     *
     * @return  Unmodifiable set of printing attributes for this doc, or null
     *          to obtain all attribute values from the job's attribute
     *          set.
     */
    public DocAttributeSet getAttributes() {
        return attributes;
    }

    /*
     * Obtains the print data representation object that contains this doc
     * object's piece of print data in the format corresponding to the
     * supported doc flavor.
     * The <CODE>getPrintData()</CODE> method returns an instance of
     * the representation class whose name is given by
     * {@link DocFlavor#getRepresentationClassName() getRepresentationClassName},
     * and the return value can be cast
     * from class Object to that representation class.
     *
     * @return  Print data representation object.
     *
     * @exception  IOException if the representation class is a stream and
     *     there was an I/O error while constructing the stream.
     */
    public Object getPrintData() throws IOException {
        return printData;
    }

    /**
     * Obtains a reader for extracting character print data from this doc.
     * The <code>Doc</code> implementation is required to support this
     * method if the <code>DocFlavor</code> has one of the following print
     * data representation classes, and return <code>null</code>
     * otherwise:
     * <UL>
     * <LI> <code>char[]</code>
     * <LI> <code>java.lang.String</code>
     * <LI> <code>java.io.Reader</code>
     * </UL>
     * The doc's print data representation object is used to construct and
     * return a <code>Reader</code> for reading the print data as a stream
     * of characters from the print data representation object.
     * However, if the print data representation object is itself a
     * <code>Reader</code> then the print data representation object is
     * simply returned.
     * <P>
     * @return  a <code>Reader</code> for reading the print data
     *          characters from this doc.
     *          If a reader cannot be provided because this doc does not meet
     *          the criteria stated above, <code>null</code> is returned.
     *
     * @exception  IOException if there was an I/O error while creating
     *             the reader.
     */
    public Reader getReaderForText() throws IOException {

        if (printData instanceof Reader) {
            return (Reader)printData;
        }

        synchronized (this) {
            if (reader != null) {
                return reader;
            }

            if (printData instanceof char[]) {
               reader = new CharArrayReader((char[])printData);
            }
            else if (printData instanceof String) {
                reader = new StringReader((String)printData);
            }
        }
        return reader;
    }

    /**
     * Obtains an input stream for extracting byte print data from
     * this doc.
     * The <code>Doc</code> implementation is required to support this
     * method if the <code>DocFlavor</code> has one of the following print
     * data representation classes; otherwise this method
     * returns <code>null</code>:
     * <UL>
     * <LI> <code>byte[]</code>
     * <LI> <code>java.io.InputStream</code>
     * </UL>
     * The doc's print data representation object is obtained.  Then, an
     * input stream for reading the print data
     * from the print data representation object as a stream of bytes is
     * created and returned.
     * However, if the print data representation object is itself an
     * input stream then the print data representation object is simply
     * returned.
     * <P>
     * @return  an <code>InputStream</code> for reading the print data
     *          bytes from this doc.  If an input stream cannot be
     *          provided because this doc does not meet
     *          the criteria stated above, <code>null</code> is returned.
     *
     * @exception  IOException
     *     if there was an I/O error while creating the input stream.
     */
    public InputStream getStreamForBytes() throws IOException {

        if (printData instanceof InputStream) {
            return (InputStream)printData;
        }

        synchronized (this) {
            if (inStream != null) {
                return inStream;
            }

            if (printData instanceof byte[]) {
               inStream = new ByteArrayInputStream((byte[])printData);
            }
        }
        return inStream;
    }

}
