///////////////////////////////////////////////////////////////////////////////
//
// TRIP Connectivity Framework
// Sample File Filter Adapter for Java
//
///////////////////////////////////////////////////////////////////////////////
//
// Modification History:
//	   TF    2011-09-24      Created
//
///////////////////////////////////////////////////////////////////////////////

package ag.smaser.trip.filefilter.example;

import ag.smaser.trip.filefilter.AdapterOutputType;
import ag.smaser.trip.filefilter.Conversion;
import ag.smaser.trip.filefilter.ConvertAbility;
import ag.smaser.trip.filefilter.FilterAdapter;
import ag.smaser.trip.filefilter.FileFilterException;
import ag.smaser.trip.filefilter.FilterReturnCode;
import java.io.DataInputStream;
import java.io.IOException;

/**
 * Example TRIPcof file filter adapter.
 *
 * This just takes text files and echoes them back to the application. The
 * text in the files is assumed to be encoded in UTF-8.
 */
public class ExampleAdapter extends FilterAdapter
{
    private DataInputStream m_stream;

    public ExampleAdapter()
    {
        super();
        m_stream = null;
    }


    /**
     * Check if the specified provided file can be converted into the specified
     * target format.
     *
     * </p>The parameter does not necessarily match a file on the local file
     * system. This method must not base its logic upon the false assumption
     * that the file name represents a local file.</p>
     *
     * @param targetFormat File format to convert to
     * @param filename The name of the file to be converted
     * @return ConvertAbility.Yes if conversion definitely can be performed,
     *         ConvertAbility.Maybe if conversion is likely (but not certain) to
     *         be succesful, and ConvertAbility.No if the conversion is not supported.
     */
    @Override
    public ConvertAbility checkConversion(AdapterOutputType targetFormat, String filename)
    {
        int nDotIdx = filename.lastIndexOf('.');
        if (nDotIdx<0)
            return ConvertAbility.Maybe; // Suffix-less files may be text...

        String strSuffix = filename.substring(nDotIdx+1).toLowerCase();
        if (strSuffix.equals("txt") || strSuffix.equals("conf") || strSuffix.equals("ini"))
        {
            if (targetFormat == AdapterOutputType.Text)
                return ConvertAbility.Yes;
        }

        return ConvertAbility.No;
    }

    /**
     * Prepare to start the conversion. Allows the custom adapter to reserve
     * resource and to perform other conversion-specific initializations.
     * @param conv State object holding information about the conversion
     * @throws FileFilterException If the conversion could not be started.
     */
    @Override
    public void openConversion(Conversion conv) throws FileFilterException
    {
        try
        {
            m_stream = new DataInputStream(conv.getInputStream());
        }
        catch (Exception x)
        {
            throw new FileFilterException(FilterReturnCode.CouldNotOpen,"Unable to create DataInputStream",x);
        }
    }

    /**
     * Ends a conversion and releases any resources used by it.
     * @param conv State object holding information about the conversion
     * @throws FileFilterException If the conversion could not be closed.
     */
    @Override
    public void closeConversion(Conversion conv) throws FileFilterException
    {
        if (m_stream != null)
        {
            try
            {
                m_stream.close();
            }
            catch (Exception ignore) {}
            m_stream = null;
        }
    }

    /**
     * The main conversion method - this is where all the real action happens.
     * @param conv State object holding information about the conversion
     * @param filename Optional name of output file (ignored in this adapter)
     * @throws FileFilterException The only type of exception that must get thrown if the conversion fails
     */
    @Override
    public void convert(Conversion conv, String filename) throws FileFilterException
    {
        byte[] chunk = null;
        int bytesRead = 0;

        // Sanity check - are we in the correct state?
        if (null == m_stream)
            throw new FileFilterException(FilterReturnCode.InvalidArgument, "Conversion has not been opened.");

        // Sanity check - output file format type
        if (conv.getOutputType() != AdapterOutputType.Text)
            throw new FileFilterException(FilterReturnCode.InvalidOutputType, "Unexpected output format");

        try
        {
            // Passthrough "conversion" here only. In a real converter you
            // would process the file data (likely using a third party library)
            // in order to extract text and properties from the file, or to
            // convert to HTML (whatever is relevant to do in your adapter).

            // NOTE: This code assumes that the encoding of the text file
            //       is in UTF-8.

            chunk = new byte[1024];
            while ((bytesRead = m_stream.read(chunk))>0)
                addConversionResult(conv,chunk,bytesRead);
        }
        catch (IOException x)
        {
            throw new FileFilterException(FilterReturnCode.ConversionError,"Unable to read UTF data from input stream",x);
        }
    }
}

