~ubuntu-branches/ubuntu/jaunty/ant/jaunty-proposed

« back to all changes in this revision

Viewing changes to src/main/org/apache/tools/ant/taskdefs/optional/Cab.java

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Gybas
  • Date: 2002-02-14 14:28:48 UTC
  • Revision ID: james.westby@ubuntu.com-20020214142848-2ww7ynmqkj31vlmn
Tags: upstream-1.4.1
ImportĀ upstreamĀ versionĀ 1.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The Apache Software License, Version 1.1
 
3
 *
 
4
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 
5
 * reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions
 
9
 * are met:
 
10
 *
 
11
 * 1. Redistributions of source code must retain the above copyright
 
12
 *    notice, this list of conditions and the following disclaimer. 
 
13
 *
 
14
 * 2. Redistributions in binary form must reproduce the above copyright
 
15
 *    notice, this list of conditions and the following disclaimer in
 
16
 *    the documentation and/or other materials provided with the
 
17
 *    distribution.
 
18
 *
 
19
 * 3. The end-user documentation included with the redistribution, if
 
20
 *    any, must include the following acknowlegement:  
 
21
 *       "This product includes software developed by the 
 
22
 *        Apache Software Foundation (http://www.apache.org/)."
 
23
 *    Alternately, this acknowlegement may appear in the software itself,
 
24
 *    if and wherever such third-party acknowlegements normally appear.
 
25
 *
 
26
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 
27
 *    Foundation" must not be used to endorse or promote products derived
 
28
 *    from this software without prior written permission. For written 
 
29
 *    permission, please contact apache@apache.org.
 
30
 *
 
31
 * 5. Products derived from this software may not be called "Apache"
 
32
 *    nor may "Apache" appear in their names without prior written
 
33
 *    permission of the Apache Group.
 
34
 *
 
35
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 
36
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
37
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
38
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 
39
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
40
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
41
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 
42
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
43
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
44
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 
45
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
46
 * SUCH DAMAGE.
 
47
 * ====================================================================
 
48
 *
 
49
 * This software consists of voluntary contributions made by many
 
50
 * individuals on behalf of the Apache Software Foundation.  For more
 
51
 * information on the Apache Software Foundation, please see
 
52
 * <http://www.apache.org/>.
 
53
 */
 
54
 
 
55
package org.apache.tools.ant.taskdefs.optional;
 
56
 
 
57
import org.apache.tools.ant.*;
 
58
import org.apache.tools.ant.taskdefs.*;
 
59
import org.apache.tools.ant.types.*;
 
60
 
 
61
import java.io.*;
 
62
import java.util.Enumeration;
 
63
import java.util.StringTokenizer;
 
64
import java.util.Vector;
 
65
import java.util.Random;
 
66
import java.text.DecimalFormat;
 
67
 
 
68
/**
 
69
 * Create a CAB archive.
 
70
 *
 
71
 * @author Roger Vaughn <a href="mailto:rvaughn@seaconinc.com">rvaughn@seaconinc.com</a>
 
72
 */
 
73
 
 
74
public class Cab extends MatchingTask {
 
75
 
 
76
    private File cabFile;
 
77
    private File baseDir;
 
78
    private Vector filesets = new Vector();
 
79
    private boolean doCompress = true;
 
80
    private boolean doVerbose = false;
 
81
    private String cmdOptions;
 
82
    
 
83
    protected String archiveType = "cab";
 
84
 
 
85
    private static String myos;
 
86
    private static boolean isWindows;
 
87
 
 
88
    static {
 
89
        myos = System.getProperty("os.name");
 
90
        isWindows = myos.toLowerCase().indexOf("windows") >= 0;
 
91
    }
 
92
    
 
93
    /**
 
94
     * This is the name/location of where to 
 
95
     * create the .cab file.
 
96
     */
 
97
    public void setCabfile(File cabFile) {
 
98
        this.cabFile = cabFile;
 
99
    }
 
100
    
 
101
    /**
 
102
     * This is the base directory to look in for 
 
103
     * things to cab.
 
104
     */
 
105
    public void setBasedir(File baseDir) {
 
106
        this.baseDir = baseDir;
 
107
    }
 
108
 
 
109
    /**
 
110
     * Sets whether we want to compress the files or only store them.
 
111
     */
 
112
    public void setCompress(boolean compress) {
 
113
        doCompress = compress;
 
114
    }
 
115
 
 
116
    /**
 
117
     * Sets whether we want to see or suppress cabarc output.
 
118
     */
 
119
    public void setVerbose(boolean verbose) {
 
120
        doVerbose = verbose;
 
121
    }
 
122
 
 
123
    /**
 
124
     * Sets additional cabarc options that aren't supported directly.
 
125
     */
 
126
    public void setOptions(String options) {
 
127
        cmdOptions = options;
 
128
    }
 
129
 
 
130
    /**
 
131
     * Adds a set of files (nested fileset attribute).
 
132
     */
 
133
    public void addFileset(FileSet set) {
 
134
        filesets.addElement(set);
 
135
    }
 
136
 
 
137
    /*
 
138
     * I'm not fond of this pattern: "sub-method expected to throw
 
139
     * task-cancelling exceptions".  It feels too much like programming
 
140
     * for side-effects to me...
 
141
     */
 
142
    protected void checkConfiguration() throws BuildException {
 
143
        if (baseDir == null) {
 
144
            throw new BuildException("basedir attribute must be set!");
 
145
        }
 
146
        if (!baseDir.exists()) {
 
147
            throw new BuildException("basedir does not exist!");
 
148
        }
 
149
        if (cabFile == null) {
 
150
            throw new BuildException("cabfile attribute must be set!");
 
151
        }
 
152
    }
 
153
 
 
154
    /**
 
155
     * Create a new exec delegate.  The delegate task is populated so that
 
156
     * it appears in the logs to be the same task as this one.
 
157
     */
 
158
    protected ExecTask createExec() throws BuildException
 
159
    {
 
160
        ExecTask exec = (ExecTask)project.createTask("exec");
 
161
        exec.setOwningTarget(this.getOwningTarget());
 
162
        exec.setTaskName(this.getTaskName());
 
163
        exec.setDescription(this.getDescription());
 
164
 
 
165
        return exec;
 
166
    }
 
167
 
 
168
    /**
 
169
     * Check to see if the target is up to date with respect to input files.
 
170
     * @return true if the cab file is newer than its dependents.
 
171
     */
 
172
    protected boolean isUpToDate(Vector files)
 
173
    {
 
174
        boolean upToDate = true;
 
175
        for (int i=0; i<files.size() && upToDate; i++)
 
176
        {
 
177
            String file = files.elementAt(i).toString();
 
178
            if (new File(baseDir,file).lastModified() > 
 
179
                cabFile.lastModified())
 
180
                upToDate = false;
 
181
        }
 
182
        return upToDate;
 
183
    }
 
184
 
 
185
    /**
 
186
     * Create the cabarc command line to use.
 
187
     */
 
188
    protected Commandline createCommand(File listFile)
 
189
    {
 
190
        Commandline command = new Commandline();
 
191
        command.setExecutable("cabarc");
 
192
        command.createArgument().setValue("-r");
 
193
        command.createArgument().setValue("-p");
 
194
 
 
195
        if (!doCompress)
 
196
        {
 
197
            command.createArgument().setValue("-m");
 
198
            command.createArgument().setValue("none");
 
199
        }
 
200
 
 
201
        if (cmdOptions != null)
 
202
        {
 
203
            command.createArgument().setLine(cmdOptions);
 
204
        }
 
205
        
 
206
        command.createArgument().setValue("n");
 
207
        command.createArgument().setFile(cabFile);
 
208
        command.createArgument().setValue("@" + listFile.getAbsolutePath());
 
209
 
 
210
        return command;
 
211
    }
 
212
 
 
213
    private static int counter = new Random().nextInt() % 100000;
 
214
    protected File createTempFile(String prefix, String suffix)
 
215
    {
 
216
        if (suffix == null)
 
217
        {
 
218
            suffix = ".tmp";
 
219
        }
 
220
 
 
221
        String name = prefix +
 
222
            new DecimalFormat("#####").format(new Integer(counter++)) +
 
223
            suffix;
 
224
 
 
225
        String tmpdir = System.getProperty("java.io.tmpdir");
 
226
 
 
227
        // java.io.tmpdir is not present in 1.1
 
228
        if (tmpdir == null)
 
229
            return new File(name);
 
230
        else
 
231
            return new File(tmpdir, name);
 
232
    }
 
233
 
 
234
    /**
 
235
     * Creates a list file.  This temporary file contains a list of all files
 
236
     * to be included in the cab, one file per line.
 
237
     */
 
238
    protected File createListFile(Vector files)
 
239
        throws IOException
 
240
    {
 
241
        File listFile = createTempFile("ant", null);
 
242
        
 
243
        PrintWriter writer = new PrintWriter(new FileOutputStream(listFile));
 
244
 
 
245
        for (int i = 0; i < files.size(); i++)
 
246
        {
 
247
            writer.println(files.elementAt(i).toString());
 
248
        }
 
249
        writer.close();
 
250
 
 
251
        return listFile;
 
252
    }
 
253
 
 
254
    /**
 
255
     * Append all files found by a directory scanner to a vector.
 
256
     */
 
257
    protected void appendFiles(Vector files, DirectoryScanner ds)
 
258
    {
 
259
        String[] dsfiles = ds.getIncludedFiles();
 
260
 
 
261
        for (int i = 0; i < dsfiles.length; i++)
 
262
        {
 
263
            files.addElement(dsfiles[i]);
 
264
        }
 
265
    }
 
266
 
 
267
    /**
 
268
     * Get the complete list of files to be included in the cab.  Filenames
 
269
     * are gathered from filesets if any have been added, otherwise from the
 
270
     * traditional include parameters.
 
271
     */
 
272
    protected Vector getFileList() throws BuildException
 
273
    {
 
274
        Vector files = new Vector();
 
275
 
 
276
        if (filesets.size() == 0)
 
277
        {
 
278
            // get files from old methods - includes and nested include
 
279
            appendFiles(files, super.getDirectoryScanner(baseDir));
 
280
        }
 
281
        else
 
282
        {
 
283
            // get files from filesets
 
284
            for (int i = 0; i < filesets.size(); i++)
 
285
            {
 
286
                FileSet fs = (FileSet) filesets.elementAt(i);
 
287
                if (fs != null)
 
288
                {
 
289
                    appendFiles(files, fs.getDirectoryScanner(project));
 
290
                }
 
291
            }
 
292
        }
 
293
 
 
294
        return files;
 
295
    }
 
296
 
 
297
    public void execute() throws BuildException {
 
298
 
 
299
        checkConfiguration();
 
300
 
 
301
        Vector files = getFileList();
 
302
    
 
303
        // quick exit if the target is up to date
 
304
        if (isUpToDate(files)) return;
 
305
 
 
306
        log("Building "+ archiveType +": "+ cabFile.getAbsolutePath());
 
307
 
 
308
        // we must be on Windows to continue
 
309
        if (!isWindows) {
 
310
            log("Using listcab/libcabinet", Project.MSG_VERBOSE);
 
311
            
 
312
            StringBuffer sb = new StringBuffer();
 
313
            
 
314
            Enumeration fileEnum = files.elements();
 
315
            
 
316
            while (fileEnum.hasMoreElements()) {
 
317
                sb.append(fileEnum.nextElement()).append("\n");
 
318
            }
 
319
            sb.append("\n").append(cabFile.getAbsolutePath()).append("\n");
 
320
            
 
321
            try {
 
322
                Process p = Runtime.getRuntime().exec("listcab");
 
323
                OutputStream out = p.getOutputStream();
 
324
                out.write(sb.toString().getBytes());
 
325
                out.flush();
 
326
                out.close();
 
327
            } catch (IOException ex) {
 
328
                String msg = "Problem creating " + cabFile + " " + ex.getMessage();
 
329
                throw new BuildException(msg);
 
330
            }
 
331
        } else {
 
332
            try {
 
333
                File listFile = createListFile(files);
 
334
                ExecTask exec = createExec();
 
335
                File outFile = null;
 
336
                
 
337
                // die if cabarc fails
 
338
                exec.setFailonerror(true);
 
339
                exec.setDir(baseDir);
 
340
                
 
341
                if (!doVerbose) {
 
342
                    outFile = createTempFile("ant", null);
 
343
                    exec.setOutput(outFile);
 
344
                }
 
345
                    
 
346
                exec.setCommand(createCommand(listFile));
 
347
                exec.execute();
 
348
    
 
349
                if (outFile != null) {
 
350
                    outFile.delete();
 
351
                }
 
352
                
 
353
                listFile.delete();
 
354
            } catch (IOException ioe) {
 
355
                String msg = "Problem creating " + cabFile + " " + ioe.getMessage();
 
356
                throw new BuildException(msg);
 
357
            }
 
358
        }
 
359
    }
 
360
}