001/*
002 * $Id: IzPackTask.java,v 1.18 2005/08/26 06:48:50 bartzkau Exp $
003 * IzPack - Copyright 2001-2005 Julien Ponge, All Rights Reserved.
004 * 
005 * http://www.izforge.com/izpack/
006 * http://developer.berlios.de/projects/izpack/
007 * 
008 * Copyright 2002 Paul Wilkinson
009 * 
010 * Licensed under the Apache License, Version 2.0 (the "License");
011 * you may not use this file except in compliance with the License.
012 * You may obtain a copy of the License at
013 * 
014 *     http://www.apache.org/licenses/LICENSE-2.0
015 *     
016 * Unless required by applicable law or agreed to in writing, software
017 * distributed under the License is distributed on an "AS IS" BASIS,
018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019 * See the License for the specific language governing permissions and
020 * limitations under the License.
021 */
022
023package com.izforge.izpack.ant;
024
025import java.util.Enumeration;
026import java.util.Hashtable;
027import java.util.Properties;
028import java.util.ResourceBundle;
029
030import org.apache.tools.ant.BuildException;
031import org.apache.tools.ant.Project;
032import org.apache.tools.ant.Task;
033import org.apache.tools.ant.types.EnumeratedAttribute;
034import org.apache.tools.ant.types.PropertySet;
035
036import com.izforge.izpack.compiler.CompilerConfig;
037import com.izforge.izpack.compiler.CompilerException;
038import com.izforge.izpack.compiler.PackagerListener;
039
040/**
041 * A IzPack Ant task.
042 * 
043 * @author Paul Wilkinson
044 */
045public class IzPackTask extends Task implements PackagerListener
046{
047    /** The embedded installation configuration */
048    private ConfigHolder config;
049
050    /** Holds value of property input. */
051    private String input;
052
053    /** Holds value of property basedir. */
054    private String basedir;
055
056    /** Holds value of property output. */
057    private String output;
058
059    /** Holds value of property compression. */
060    private String compression;
061
062    /** Holds value of property compression. */
063    private int compressionLevel;
064
065    /** Holds value of property installerType. */
066    private InstallerType installerType;
067
068    /**
069     * Holds value of property izPackDir. This should point at the IzPack directory
070     */
071    private String izPackDir;
072
073    /** Holds properties used to make substitutions in the install file */
074    private Properties properties;
075
076    /** should we inherit properties from the Ant file? */
077    private boolean inheritAll = false;
078
079    /** Creates new IZPackTask */
080    public IzPackTask()
081    {
082        basedir = null;
083        config = null;
084        input = null;
085        output = null;
086        installerType = null;
087        izPackDir = null;
088        compression = "default";
089        compressionLevel = -1;
090    }
091
092    /**
093     * Called by ant to create the object for the config nested element.
094     * @return a holder object for the config nested element.
095     */
096    public ConfigHolder createConfig()
097    {
098        config = new ConfigHolder(getProject());
099        return config;
100    }
101
102    /**
103     * Logs a message to the Ant log at default priority (MSG_INFO).
104     * 
105     * @param str The message to log.
106     */
107    public void packagerMsg(String str)
108    {
109        packagerMsg(str, MSG_INFO);
110    }
111
112    /**
113     * Logs a message to the Ant log at the specified priority.
114     * 
115     * @param str The message to log.
116     * @param priority The priority of the message.
117     */
118    public void packagerMsg(String str, int priority)
119    {
120        final int antPriority;
121        switch (priority)
122        // No guarantee of a direct conversion. It's an enum
123        {
124        case MSG_DEBUG:
125            antPriority = Project.MSG_DEBUG;
126            break;
127        case MSG_ERR:
128            antPriority = Project.MSG_ERR;
129            break;
130        case MSG_INFO:
131            antPriority = Project.MSG_INFO;
132            break;
133        case MSG_VERBOSE:
134            antPriority = Project.MSG_VERBOSE;
135            break;
136        case MSG_WARN:
137            antPriority = Project.MSG_WARN;
138            break;
139        default: // rather than die...
140            antPriority = Project.MSG_INFO;
141        }
142        log(str, antPriority);
143    }
144
145    /** Called when the packaging starts. */
146    public void packagerStart()
147    {
148        log(ResourceBundle.getBundle("com/izforge/izpack/ant/langpacks/messages").getString(
149                "Packager_starting"), Project.MSG_DEBUG);
150    }
151
152    /** Called when the packaging stops. */
153    public void packagerStop()
154    {
155        log(ResourceBundle.getBundle("com/izforge/izpack/ant/langpacks/messages").getString(
156                "Packager_ended"), Project.MSG_DEBUG);
157    }
158
159    /**
160     * Packages.
161     * 
162     * @exception BuildException Description of the Exception
163     */
164    public void execute() throws org.apache.tools.ant.BuildException
165    {
166        // Either the input attribute or config element must be specified
167        if (input == null && config == null)
168            throw new BuildException(ResourceBundle.getBundle(
169                    "com/izforge/izpack/ant/langpacks/messages").getString(
170                    "input_must_be_specified"));
171
172        if (output == null)
173            throw new BuildException(ResourceBundle.getBundle(
174                    "com/izforge/izpack/ant/langpacks/messages").getString(
175                    "output_must_be_specified"));
176
177        // if (installerType == null) now optional
178
179        if (basedir == null)
180            throw new BuildException(ResourceBundle.getBundle(
181                    "com/izforge/izpack/ant/langpacks/messages").getString(
182                    "basedir_must_be_specified"));
183
184        // if (izPackDir == null)
185        // throw new
186        // BuildException(java.util.ResourceBundle.getBundle("com/izforge/izpack/ant/langpacks/messages").getString("izPackDir_must_be_specified"));
187
188        String kind = (installerType == null ? null : installerType.getValue());
189
190        CompilerConfig c = null;
191        String configText = null;
192        if(config != null )
193        {// Pass in the embedded configuration
194            configText = config.getText();
195            input = null;
196        }
197        try
198        {
199            // else use external configuration referenced by the input attribute
200            c = new CompilerConfig(input, basedir, kind, output, 
201                    compression, compressionLevel, this, configText);
202        }
203        catch (CompilerException e1)
204        {
205            throw new BuildException(e1);
206        }
207        CompilerConfig.setIzpackHome(izPackDir);
208
209        if (properties != null)
210        {
211            Enumeration e = properties.keys();
212            while (e.hasMoreElements())
213            {
214                String name = (String) e.nextElement();
215                String value = properties.getProperty(name);
216                c.addProperty(name, value);
217            }
218        }
219
220        if (inheritAll == true)
221        {
222            Hashtable projectProps = getProject().getProperties();
223            Enumeration e = projectProps.keys();
224            while (e.hasMoreElements())
225            {
226                String name = (String) e.nextElement();
227                String value = (String) projectProps.get(name);
228                c.addProperty(name, value);
229            }            
230        }
231
232        try
233        {
234            c.executeCompiler();
235        }
236        catch (Exception e)
237        {
238            throw new BuildException(e);// Throw an exception if compilation
239            // failed
240        }
241    }
242
243    /**
244     * Setter for property input.
245     * 
246     * @param input New value of property input.
247     */
248    public void setInput(String input)
249    {
250        this.input = input;
251    }
252
253    /**
254     * Setter for property basedir.
255     * 
256     * @param basedir New value of property basedir.
257     */
258    public void setBasedir(String basedir)
259    {
260        this.basedir = basedir;
261    }
262
263    /**
264     * Setter for property output.
265     * 
266     * @param output New value of property output.
267     */
268    public void setOutput(String output)
269    {
270        this.output = output;
271    }
272
273    /**
274     * Setter for property installerType.
275     * 
276     * @param installerType New value of property installerType.
277     */
278    public void setInstallerType(InstallerType installerType)
279    {
280        this.installerType = installerType;
281    }
282
283    /**
284     * Setter for property izPackDir.
285     * 
286     * @param izPackDir New value of property izPackDir.
287     */
288    public void setIzPackDir(String izPackDir)
289    {
290        if (!(izPackDir.endsWith("/"))) izPackDir += "/";
291        this.izPackDir = izPackDir;
292    }
293
294    /**
295     * If true, pass all Ant properties to IzPack. Defaults to false;
296     */
297    public void setInheritAll(boolean value)
298    {
299        inheritAll = value;
300    }
301
302    /**
303     * Setter for property compression.
304     * @param compression The type compression to set for pack compression.
305     */
306    public void setCompression(String compression)
307    {
308        this.compression = compression;
309    }
310
311    /**
312     * @param compressionLevel The compressionLevel to set.
313     */
314    public void setCompressionLevel(int compressionLevel)
315    {
316        this.compressionLevel = compressionLevel;
317    }
318
319    /**
320     * Ant will call this for each <property> tag to the IzPack task.
321     */
322    public void addConfiguredProperty(Property property)
323    {
324        if (properties == null) properties = new Properties();
325
326        property.execute(); // don't call perform(), so no build events triggered
327
328        Properties props = property.getProperties();
329        Enumeration e = props.keys();
330        while (e.hasMoreElements())
331        {
332            String name = (String) e.nextElement();
333            String value = props.getProperty(name);
334            log("Adding property: " + property.getClass() + name+"=" + value,
335                Project.MSG_VERBOSE);
336
337            properties.setProperty(name, value);
338        }
339    }
340
341    /**
342     * A set of properties to pass from the build environment to the install compile
343     *
344     * @param ps The propertyset collection of properties
345     */
346    public void addConfiguredPropertyset(PropertySet ps)
347    {
348        if (properties == null) properties = new Properties();
349
350        properties.putAll(ps.getProperties());
351    }
352
353    /**
354     * Enumerated attribute with the values "asis", "add" and "remove".
355     * 
356     * @author Paul Wilkinson
357     */
358    public static class InstallerType extends EnumeratedAttribute
359    {
360
361        public String[] getValues()
362        {
363            return new String[] { CompilerConfig.STANDARD, CompilerConfig.WEB};
364        }
365    }
366}