001    /*
002     * Jpkg - Java library and tools for operating system package creation.
003     *
004     * Copyright (c) 2007 Three Rings Design, Inc.
005     * All rights reserved.
006     *
007     * Redistribution and use in source and binary forms, with or without
008     * modification, are permitted provided that the following conditions
009     * are met:
010     * 1. Redistributions of source code must retain the above copyright
011     *    notice, this list of conditions and the following disclaimer.
012     * 2. Redistributions in binary form must reproduce the above copyright
013     *    notice, this list of conditions and the following disclaimer in the
014     *    documentation and/or other materials provided with the distribution.
015     * 3. Neither the name of the copyright owner nor the names of contributors
016     *    may be used to endorse or promote products derived from this software
017     *    without specific prior written permission.
018     *
019     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
023     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
024     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
025     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
026     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
027     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
029     * POSSIBILITY OF SUCH DAMAGE.
030     */
031    package com.threerings.jpkg.ant.dpkg.scripts.runner;
032    
033    import java.io.ByteArrayOutputStream;
034    import java.io.IOException;
035    import java.io.OutputStream;
036    
037    import javax.mail.MessagingException;
038    import javax.mail.internet.MimeUtility;
039    
040    import org.apache.commons.io.IOUtils;
041    
042    import com.threerings.jpkg.ant.dpkg.Dpkg;
043    import com.threerings.jpkg.ant.dpkg.DpkgData;
044    
045    /**
046     * A base64 encoded version of a {@link PackageScript} suitable for input to the uuencode command.
047     * This class is public as required by Velocity, and should not be considered part of the public API.
048     */
049    public class EncodedScript
050    {
051        /**
052         * Construct a new EncodedScript from the supplied {@link PackageScript}.
053         * @param source The {@link PackageScript} to encode.
054         * @param data The {@link DpkgData} to pass to the script.
055         * @throws IOException If the encoding fails.
056         */
057        public EncodedScript (PackageScript source, DpkgData data)
058            throws IOException
059        {
060            _source = source;
061    
062            // perform the encoding in memory. also, do this in the constructor as getEncodedSource()
063            // will be called inside of a Velocity template so let's get all the exception handling done
064            // right away so the caller can handle it.
065            final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
066            OutputStream output = null;
067            try {
068                output = MimeUtility.encode(bytes, BASE64);
069            } catch (final MessagingException e) {
070                throw new IOException("Failed to uuencode script. name=[" + _source.getFriendlyName() + "], reason=[" + e.getMessage() + "].");
071            }
072            IOUtils.write(HEADER, bytes, Dpkg.CHAR_ENCODING);
073            bytes.flush();
074            IOUtils.copy(_source.getSource(data), output);
075            output.flush();
076            IOUtils.write(FOOTER, bytes, Dpkg.CHAR_ENCODING);
077            bytes.flush();
078    
079            output.close();
080            bytes.close();
081            _encoded = bytes.toString(Dpkg.CHAR_ENCODING);
082        }
083    
084        /**
085         * Returns a human readable name for this script.
086         * @see PackageScript#getFriendlyName()
087         */
088        public String getFriendlyName ()
089        {
090            return _source.getFriendlyName();
091        }
092    
093        /**
094         * Returns whether this scripts failure should be reported to the packaging system.
095         * @see PackageScript#failOnError()
096         */
097        public boolean failOnError ()
098        {
099            return _source.failOnError();
100        }
101    
102        /**
103         * Returns the original script source base64 encoded.
104         */
105        public String getEncodedSource ()
106        {
107            return _encoded;
108        }
109    
110        /** The base64 constant as defined in javax.mail. */
111        private static final String BASE64 = "base64";
112    
113        /** The header and footer required by the uuedecode command. */
114        private static final String HEADER = "begin-base64 644 encoder.buf\n";
115        private static final String FOOTER = "\n====";
116    
117        /** The uuencoded script source. */
118        private final String _encoded;
119    
120        /** The script being encoded. */
121        private final PackageScript _source;
122    }