~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to javawebstart/signtask/antsrc/org/netbeans/modules/javawebstart/signtask/SignJarsTask.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SignJarsTask.java
 
3
 *
 
4
 * Created on April 17, 2007, 12:27 PM
 
5
 */
 
6
 
 
7
package org.netbeans.modules.javawebstart.signtask;
 
8
 
 
9
import java.io.File;
 
10
import java.io.IOException;
 
11
import java.io.PrintWriter;
 
12
 
 
13
import java.util.ArrayList;
 
14
import java.util.Enumeration;
 
15
import java.util.HashMap;
 
16
import java.util.HashSet;
 
17
import java.util.Iterator;
 
18
import java.util.LinkedList;
 
19
import java.util.List;
 
20
import java.util.Map;
 
21
import java.util.Map.Entry;
 
22
import java.util.Set;
 
23
 
 
24
import java.util.zip.ZipEntry;
 
25
import java.util.zip.ZipFile;
 
26
 
 
27
import org.apache.tools.ant.BuildException;
 
28
import org.apache.tools.ant.DirectoryScanner;
 
29
import org.apache.tools.ant.Project;
 
30
import org.apache.tools.ant.Task;
 
31
import org.apache.tools.ant.taskdefs.SignJar;
 
32
import org.apache.tools.ant.types.FileSet;
 
33
 
 
34
/**
 
35
 * 
 
36
 * @author Milan Kubec
 
37
 */
 
38
public class SignJarsTask extends Task {
 
39
    
 
40
    private static final String SIG_START = "META-INF/";
 
41
    private static final String SIG_END = ".SF";
 
42
    
 
43
    private int compIndex = 1;
 
44
    
 
45
    private String keystore;
 
46
    public void setKeystore(String s) {
 
47
        keystore = s;
 
48
    }
 
49
    
 
50
    private String storepass;
 
51
    public void setStorepass(String s) {
 
52
        storepass = s;
 
53
    }
 
54
    
 
55
    private String keypass;
 
56
    public void setKeypass(String s) {
 
57
        keypass = s;
 
58
    }
 
59
    
 
60
    private String alias;
 
61
    public void setAlias(String s) {
 
62
        alias = s;
 
63
    }
 
64
    
 
65
    private File mainJar;
 
66
    public void setMainjar(File f) {
 
67
        mainJar = f;
 
68
    }
 
69
    
 
70
    private File destDir;
 
71
    public void setDestdir(File f) {
 
72
        destDir = f;
 
73
    }
 
74
    
 
75
    private String codebase;
 
76
    public void setCodebase(String s) {
 
77
        codebase = s;
 
78
    }
 
79
    
 
80
    private String compProp;
 
81
    public void setComponentsprop(String s) {
 
82
        compProp = s;
 
83
    }
 
84
    
 
85
    private String signedJarsProp;
 
86
    public void setSignedjarsprop(String s) {
 
87
        signedJarsProp = s;
 
88
    }
 
89
    
 
90
    private List<FileSet> filesets = new LinkedList<FileSet>();
 
91
    public void addFileset(FileSet fs) {
 
92
        filesets.add(fs);
 
93
    }
 
94
    
 
95
    public void execute() throws BuildException {
 
96
        
 
97
        Map<Set<String>,List<File>> signersMap = new HashMap(); // Set<signerName> -> List<jarPath>
 
98
        List<File> files2sign = new ArrayList<File>();
 
99
        List<File> alreadySigned = new ArrayList<File>();
 
100
        
 
101
        Iterator it = filesets.iterator();
 
102
        while (it.hasNext()) {
 
103
            FileSet fs = (FileSet) it.next();
 
104
            File dir = fs.getDir(getProject());
 
105
            if (!dir.exists()) {
 
106
                continue;
 
107
            }
 
108
            log("Processing FileSet: " + fs, Project.MSG_VERBOSE);
 
109
            DirectoryScanner ds = fs.getDirectoryScanner(getProject());
 
110
            File basedir = ds.getBasedir();
 
111
            String[] files = ds.getIncludedFiles();
 
112
            for (String f : files) {
 
113
                try {
 
114
                    File fl = new File(basedir, f);
 
115
                    Set<String> sgs = getSignatures(fl);
 
116
                    if (sgs.size() == 0) {
 
117
                        files2sign.add(fl);
 
118
                    } else {
 
119
                        // test if the file is signed with passed alias
 
120
                        if (sgs.size() == 1 && sgs.contains(alias.toUpperCase())) {
 
121
                            alreadySigned.add(fl);
 
122
                        } else {
 
123
                            List lst = signersMap.get(sgs);
 
124
                            if (lst != null) {
 
125
                                lst.add(fl);
 
126
                            } else {
 
127
                                List<File> nlst = new ArrayList<File>();
 
128
                                nlst.add(fl);
 
129
                                signersMap.put(sgs, nlst);
 
130
                            }
 
131
                        }
 
132
                    }
 
133
                } catch (IOException ex) {
 
134
                    throw new BuildException(ex, getLocation());
 
135
                }
 
136
            }
 
137
        }
 
138
        
 
139
        log("Files to be signed: " + mainJar.toString() + ", " + files2sign.toString(), Project.MSG_VERBOSE);
 
140
        
 
141
        // for already signed files generate component jnlp file
 
142
        log("Files already signed by requested alias: " + alreadySigned.toString(), Project.MSG_VERBOSE);
 
143
        
 
144
        StringBuilder signedJarsBuilder = new StringBuilder();
 
145
        SignJar signJar = (SignJar) getProject().createTask("signjar");
 
146
        signJar.setLocation(getLocation());
 
147
        signJar.setKeystore(keystore);
 
148
        signJar.setStorepass(storepass);
 
149
        signJar.setKeypass(keypass);
 
150
        signJar.setAlias(alias);
 
151
        signJar.init();
 
152
        
 
153
        // test main jar if its already signed with passed alias ??
 
154
        log("Signing main jar file: " + mainJar, Project.MSG_VERBOSE);
 
155
        signJar.setJar(mainJar);
 
156
        signJar.execute();
 
157
        
 
158
        if (files2sign.size() > 0) {
 
159
            for (Iterator<File> iter = files2sign.iterator(); iter.hasNext(); ) {
 
160
                File f = iter.next();
 
161
                log("Signing file: " + f, Project.MSG_VERBOSE);
 
162
                signJar.setJar(f);
 
163
                signJar.execute();
 
164
                signedJarsBuilder.append("\n        <jar href=\"lib/" + f.getName() + "\" download=\"eager\"/>"); // XXX lib ?
 
165
            }
 
166
        }
 
167
        
 
168
        if (alreadySigned.size() > 0) {
 
169
            for (Iterator<File> iter = alreadySigned.iterator(); iter.hasNext(); ) {
 
170
                File f = iter.next();
 
171
                log("Adding signed file: " + f, Project.MSG_VERBOSE);
 
172
                signedJarsBuilder.append("\n        <jar href=\"lib/" + f.getName() + "\" download=\"eager\"/>"); // XXX lib ?
 
173
            }
 
174
        }
 
175
        
 
176
        getProject().setProperty(signedJarsProp, signedJarsBuilder.toString());
 
177
        
 
178
        StringBuilder compsBuilder = new StringBuilder();
 
179
        for (Iterator<Entry<Set<String>,List<File>>> iter = signersMap.entrySet().iterator(); iter.hasNext(); ) {
 
180
            Entry<Set<String>,List<File>> entry = iter.next();
 
181
            log("Already signed: keystore aliases = " + entry.getKey() + " -> signed jars = " + entry.getValue(), Project.MSG_VERBOSE);
 
182
            
 
183
            String compName = "jnlpcomponent" + compIndex++;
 
184
            createJNLPComponentFile(entry.getKey(), entry.getValue(), compName);
 
185
            compsBuilder.append("\n        <extension name=\"" + compName + "\" href=\"" + compName + ".jnlp\"/>");
 
186
        }
 
187
        
 
188
        getProject().setProperty(compProp, compsBuilder.toString());
 
189
        
 
190
    }
 
191
    
 
192
    /**
 
193
     * Returns set of signature aliases used to sign this file
 
194
     */
 
195
    private static Set<String> getSignatures(File f) throws IOException {
 
196
        ZipFile jarFile = null;
 
197
        Set<String> signatures = new HashSet<String>(3);
 
198
        try {
 
199
            jarFile = new ZipFile(f);
 
200
            for (Enumeration<ZipEntry> en = (Enumeration<ZipEntry>) jarFile.entries(); en.hasMoreElements(); ) {
 
201
                ZipEntry je = en.nextElement();
 
202
                if (!je.isDirectory() && je.getName().startsWith(SIG_START) && je.getName().endsWith(SIG_END)) {
 
203
                    // there is signature file, get the name
 
204
                    String sigName = je.getName().substring(SIG_START.length(), je.getName().indexOf(SIG_END));
 
205
                    signatures.add(sigName);
 
206
                }
 
207
            }
 
208
        } finally {
 
209
            if (jarFile != null) jarFile.close();
 
210
        }
 
211
        return signatures;
 
212
    }
 
213
    
 
214
    /**
 
215
     * return filename of the JNLP component file ??
 
216
     */
 
217
    private String createJNLPComponentFile(Set<String> aliases, List<File> jars, String compName) {
 
218
        
 
219
        File f = new File(destDir, compName + ".jnlp");
 
220
        PrintWriter writer = null;
 
221
        try {
 
222
            writer = new PrintWriter(f);
 
223
        } catch (IOException ioe) {
 
224
            throw new BuildException(ioe, getLocation());
 
225
        }
 
226
        writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
 
227
        writer.println("<jnlp spec=\"1.0+\" codebase=\"" + codebase + "\">");
 
228
        writer.println("    <information>");
 
229
        writer.println("        <title>" + compName + "</title>");
 
230
        writer.println("        <vendor>" + concatSet(aliases) + "</vendor>");
 
231
        writer.println("    </information>");
 
232
        writer.println("    <security>");
 
233
        writer.println("        <all-permissions/>");
 
234
        writer.println("    </security>");
 
235
        writer.println("    <resources>");
 
236
        for (Iterator<File> iter = jars.iterator(); iter.hasNext(); ) {
 
237
            writer.println("        <jar href=\"" + getPath(destDir.getAbsolutePath(), iter.next().getAbsolutePath()) + "\" download=\"eager\"/>");
 
238
        }
 
239
        writer.println("    </resources>");
 
240
        writer.println("    <component-desc/>");
 
241
        writer.println("</jnlp>");
 
242
        writer.flush();
 
243
        writer.close();
 
244
        
 
245
        return f.getAbsolutePath();
 
246
    
 
247
    }
 
248
    
 
249
    /* Returns the result after subtraction of filePath - dirPath
 
250
     */ 
 
251
    private String getPath(String dirPath, String filePath) {
 
252
        String retVal = null;
 
253
        if (filePath.indexOf(dirPath) != -1) {
 
254
            retVal = (filePath.substring(dirPath.length() + 1).replace('\\', '/'));
 
255
        }
 
256
        return retVal;
 
257
    }
 
258
    
 
259
    /* Returns the concatenation of set items, separated by commas
 
260
     */
 
261
    private String concatSet(Set<String> s) {
 
262
        StringBuilder sb = new StringBuilder();
 
263
        boolean first = true;
 
264
        for (Iterator iter = s.iterator(); iter.hasNext(); ) {
 
265
            if (first) {
 
266
                sb.append(iter.next());
 
267
            } else {
 
268
                sb.append(", " + iter.next());
 
269
            }
 
270
        }
 
271
        return sb.toString();
 
272
    }
 
273
    
 
274
}