Source Code Cross Referenced for SignJar.java in  » Build » ANT » org » apache » tools » ant » taskdefs » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Build » ANT » org.apache.tools.ant.taskdefs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         *
017:         */
018:
019:        package org.apache.tools.ant.taskdefs;
020:
021:        import java.io.File;
022:        import java.io.IOException;
023:        import java.util.Iterator;
024:
025:        import org.apache.tools.ant.BuildException;
026:        import org.apache.tools.ant.Project;
027:        import org.apache.tools.ant.taskdefs.condition.IsSigned;
028:        import org.apache.tools.ant.types.Path;
029:        import org.apache.tools.ant.types.resources.FileResource;
030:        import org.apache.tools.ant.util.FileUtils;
031:        import org.apache.tools.ant.util.IdentityMapper;
032:        import org.apache.tools.ant.util.FileNameMapper;
033:
034:        /**
035:         * Signs JAR or ZIP files with the javasign command line tool. The tool detailed
036:         * dependency checking: files are only signed if they are not signed. The
037:         * <tt>signjar</tt> attribute can point to the file to generate; if this file
038:         * exists then its modification date is used as a cue as to whether to resign
039:         * any JAR file.
040:         *
041:         * Timestamp driven signing is based on the unstable and inadequately documented
042:         * information in the Java1.5 docs
043:         * @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/time-of-signing-beta1.html">
044:         * beta documentation</a>
045:         * @ant.task category="java"
046:         * @since Ant 1.1
047:         */
048:        public class SignJar extends AbstractJarSignerTask {
049:            // CheckStyle:VisibilityModifier OFF - bc
050:
051:            private static final FileUtils FILE_UTILS = FileUtils
052:                    .getFileUtils();
053:
054:            /**
055:             * name to a signature file
056:             */
057:            protected String sigfile;
058:
059:            /**
060:             * name of a single jar
061:             */
062:            protected File signedjar;
063:
064:            /**
065:             * flag for internal sf signing
066:             */
067:            protected boolean internalsf;
068:
069:            /**
070:             * sign sections only?
071:             */
072:            protected boolean sectionsonly;
073:
074:            /**
075:             * flag to preserve timestamp on modified files
076:             */
077:            private boolean preserveLastModified;
078:
079:            /**
080:             * Whether to assume a jar which has an appropriate .SF file in is already
081:             * signed.
082:             */
083:            protected boolean lazy;
084:
085:            /**
086:             * the output directory when using paths.
087:             */
088:            protected File destDir;
089:
090:            /**
091:             * mapper for todir work
092:             */
093:            private FileNameMapper mapper;
094:
095:            /**
096:             * URL for a tsa; null implies no tsa support
097:             */
098:            protected String tsaurl;
099:
100:            /**
101:             * alias for the TSA in the keystore
102:             */
103:            protected String tsacert;
104:
105:            /**
106:             * error string for unit test verification: {@value}
107:             */
108:            public static final String ERROR_TODIR_AND_SIGNEDJAR = "'destdir' and 'signedjar' cannot both be set";
109:            /**
110:             * error string for unit test verification: {@value}
111:             */
112:            public static final String ERROR_TOO_MANY_MAPPERS = "Too many mappers";
113:            /**
114:             * error string for unit test verification {@value}
115:             */
116:            public static final String ERROR_SIGNEDJAR_AND_PATHS = "You cannot specify the signed JAR when using paths or filesets";
117:            /**
118:             * error string for unit test verification: {@value}
119:             */
120:            public static final String ERROR_BAD_MAP = "Cannot map source file to anything sensible: ";
121:            /**
122:             * error string for unit test verification: {@value}
123:             */
124:            public static final String ERROR_MAPPER_WITHOUT_DEST = "The destDir attribute is required if a mapper is set";
125:            /**
126:             * error string for unit test verification: {@value}
127:             */
128:            public static final String ERROR_NO_ALIAS = "alias attribute must be set";
129:            /**
130:             * error string for unit test verification: {@value}
131:             */
132:            public static final String ERROR_NO_STOREPASS = "storepass attribute must be set";
133:
134:            // CheckStyle:VisibilityModifier ON
135:
136:            /**
137:             * name of .SF/.DSA file; optional
138:             *
139:             * @param sigfile the name of the .SF/.DSA file
140:             */
141:            public void setSigfile(final String sigfile) {
142:                this .sigfile = sigfile;
143:            }
144:
145:            /**
146:             * name of signed JAR file; optional
147:             *
148:             * @param signedjar the name of the signed jar file
149:             */
150:            public void setSignedjar(final File signedjar) {
151:                this .signedjar = signedjar;
152:            }
153:
154:            /**
155:             * Flag to include the .SF file inside the signature; optional; default
156:             * false
157:             *
158:             * @param internalsf if true include the .SF file inside the signature
159:             */
160:            public void setInternalsf(final boolean internalsf) {
161:                this .internalsf = internalsf;
162:            }
163:
164:            /**
165:             * flag to compute hash of entire manifest; optional, default false
166:             *
167:             * @param sectionsonly flag to compute hash of entire manifest
168:             */
169:            public void setSectionsonly(final boolean sectionsonly) {
170:                this .sectionsonly = sectionsonly;
171:            }
172:
173:            /**
174:             * flag to control whether the presence of a signature file means a JAR is
175:             * signed; optional, default false
176:             *
177:             * @param lazy flag to control whether the presence of a signature
178:             */
179:            public void setLazy(final boolean lazy) {
180:                this .lazy = lazy;
181:            }
182:
183:            /**
184:             * Optionally sets the output directory to be used.
185:             *
186:             * @param destDir the directory in which to place signed jars
187:             * @since Ant 1.7
188:             */
189:            public void setDestDir(File destDir) {
190:                this .destDir = destDir;
191:            }
192:
193:            /**
194:             * add a mapper to determine file naming policy. Only used with toDir
195:             * processing.
196:             *
197:             * @param newMapper the mapper to add.
198:             * @since Ant 1.7
199:             */
200:            public void add(FileNameMapper newMapper) {
201:                if (mapper != null) {
202:                    throw new BuildException(ERROR_TOO_MANY_MAPPERS);
203:                }
204:                mapper = newMapper;
205:            }
206:
207:            /**
208:             * get the active mapper; may be null
209:             * @return mapper or null
210:             * @since Ant 1.7
211:             */
212:            public FileNameMapper getMapper() {
213:                return mapper;
214:            }
215:
216:            /**
217:             * get the -tsaurl url
218:             * @return url or null
219:             * @since Ant 1.7
220:             */
221:            public String getTsaurl() {
222:                return tsaurl;
223:            }
224:
225:            /**
226:             *
227:             * @param tsaurl the tsa url.
228:             * @since Ant 1.7
229:             */
230:            public void setTsaurl(String tsaurl) {
231:                this .tsaurl = tsaurl;
232:            }
233:
234:            /**
235:             * get the -tsacert option
236:             * @since Ant 1.7
237:             * @return a certificate alias or null
238:             */
239:            public String getTsacert() {
240:                return tsacert;
241:            }
242:
243:            /**
244:             * set the alias in the keystore of the TSA to use;
245:             * @param tsacert the cert alias.
246:             */
247:            public void setTsacert(String tsacert) {
248:                this .tsacert = tsacert;
249:            }
250:
251:            /**
252:             * sign the jar(s)
253:             *
254:             * @throws BuildException on errors
255:             */
256:            public void execute() throws BuildException {
257:                //validation logic
258:                final boolean hasJar = jar != null;
259:                final boolean hasSignedJar = signedjar != null;
260:                final boolean hasDestDir = destDir != null;
261:                final boolean hasMapper = mapper != null;
262:
263:                if (!hasJar && !hasResources()) {
264:                    throw new BuildException(ERROR_NO_SOURCE);
265:                }
266:                if (null == alias) {
267:                    throw new BuildException(ERROR_NO_ALIAS);
268:                }
269:
270:                if (null == storepass) {
271:                    throw new BuildException(ERROR_NO_STOREPASS);
272:                }
273:
274:                if (hasDestDir && hasSignedJar) {
275:                    throw new BuildException(ERROR_TODIR_AND_SIGNEDJAR);
276:                }
277:
278:                if (hasResources() && hasSignedJar) {
279:                    throw new BuildException(ERROR_SIGNEDJAR_AND_PATHS);
280:                }
281:
282:                //this isnt strictly needed, but by being fussy now,
283:                //we can change implementation details later
284:                if (!hasDestDir && hasMapper) {
285:                    throw new BuildException(ERROR_MAPPER_WITHOUT_DEST);
286:                }
287:
288:                beginExecution();
289:
290:                try {
291:                    //special case single jar handling with signedjar attribute set
292:                    if (hasJar && hasSignedJar) {
293:                        // single jar processing
294:                        signOneJar(jar, signedjar);
295:                        //return here.
296:                        return;
297:                    }
298:
299:                    //the rest of the method treats single jar like
300:                    //a nested path with one file
301:
302:                    Path sources = createUnifiedSourcePath();
303:                    //set up our mapping policy
304:                    FileNameMapper destMapper;
305:                    if (hasMapper) {
306:                        destMapper = mapper;
307:                    } else {
308:                        //no mapper? use the identity policy
309:                        destMapper = new IdentityMapper();
310:                    }
311:
312:                    //at this point the paths are set up with lists of files,
313:                    //and the mapper is ready to map from source dirs to dest files
314:                    //now we iterate through every JAR giving source and dest names
315:                    // deal with the paths
316:                    Iterator iter = sources.iterator();
317:                    while (iter.hasNext()) {
318:                        FileResource fr = (FileResource) iter.next();
319:
320:                        //calculate our destination directory; it is either the destDir
321:                        //attribute, or the base dir of the fileset (for in situ updates)
322:                        File toDir = hasDestDir ? destDir : fr.getBaseDir();
323:
324:                        //determine the destination filename via the mapper
325:                        String[] destFilenames = destMapper.mapFileName(fr
326:                                .getName());
327:                        if (destFilenames == null || destFilenames.length != 1) {
328:                            //we only like simple mappers.
329:                            throw new BuildException(ERROR_BAD_MAP
330:                                    + fr.getFile());
331:                        }
332:                        File destFile = new File(toDir, destFilenames[0]);
333:                        signOneJar(fr.getFile(), destFile);
334:                    }
335:                } finally {
336:                    endExecution();
337:                }
338:            }
339:
340:            /**
341:             * Sign one jar.
342:             * <p/>
343:             * The signing only takes place if {@link #isUpToDate(File, File)} indicates
344:             * that it is needed.
345:             *
346:             * @param jarSource source to sign
347:             * @param jarTarget target; may be null
348:             * @throws BuildException
349:             */
350:            private void signOneJar(File jarSource, File jarTarget)
351:                    throws BuildException {
352:
353:                File targetFile = jarTarget;
354:                if (targetFile == null) {
355:                    targetFile = jarSource;
356:                }
357:                if (isUpToDate(jarSource, targetFile)) {
358:                    return;
359:                }
360:
361:                long lastModified = jarSource.lastModified();
362:                final ExecTask cmd = createJarSigner();
363:
364:                setCommonOptions(cmd);
365:
366:                bindToKeystore(cmd);
367:                if (null != sigfile) {
368:                    addValue(cmd, "-sigfile");
369:                    String value = this .sigfile;
370:                    addValue(cmd, value);
371:                }
372:
373:                //DO NOT SET THE -signedjar OPTION if source==dest
374:                //unless you like fielding hotspot crash reports
375:                if (null != targetFile && !jarSource.equals(targetFile)) {
376:                    addValue(cmd, "-signedjar");
377:                    addValue(cmd, targetFile.getPath());
378:                }
379:
380:                if (internalsf) {
381:                    addValue(cmd, "-internalsf");
382:                }
383:
384:                if (sectionsonly) {
385:                    addValue(cmd, "-sectionsonly");
386:                }
387:
388:                //add -tsa operations if declared
389:                addTimestampAuthorityCommands(cmd);
390:
391:                //JAR source is required
392:                addValue(cmd, jarSource.getPath());
393:
394:                //alias is required for signing
395:                addValue(cmd, alias);
396:
397:                log("Signing JAR: " + jarSource.getAbsolutePath() + " to "
398:                        + targetFile.getAbsolutePath() + " as " + alias);
399:
400:                cmd.execute();
401:
402:                // restore the lastModified attribute
403:                if (preserveLastModified) {
404:                    targetFile.setLastModified(lastModified);
405:                }
406:            }
407:
408:            /**
409:             * If the tsa parameters are set, this passes them to the command.
410:             * There is no validation of java version, as third party JDKs
411:             * may implement this on earlier/later jarsigner implementations.
412:             * @param cmd the exec task.
413:             */
414:            private void addTimestampAuthorityCommands(final ExecTask cmd) {
415:                if (tsaurl != null) {
416:                    addValue(cmd, "-tsa");
417:                    addValue(cmd, tsaurl);
418:                }
419:                if (tsacert != null) {
420:                    addValue(cmd, "-tsacert");
421:                    addValue(cmd, tsacert);
422:                }
423:            }
424:
425:            /**
426:             * Compare a jar file with its corresponding signed jar. The logic for this
427:             * is complex, and best explained in the source itself. Essentially if
428:             * either file doesnt exist, or the destfile has an out of date timestamp,
429:             * then the return value is false.
430:             * <p/>
431:             * If we are signing ourself, the check {@link #isSigned(File)} is used to
432:             * trigger the process.
433:             *
434:             * @param jarFile       the unsigned jar file
435:             * @param signedjarFile the result signed jar file
436:             * @return true if the signedjarFile is considered up to date
437:             */
438:            protected boolean isUpToDate(File jarFile, File signedjarFile) {
439:                if (null == jarFile || !jarFile.exists()) {
440:                    //these are pathological cases, but retained in case somebody
441:                    //subclassed us.
442:                    return false;
443:                }
444:
445:                //we normally compare destination with source
446:                File destFile = signedjarFile;
447:                if (destFile == null) {
448:                    //but if no dest is specified, compare source to source
449:                    destFile = jarFile;
450:                }
451:
452:                //if, by any means, the destfile and source match,
453:                if (jarFile.equals(destFile)) {
454:                    if (lazy) {
455:                        //we check the presence of signatures on lazy signing
456:                        return isSigned(jarFile);
457:                    }
458:                    //unsigned or non-lazy self signings are always false
459:                    return false;
460:                }
461:
462:                //if they are different, the timestamps are used
463:                return FILE_UTILS.isUpToDate(jarFile, destFile);
464:            }
465:
466:            /**
467:             * test for a file being signed, by looking for a signature in the META-INF
468:             * directory with our alias.
469:             *
470:             * @param file the file to be checked
471:             * @return true if the file is signed
472:             * @see IsSigned#isSigned(File, String)
473:             */
474:            protected boolean isSigned(File file) {
475:                try {
476:                    return IsSigned.isSigned(file, alias);
477:                } catch (IOException e) {
478:                    //just log this
479:                    log(e.toString(), Project.MSG_VERBOSE);
480:                    return false;
481:                }
482:            }
483:
484:            /**
485:             * true to indicate that the signed jar modification date remains the same
486:             * as the original. Defaults to false
487:             *
488:             * @param preserveLastModified if true preserve the last modified time
489:             */
490:            public void setPreserveLastModified(boolean preserveLastModified) {
491:                this.preserveLastModified = preserveLastModified;
492:            }
493:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.