Source Code Cross Referenced for JarBundler.java in  » Swing-Library » jEdit » net » sourceforge » jarbundler » 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 » Swing Library » jEdit » net.sourceforge.jarbundler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * A Mac OS X Jar Bundler Ant Task.
0003:         *
0004:         * Copyright (c) 2003, Seth J. Morabito <sethm@loomcom.com> All rights reserved.
0005:         *
0006:         * This program is free software; you can redistribute it and/or modify it
0007:         * under the terms of the GNU General Public License as published by the Free
0008:         * Software Foundation; either version 2 of the License, or (at your option)
0009:         * any later version.
0010:         *
0011:         * This program is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See  the GNU General Public License for
0014:         * more details.
0015:         *
0016:         * You should have received a copy of the GNU General Public License along with
0017:         * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
0018:         * Place - Suite 330, Boston, MA  02111-1307, USA.
0019:         */
0020:
0021:        package net.sourceforge.jarbundler;
0022:
0023:        // This package's imports
0024:        import net.sourceforge.jarbundler.AppBundleProperties;
0025:        import net.sourceforge.jarbundler.DocumentType;
0026:        import net.sourceforge.jarbundler.JavaProperty;
0027:        import net.sourceforge.jarbundler.PropertyListWriter;
0028:
0029:        // Java I/O
0030:        import java.io.BufferedWriter;
0031:        import java.io.BufferedReader;
0032:        import java.io.File;
0033:        import java.io.FileWriter;
0034:        import java.io.FileReader;
0035:        import java.io.IOException;
0036:        import java.io.InputStream;
0037:        import java.io.PrintWriter;
0038:
0039:        // Java Utility
0040:        import java.util.ArrayList;
0041:        import java.util.HashSet;
0042:        import java.util.Iterator;
0043:        import java.util.List;
0044:        import java.util.Set;
0045:
0046:        // Apache Jakarta
0047:        import org.apache.tools.ant.BuildException;
0048:        import org.apache.tools.ant.FileScanner;
0049:        import org.apache.tools.ant.Project;
0050:        import org.apache.tools.ant.Task;
0051:
0052:        import org.apache.tools.ant.types.FileList;
0053:        import org.apache.tools.ant.types.FileSet;
0054:        import org.apache.tools.ant.types.PatternSet;
0055:
0056:        import org.apache.tools.ant.taskdefs.MatchingTask;
0057:        import org.apache.tools.ant.taskdefs.Chmod;
0058:        import org.apache.tools.ant.taskdefs.Delete;
0059:
0060:        import org.apache.tools.ant.util.FileUtils;
0061:
0062:        // Java language imports
0063:        import java.lang.Boolean;
0064:        import java.lang.Process;
0065:        import java.lang.Runtime;
0066:        import java.lang.String;
0067:        import java.lang.System;
0068:
0069:        /**
0070:         * <p>
0071:         * An ant task which creates a Mac OS X Application Bundle for a Java
0072:         * application.
0073:         * </p>
0074:         * 
0075:         * <dl>
0076:         * <dt>dir</dt>
0077:         * <dd>The directory into which to put the new application bundle.</dd>
0078:         * <dt>name</dt>
0079:         * <dd>The name of the application bundle. Note that the maximum length of this
0080:         * name is 16 characters, and it will be silently cropped if it is longer than
0081:         * this.</dd>
0082:         * <dt>mainclass</dt>
0083:         * <dd>The main Java class to call when running the application.</dd>
0084:         * </dl>
0085:         * 
0086:         * <p>
0087:         * One of the following three MUST be used:
0088:         * 
0089:         * <ol>
0090:         * <li>jars Space or comma-separated list of JAR files to include.; OR</li>
0091:         * <li>One or more nested &lt;jarfileset&gt;s. These are normal ANT FileSets;
0092:         * OR </li>
0093:         * <li>One or more nested &lt;jarfilelist&gt;s. These are standard ANT
0094:         * FileLists. </li>
0095:         * </ol>
0096:         * 
0097:         * <p>
0098:         * Optional attributes:
0099:         * 
0100:         * <p>
0101:         * The following attributes are not required, but you can use them to override
0102:         * default behavior.
0103:         * 
0104:         * <dl>
0105:         * <dt>verbose
0106:         * <dd>If true, show more verbose output while running the task
0107:         * 
0108:         * <dt>version
0109:         * <dd>Version information about your application (e.g., "1.0")
0110:         * 
0111:         * <dt>infostring
0112:         * <dd>String to show in the "Get Info" dialog
0113:         * </dl>
0114:         * 
0115:         * These attributes control the fine-tuning of the "Mac OS X" look and feel.
0116:         * 
0117:         * <dl>
0118:         * <dt>arguments
0119:         * <dd>Command line arguments. (no default)
0120:         * 
0121:         * <dt>smalltabs
0122:         * <dd>Use small tabs. (default "false") Deprecated under JVM 1.4.1
0123:         * 
0124:         * <dt>antialiasedgraphics
0125:         * <dd>Use anti-aliased graphics (default "false")
0126:         * 
0127:         * <dt>antialiasedtext
0128:         * <dd>Use anti-aliased text (default "false")
0129:         * 
0130:         * <dt>bundleid
0131:         * <dd>Unique identifier for this bundle, in the form of a Java package. No
0132:         * default.
0133:         * 
0134:         * <dt>buildnumber
0135:         * <dd>Unique identifier for this build
0136:         * 
0137:         * <dt>developmentregion
0138:         * <dd>Development Region. Default "English".
0139:         * 
0140:         * <dt>execs
0141:         * <dd>Files to be copied into "Resources/MacOS" and made executable
0142:         * 
0143:         * <dt>liveresize
0144:         * <dd>Use "Live resizing" (default "false") Deprecated under JVM 1.4.1
0145:         * 
0146:         * 
0147:         * <dt>growbox
0148:         * <dd>Show growbox (default "true")
0149:         * 
0150:         * <dt>growboxintrudes
0151:         * <dd>Intruding growbox (default "false") Deprecated under JVM 1.4.1
0152:         * 
0153:         * <dt>screenmenu
0154:         * <dd>Put swing menu into Mac OS X menu bar.
0155:         * 
0156:         * <dt>type
0157:         * <dd>Bundle type (default "APPL")
0158:         * 
0159:         * <dt>signature
0160:         * <dd>Bundle Signature (default "????")
0161:         * 
0162:         * <dt>stubfile
0163:         * <dd>The Java Application Stub file to copy for your application (default
0164:         * MacOS system stub file)
0165:         * </dl>
0166:         * 
0167:         * <p>
0168:         * Rarely used optional attributes.
0169:         * <dl>
0170:         * <dt>chmod
0171:         * <dd>Full path to the chmod command. This almost certainly does NOT need to
0172:         * be set.
0173:         * </dl>
0174:         * 
0175:         * <p>
0176:         * The task also supports nested &lt;execfileset&gt; and/or &lt;execfilelist&gt;
0177:         * elements, and &lt;resourcefileset&gt; and/or &lt;resourcefilelist&gt;
0178:         * elements, which are standard Ant FileSet and FileList elements. In the first
0179:         * case, the referenced files are copied to the <code>Contents/MacOS</code>
0180:         * directory and made executable, and in the second they are copied to the
0181:         * <code>Contents/Resources</code> directory and not made executable. If you
0182:         * winrces, note that in fact the files are installed in locations which have
0183:         * the same relation to the <code>Contents/Resources</code> directory as the
0184:         * files in the FileSet or FileList have to the 'dir' attribute. Thus in the
0185:         * case:
0186:         * 
0187:         * <pre>
0188:         *   &lt;resourcefileset dir=&quot;builddir/architectures&quot;
0189:         *                       includes=&quot;ppc/*.jnilib&quot;/&gt;
0190:         * </pre>
0191:         * 
0192:         * <p>
0193:         * the <code>*.jnilib</code> files will be installed in
0194:         * <code>Contents/Resources/ppc</code>.
0195:         * 
0196:         * <p>
0197:         * The task supports a nested &lt;javaproperty&gt; element, which allows you to
0198:         * specify further properties which are set for the JVM when the application is
0199:         * launched. This takes a required <code>key</code> attribute, giving the
0200:         * property key, plus an attribute giving the property value, which may be one
0201:         * of <code>value</code>, giving the string value of the property,
0202:         * <code>file</code>, setting the value of the property to be the absolute
0203:         * path of the given file, or <code>path</code>, which sets the value to the
0204:         * given path. If you are setting paths here, recall that, within the bundle,
0205:         * <code>$APP_PACKAGE</code> is set to the root directory of the bundle (ie,
0206:         * the path to the <code>foo.app</code> directory), and <code>$JAVAROOT</code>
0207:         * to the directory <code>Contents/Resources/Java</code>.
0208:         * 
0209:         * <p>
0210:         * Minimum example:
0211:         * 
0212:         * <pre>
0213:         *  
0214:         *    &lt;jarbundler dir=&quot;release&quot; name=&quot;Bar Project&quot; mainclass=&quot;org.bar.Main&quot;
0215:         *        jars=&quot;bin/Bar.jar&quot; /&gt;
0216:         * </pre>
0217:         * 
0218:         * <p>
0219:         * Using Filesets
0220:         * 
0221:         * <pre>
0222:         *    &lt;jarbundler dir=&quot;release&quot; name=&quot;Bar Project&quot; mainclass=&quot;org.bar.Main&quot;&gt;
0223:         *      &lt;jarfileset dir=&quot;bin&quot;&gt;
0224:         *        &lt;include name=&quot;*.jar&quot; /&gt;
0225:         *        &lt;exclude name=&quot;test.jar&quot; /&gt;
0226:         *      &lt;/jarfileset&gt;
0227:         *      &lt;execfileset dir=&quot;execs&quot;&gt;
0228:         *        &lt;include name=&quot;**&quot; /&gt;
0229:         *      &lt;/execfileset&gt;
0230:         *    &lt;/jarbundler&gt;
0231:         * </pre>
0232:         * 
0233:         * <p>
0234:         * Much Longer example:
0235:         * </p>
0236:         * 
0237:         * <pre>
0238:         *    &lt;jarbundler dir=&quot;release&quot;
0239:         *                name=&quot;Foo Project&quot;
0240:         *                mainclass=&quot;org.bar.Main&quot;
0241:         *                version=&quot;1.0 b 1&quot;
0242:         *                infostring=&quot;Foo Project (c) 2002&quot; 
0243:         *                type=&quot;APPL&quot;
0244:         *                jars=&quot;bin/foo.jar bin/bar.jar&quot;
0245:         *                execs=&quot;exec/foobar&quot;
0246:         *                signature=&quot;????&quot;
0247:         *                workingdirectory=&quot;temp&quot;
0248:         *                icon=&quot;resources/foo.icns&quot;
0249:         *                jvmversion=&quot;1.4.1+&quot;
0250:         *                vmoptions=&quot;-Xmx256m&quot;/&gt;
0251:         * </pre>
0252:         * 
0253:         * http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/
0254:         */
0255:        public class JarBundler extends MatchingTask {
0256:
0257:            private static final String DEFAULT_STUB = "/System/Library/Frameworks/JavaVM.framework/Versions/Current/Resources/MacOS/JavaApplicationStub";
0258:
0259:            private static final String ABOUTMENU_KEY = "com.apple.mrj.application.apple.menu.about.name";
0260:            private static final Set menuItems = new HashSet();
0261:            private File mAppIcon;
0262:
0263:            private File mRootDir;
0264:
0265:            private final List mJavaFileLists = new ArrayList();
0266:            private final List mJarFileSets = new ArrayList();
0267:
0268:            private final List mExecFileLists = new ArrayList();
0269:            private final List mExecFileSets = new ArrayList();
0270:
0271:            private final List mResourceFileLists = new ArrayList();
0272:            private final List mResourceFileSets = new ArrayList();
0273:
0274:            private final List mJarFileLists = new ArrayList();
0275:            private final List mJavaFileSets = new ArrayList();
0276:
0277:            private final List mExtraClassPathFileLists = new ArrayList();
0278:            private final List mExtraClassPathFileSets = new ArrayList();
0279:
0280:            private final List mJarAttrs = new ArrayList();
0281:
0282:            private final List mExecAttrs = new ArrayList();
0283:
0284:            private final List mExtraClassPathAttrs = new ArrayList();
0285:
0286:            private final List mHelpBooks = new ArrayList();
0287:
0288:            private boolean mVerbose = false;
0289:            private boolean mShowPlist = false;
0290:
0291:            // Java properties used by Mac OS X Java applications
0292:
0293:            private File mStubFile = new File(DEFAULT_STUB);
0294:
0295:            private Boolean mAntiAliasedGraphics = null;
0296:
0297:            private Boolean mAntiAliasedText = null;
0298:
0299:            private Boolean mLiveResize = null;
0300:
0301:            private Boolean mScreenMenuBar = null;
0302:
0303:            private Boolean mGrowbox = null;
0304:
0305:            private Boolean mGrowboxIntrudes = null;
0306:
0307:            // The root of the application bundle
0308:            private File bundleDir;
0309:
0310:            // "Contents" directory
0311:            private File mContentsDir;
0312:
0313:            // "Contents/MacOS" directory
0314:            private File mMacOsDir;
0315:
0316:            // "Contents/Resources" directory
0317:            private File mResourcesDir;
0318:
0319:            // "Contents/Resources/Java" directory
0320:            private File mJavaDir;
0321:
0322:            // Full path to the 'chmod' command. Can be overridden
0323:            // with the 'chmod' attribute. Won't cause any harm if
0324:            // not set, or if this executable doesn't exist.
0325:
0326:            private AppBundleProperties bundleProperties = new AppBundleProperties();
0327:
0328:            // Ant file utilities
0329:
0330:            private FileUtils mFileUtils = FileUtils.getFileUtils();
0331:
0332:            /***************************************************************************
0333:             * Retreive task attributes
0334:             **************************************************************************/
0335:
0336:            /**
0337:             * Arguments to the
0338:             * 
0339:             * @param s
0340:             *            The arguments to pass to the application being launched.
0341:             */
0342:            public void setArguments(String s) {
0343:                bundleProperties.setArguments(s);
0344:            }
0345:
0346:            /**
0347:             * Override the stub file path to build on non-MacOS platforms
0348:             * 
0349:             * @param file
0350:             *            the path to the stub file
0351:             */
0352:            public void setStubFile(File file) {
0353:                mStubFile = (file.exists()) ? file : new File(DEFAULT_STUB);
0354:                bundleProperties.setCFBundleExecutable(file.getName());
0355:            }
0356:
0357:            /**
0358:             * Setter for the "dir" attribute (required)
0359:             */
0360:            public void setDir(File f) {
0361:                mRootDir = f;
0362:            }
0363:
0364:            /**
0365:             * Setter for the "name" attribute (required) This attribute names the
0366:             * output application bundle and asks as the CFBundleName if 'bundlename' is
0367:             * not specified
0368:             */
0369:            public void setName(String s) {
0370:                bundleProperties.setApplicationName(s);
0371:            }
0372:
0373:            /**
0374:             * Setter for the "shortname" attribute (optional) This key identifies the
0375:             * short name of the bundle. This name should be less than 16 characters
0376:             * long and be suitable for displaying in the menu and the About box. The
0377:             * name is (silently) cropped to this if necessary.
0378:             */
0379:            public void setShortName(String s) {
0380:                bundleProperties.setCFBundleName(s);
0381:            }
0382:
0383:            /**
0384:             * Setter for the "mainclass" attribute (required)
0385:             */
0386:            public void setMainClass(String s) {
0387:                bundleProperties.setMainClass(s);
0388:            }
0389:
0390:            /**
0391:             * Setter for the "WorkingDirectory" attribute (optional)
0392:             */
0393:            public void setWorkingDirectory(String s) {
0394:                bundleProperties.setWorkingDirectory(s);
0395:            }
0396:
0397:            /**
0398:             * Setter for the "icon" attribute (optional)
0399:             */
0400:
0401:            public void setIcon(File f) {
0402:                mAppIcon = f;
0403:                bundleProperties.setCFBundleIconFile(f.getName());
0404:            }
0405:
0406:            /**
0407:             * Setter for the "bundleid" attribute (optional) This key specifies a
0408:             * unique identifier string for the bundle. This identifier should be in the
0409:             * form of a Java-style package name, for example com.mycompany.myapp. The
0410:             * bundle identifier can be used to locate the bundle at runtime. The
0411:             * preferences system uses this string to identify applications uniquely.
0412:             * 
0413:             * No default.
0414:             */
0415:            public void setBundleid(String s) {
0416:                bundleProperties.setCFBundleIdentifier(s);
0417:            }
0418:
0419:            /**
0420:             * Setter for the "developmentregion" attribute(optional) Default "English".
0421:             */
0422:            public void setDevelopmentregion(String s) {
0423:                bundleProperties.setCFBundleDevelopmentRegion(s);
0424:            }
0425:
0426:            /**
0427:             * Setter for the "aboutmenuname" attribute (optional)
0428:             */
0429:            public void setAboutmenuname(String s) {
0430:                bundleProperties.setCFBundleName(s);
0431:            }
0432:
0433:            /**
0434:             * Setter for the "smalltabs" attribute (optional)
0435:             */
0436:            public void setSmallTabs(boolean b) {
0437:                bundleProperties.addJavaProperty("com.apple.smallTabs",
0438:                        new Boolean(b).toString());
0439:            }
0440:
0441:            /**
0442:             * Setter for the "vmoptions" attribute (optional)
0443:             */
0444:            public void setVmoptions(String s) {
0445:                bundleProperties.setVMOptions(s);
0446:            }
0447:
0448:            /**
0449:             * Setter for the "antialiasedgraphics" attribute (optional)
0450:             */
0451:            public void setAntialiasedgraphics(boolean b) {
0452:                mAntiAliasedGraphics = new Boolean(b);
0453:            }
0454:
0455:            /**
0456:             * Setter for the "antialiasedtext" attribute (optional)
0457:             */
0458:            public void setAntialiasedtext(boolean b) {
0459:                mAntiAliasedText = new Boolean(b);
0460:            }
0461:
0462:            /**
0463:             * Setter for the "screenmenu" attribute (optional)
0464:             */
0465:            public void setScreenmenu(boolean b) {
0466:                mScreenMenuBar = new Boolean(b);
0467:            }
0468:
0469:            /**
0470:             * Setter for the "growbox" attribute (optional)
0471:             */
0472:            public void setGrowbox(boolean b) {
0473:                mGrowbox = new Boolean(b);
0474:            }
0475:
0476:            /**
0477:             * Setter for the "growboxintrudes" attribute (optional)
0478:             */
0479:            public void setGrowboxintrudes(boolean b) {
0480:                mGrowboxIntrudes = new Boolean(b);
0481:            }
0482:
0483:            /**
0484:             * Setter for the "liveresize" attribute (optional)
0485:             */
0486:            public void setLiveresize(boolean b) {
0487:                mLiveResize = new Boolean(b);
0488:            }
0489:
0490:            /**
0491:             * Setter for the "type" attribute (optional)
0492:             */
0493:            public void setType(String s) {
0494:                bundleProperties.setCFBundlePackageType(s);
0495:            }
0496:
0497:            /**
0498:             * Setter for the "signature" attribute (optional)
0499:             */
0500:            public void setSignature(String s) {
0501:                bundleProperties.setCFBundleSignature(s);
0502:            }
0503:
0504:            /**
0505:             * Setter for the "jvmversion" attribute (optional)
0506:             */
0507:            public void setJvmversion(String s) {
0508:                bundleProperties.setJVMVersion(s);
0509:            }
0510:
0511:            /**
0512:             * Setter for the "infostring" attribute (optional) This key identifies a
0513:             * human-readable plain text string displaying the copyright information for
0514:             * the bundle. The Finder displays this information in the Info window of
0515:             * the bundle. (This string was also known as the long version string in Mac
0516:             * OS 9). The format of the key should be of the following format: "&copy;
0517:             * Great Software, Inc, 1999". You can localize this string by including it
0518:             * in the InfoPlist.strings file of the appropriate .lproj directory.
0519:             */
0520:
0521:            public void setInfoString(String s) {
0522:                bundleProperties.setCFBundleGetInfoString(s);
0523:            }
0524:
0525:            /**
0526:             * Setter for the "shortinfostring" attribute (optional) This key identifies
0527:             * the marketing version of the bundle. The marketing version is a string
0528:             * that usually displays the major and minor version of the bundle. This
0529:             * string is usually of the form n.n.n where n is a number. The first number
0530:             * is the major version number of the bundle. The second and third numbers
0531:             * are minor revision numbers. You may omit minor revision numbers as
0532:             * appropriate. The value of this key is displayed in the default About box
0533:             * for Cocoa applications.
0534:             * 
0535:             * The value for this key differs from the value for "CFBundleVersion",
0536:             * which identifies a specific build number. The CFBundleShortVersionString
0537:             * value represents a more formal version that does not change with every
0538:             * build.
0539:             */
0540:            public void setShortInfoString(String s) {
0541:                setVersion(s);
0542:            }
0543:
0544:            /**
0545:             * Setter for the "verbose" attribute (optional)
0546:             */
0547:            public void setVerbose(boolean verbose) {
0548:                this .mVerbose = verbose;
0549:            }
0550:
0551:            public void setShowPlist(boolean showPlist) {
0552:                this .mShowPlist = showPlist;
0553:            }
0554:
0555:            /**
0556:             * Setter for the "buildnumber" attribute (optional) This key specifies the
0557:             * exact build version of the bundle. This string is usually of the form
0558:             * nn.n.nxnnn where n is a digit and x is a character from the set [abdf].
0559:             * The first number is the major version number of the bundle and can
0560:             * contain one or two digits to represent a number in the range 0-99. The
0561:             * second and third numbers are minor revision numbers and must be a single
0562:             * numeric digit. The fourth set of digits is the specific build number for
0563:             * the release.
0564:             * 
0565:             * You may omit minor revision and build number information as appropriate.
0566:             * You may also omit major and minor revision information and specify only a
0567:             * build number. For example, valid version numbers include: 1.0.1,
0568:             * 1.2.1b10, 1.2d200, d125, 101, and 1.0.
0569:             * 
0570:             * The value of this key typically changes between builds and is displayed
0571:             * in the Cocoa About panel in parenthesis. To specify the version
0572:             * information of a released bundle, use the CFBundleShortVersionString key.
0573:             */
0574:            public void setBuild(String s) {
0575:                bundleProperties.setCFBundleVersion(s);
0576:            }
0577:
0578:            /**
0579:             * Setter for the version attribute (optional). It is this property, not
0580:             * CFBundleVersion, which should receive the `short' version string. See for
0581:             * example
0582:             * <http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/>
0583:             */
0584:            public void setVersion(String s) {
0585:                bundleProperties.setCFBundleShortVersionString(s);
0586:            }
0587:
0588:            public void setHelpBookFolder(String s) {
0589:                bundleProperties.setCFBundleHelpBookFolder(s);
0590:            }
0591:
0592:            public void setHelpBookName(String s) {
0593:                bundleProperties.setCFBundleHelpBookName(s);
0594:            }
0595:
0596:            /**
0597:             * Setter for the "jars" attribute (required if no "jarfileset" is present)
0598:             */
0599:            public void setJars(String s) {
0600:                PatternSet patset = new PatternSet();
0601:                patset.setIncludes(s);
0602:
0603:                String[] jarNames = patset.getIncludePatterns(getProject());
0604:
0605:                for (int i = 0; i < jarNames.length; i++)
0606:                    mJarAttrs.add(getProject().resolveFile(jarNames[i]));
0607:            }
0608:
0609:            /**
0610:             * Setter for the "jar" attribute (required if no "jarfileset" is present)
0611:             */
0612:            public void setJar(File s) {
0613:                mJarAttrs.add(s);
0614:            }
0615:
0616:            /**
0617:             * Setter for the "execs" attribute (optional)
0618:             */
0619:            public void setExecs(String s) {
0620:                PatternSet patset = new PatternSet();
0621:                patset.setIncludes(s);
0622:
0623:                String[] execNames = patset.getIncludePatterns(getProject());
0624:
0625:                for (int i = 0; i < execNames.length; i++) {
0626:                    File f = new File(execNames[i]);
0627:                    mExecAttrs.add(f);
0628:                }
0629:            }
0630:
0631:            /**
0632:             * Setter for the "extraclasspath" attribute (optional)
0633:             */
0634:            public void setExtraclasspath(String s) {
0635:                PatternSet patset = new PatternSet();
0636:                patset.setIncludes(s);
0637:
0638:                String[] cpNames = patset.getIncludePatterns(getProject());
0639:
0640:                for (int i = 0; i < cpNames.length; i++) {
0641:                    File f = new File(cpNames[i]);
0642:                    mExtraClassPathAttrs.add(f);
0643:                }
0644:            }
0645:
0646:            /**
0647:             * Set the 'chmod' executable.
0648:             */
0649:            public void setChmod(String s) {
0650:                log("The \"chmod\" attribute has deprecaited, using the ANT Chmod task internally");
0651:            }
0652:
0653:            /***************************************************************************
0654:             * Nested tasks - derived from FileList and FileSet
0655:             **************************************************************************/
0656:
0657:            public void addJarfileset(FileSet fs) {
0658:                mJarFileSets.add(fs);
0659:            }
0660:
0661:            public void addJarfilelist(FileList fl) {
0662:                mJarFileLists.add(fl);
0663:            }
0664:
0665:            public void addExecfileset(FileSet fs) {
0666:                mExecFileSets.add(fs);
0667:            }
0668:
0669:            public void addExecfilelist(FileList fl) {
0670:                mExecFileLists.add(fl);
0671:            }
0672:
0673:            public void addResourcefileset(FileSet fs) {
0674:                mResourceFileSets.add(fs);
0675:            }
0676:
0677:            public void addResourcefilelist(FileList fl) {
0678:                mResourceFileLists.add(fl);
0679:            }
0680:
0681:            public void addJavafileset(FileSet fs) {
0682:                mJavaFileSets.add(fs);
0683:            }
0684:
0685:            public void addJavafilelist(FileList fl) {
0686:                mJavaFileLists.add(fl);
0687:            }
0688:
0689:            public void addExtraclasspathfileset(FileSet fs) {
0690:                mExtraClassPathFileSets.add(fs);
0691:            }
0692:
0693:            public void addExtraclasspathfilelist(FileList fl) {
0694:                mExtraClassPathFileLists.add(fl);
0695:            }
0696:
0697:            /***************************************************************************
0698:             * Nested tasks - new tasks with custom attributes
0699:             **************************************************************************/
0700:
0701:            public void addConfiguredJavaProperty(JavaProperty javaProperty)
0702:                    throws BuildException {
0703:
0704:                String name = javaProperty.getName();
0705:                String value = javaProperty.getValue();
0706:
0707:                if ((name == null) || (value == null))
0708:                    throw new BuildException(
0709:                            "'<javaproperty>' must have both 'name' and 'value' attibutes");
0710:
0711:                bundleProperties.addJavaProperty(name, value);
0712:            }
0713:
0714:            public void addConfiguredDocumentType(DocumentType documentType)
0715:                    throws BuildException {
0716:
0717:                String name = documentType.getName();
0718:                String role = documentType.getRole();
0719:                List osTypes = documentType.getOSTypes();
0720:                List extensions = documentType.getExtensions();
0721:                List mimeTypes = documentType.getMimeTypes();
0722:
0723:                if ((name == null) || (role == null))
0724:                    throw new BuildException(
0725:                            "'<documenttype>' must have both a 'name' and a 'role' attibute");
0726:
0727:                if ((osTypes.isEmpty()) && (extensions.isEmpty())
0728:                        && (mimeTypes.isEmpty()))
0729:                    throw new BuildException(
0730:                            "'<documenttype>' of \""
0731:                                    + name
0732:                                    + "\" must have 'osTypes' or 'extensions' or 'mimeTypes'");
0733:
0734:                bundleProperties.addDocumentType(documentType);
0735:            }
0736:
0737:            public void addConfiguredService(Service service) {
0738:
0739:                //if (service.getPortName() == null)
0740:                //	throw new BuildException("\"<service>\" must have a \"portName\" attribute");
0741:
0742:                if (service.getMessage() == null)
0743:                    throw new BuildException(
0744:                            "\"<service>\" must have a \"message\" attribute");
0745:
0746:                String menuItem = service.getMenuItem();
0747:                if (menuItem == null)
0748:                    throw new BuildException(
0749:                            "\"<service>\" must have a \"menuItem\" attribute");
0750:                if (!menuItems.add(menuItem))
0751:                    throw new BuildException(
0752:                            "\"<service>\" \"menuItem\" value must be unique");
0753:
0754:                if (service.getSendTypes().isEmpty()
0755:                        && service.getReturnTypes().isEmpty())
0756:                    throw new BuildException(
0757:                            "\"<service>\" must have either a \"sendTypes\" attribute, a \"returnTypes\" attribute or both");
0758:
0759:                String keyEquivalent = service.getKeyEquivalent();
0760:                if ((keyEquivalent != null) && (1 != keyEquivalent.length()))
0761:                    throw new BuildException(
0762:                            "\"<service>\" \"keyEquivalent\" must be one character if present");
0763:
0764:                String timeoutString = service.getTimeout();
0765:                if (timeoutString != null) {
0766:                    long timeout = -1;
0767:                    try {
0768:                        timeout = Long.parseLong(timeoutString);
0769:                    } catch (NumberFormatException nfe) {
0770:                        throw new BuildException(
0771:                                "\"<service>\" \"timeout\" must be a positive integral number");
0772:                    }
0773:                    if (timeout < 0)
0774:                        throw new BuildException(
0775:                                "\"<service>\" \"timeout\" must not be negative");
0776:                }
0777:
0778:                bundleProperties.addService(service);
0779:            }
0780:
0781:            public void addConfiguredHelpBook(HelpBook helpBook) {
0782:
0783:                // Validity check on 'foldername'
0784:                if (helpBook.getFolderName() == null) {
0785:                    if (bundleProperties.getCFBundleHelpBookFolder() == null)
0786:                        throw new BuildException(
0787:                                "Either the '<helpbook>' attribute 'foldername' or the '<jarbundler>' attribute 'helpbookfolder' must be defined");
0788:                    helpBook.setFolderName(bundleProperties
0789:                            .getCFBundleHelpBookFolder());
0790:                }
0791:
0792:                // Validity check on 'title'
0793:                if (helpBook.getName() == null) {
0794:                    if (bundleProperties.getCFBundleHelpBookName() == null)
0795:                        throw new BuildException(
0796:                                "Either the '<helpbook>' attribute 'name' or the '<jarbundler>' attribute 'helpbookname' must be defined");
0797:                    helpBook
0798:                            .setName(bundleProperties.getCFBundleHelpBookName());
0799:                }
0800:
0801:                // Make sure some file were selected...
0802:                List fileLists = helpBook.getFileLists();
0803:                List fileSets = helpBook.getFileSets();
0804:
0805:                if (fileLists.isEmpty() && fileSets.isEmpty())
0806:                    throw new BuildException(
0807:                            "The '<helpbook>' task must have either "
0808:                                    + "'<fileset>' or  '<filelist>' nested tags");
0809:
0810:                mHelpBooks.add(helpBook);
0811:            }
0812:
0813:            /***************************************************************************
0814:             * Execute the task
0815:             **************************************************************************/
0816:
0817:            /**
0818:             * The method executing the task
0819:             */
0820:
0821:            public void execute() throws BuildException {
0822:
0823:                // Delete any existing Application bundle directory structure
0824:
0825:                bundleDir = new File(mRootDir, bundleProperties
0826:                        .getApplicationName()
0827:                        + ".app");
0828:
0829:                if (bundleDir.exists()) {
0830:                    Delete deleteTask = new Delete();
0831:                    deleteTask.setProject(getProject());
0832:                    deleteTask.setDir(bundleDir);
0833:                    deleteTask.execute();
0834:                }
0835:
0836:                // Validate - look for required attributes
0837:                // ///////////////////////////////////////////
0838:
0839:                if (mRootDir == null)
0840:                    throw new BuildException(
0841:                            "Required attribute \"dir\" is not set.");
0842:
0843:                if (mJarAttrs.isEmpty() && mJarFileSets.isEmpty()
0844:                        && mJarFileLists.isEmpty())
0845:                    throw new BuildException(
0846:                            "Either the attribute \"jar\" must "
0847:                                    + "be set, or one or more jarfilelists or "
0848:                                    + "jarfilesets must be added.");
0849:
0850:                if (!mJarAttrs.isEmpty()
0851:                        && (!mJarFileSets.isEmpty() || !mJarFileLists.isEmpty()))
0852:                    throw new BuildException(
0853:                            "Cannot set both the attribute "
0854:                                    + "\"jars\" and use jar filesets/filelists.  Use only one or the other.");
0855:
0856:                if (bundleProperties.getApplicationName() == null)
0857:                    throw new BuildException(
0858:                            "Required attribute \"name\" is not set.");
0859:
0860:                if (bundleProperties.getMainClass() == null)
0861:                    throw new BuildException(
0862:                            "Required attribute \"mainclass\" is not set.");
0863:
0864:                // /////////////////////////////////////////////////////////////////////////////////////
0865:
0866:                // Set up some Java properties
0867:
0868:                // About Menu, deprecated under 1.4+
0869:                if (useOldPropertyNames())
0870:                    bundleProperties.addJavaProperty(ABOUTMENU_KEY,
0871:                            bundleProperties.getCFBundleName());
0872:
0873:                // Anti Aliased Graphics, renamed in 1.4+
0874:                String antiAliasedProperty = useOldPropertyNames() ? "com.apple.macosx.AntiAliasedGraphicsOn"
0875:                        : "apple.awt.antialiasing";
0876:
0877:                if (mAntiAliasedGraphics != null)
0878:                    bundleProperties.addJavaProperty(antiAliasedProperty,
0879:                            mAntiAliasedGraphics.toString());
0880:
0881:                // Anti Aliased Text, renamed in 1.4+
0882:                String antiAliasedTextProperty = useOldPropertyNames() ? "com.apple.macosx.AntiAliasedTextOn"
0883:                        : "apple.awt.textantialiasing";
0884:
0885:                if (mAntiAliasedText != null)
0886:                    bundleProperties.addJavaProperty(antiAliasedTextProperty,
0887:                            mAntiAliasedText.toString());
0888:
0889:                // Live Resize, deprecated under 1.4+
0890:                if (useOldPropertyNames() && (mLiveResize != null))
0891:                    bundleProperties.addJavaProperty(
0892:                            "com.apple.mrj.application.live-resize",
0893:                            mLiveResize.toString());
0894:
0895:                // Screen Menu Bar, renamed in 1.4+
0896:                String screenMenuBarProperty = useOldPropertyNames() ? "com.apple.macos.useScreenMenuBar"
0897:                        : "apple.laf.useScreenMenuBar";
0898:
0899:                if (mScreenMenuBar != null)
0900:                    bundleProperties.addJavaProperty(screenMenuBarProperty,
0901:                            mScreenMenuBar.toString());
0902:
0903:                // Growbox, added with 1.4+
0904:                if ((useOldPropertyNames() == false) && (mGrowbox != null))
0905:                    bundleProperties.addJavaProperty("apple.awt.showGrowBox",
0906:                            mGrowbox.toString());
0907:
0908:                // Growbox Intrudes, deprecated under 1.4+
0909:                if (useOldPropertyNames() && (mGrowboxIntrudes != null))
0910:                    bundleProperties.addJavaProperty(
0911:                            "com.apple.mrj.application.growbox.intrudes",
0912:                            mGrowboxIntrudes.toString());
0913:
0914:                if (!mRootDir.exists()
0915:                        || (mRootDir.exists() && !mRootDir.isDirectory()))
0916:                    throw new BuildException(
0917:                            "Destination directory specified by \"dir\" "
0918:                                    + "attribute must already exist.");
0919:
0920:                if (bundleDir.exists())
0921:                    throw new BuildException("The directory/bundle \""
0922:                            + bundleDir.getName()
0923:                            + "\" already exists, cannot continue.");
0924:
0925:                // Status message
0926:                log("Creating application bundle: " + bundleDir);
0927:
0928:                if (!bundleDir.mkdir())
0929:                    throw new BuildException("Unable to create bundle: "
0930:                            + bundleDir);
0931:
0932:                // Make the Contents directory
0933:                mContentsDir = new File(bundleDir, "Contents");
0934:
0935:                if (!mContentsDir.mkdir())
0936:                    throw new BuildException("Unable to create directory "
0937:                            + mContentsDir);
0938:
0939:                // Make the "MacOS" directory
0940:                mMacOsDir = new File(mContentsDir, "MacOS");
0941:
0942:                if (!mMacOsDir.mkdir())
0943:                    throw new BuildException("Unable to create directory "
0944:                            + mMacOsDir);
0945:
0946:                // Make the Resources directory
0947:                mResourcesDir = new File(mContentsDir, "Resources");
0948:
0949:                if (!mResourcesDir.mkdir())
0950:                    throw new BuildException("Unable to create directory "
0951:                            + mResourcesDir);
0952:
0953:                // Make the Resources/Java directory
0954:                mJavaDir = new File(mResourcesDir, "Java");
0955:
0956:                if (!mJavaDir.mkdir())
0957:                    throw new BuildException("Unable to create directory "
0958:                            + mJavaDir);
0959:
0960:                // Copy icon file to resource dir. If no icon parameter
0961:                // is supplied, the default icon will be used.
0962:
0963:                if (mAppIcon != null) {
0964:
0965:                    try {
0966:                        File dest = new File(mResourcesDir, mAppIcon.getName());
0967:
0968:                        if (mVerbose)
0969:                            log("Copying application icon file to \""
0970:                                    + bundlePath(dest) + "\"");
0971:
0972:                        mFileUtils.copyFile(mAppIcon, dest);
0973:                    } catch (IOException ex) {
0974:                        throw new BuildException("Cannot copy icon file: " + ex);
0975:                    }
0976:                }
0977:
0978:                // Copy document type icons, if any, to the resource dir
0979:                try {
0980:                    Iterator itor = bundleProperties.getDocumentTypes()
0981:                            .iterator();
0982:
0983:                    while (itor.hasNext()) {
0984:                        DocumentType documentType = (DocumentType) itor.next();
0985:                        File iconFile = documentType.getIconFile();
0986:                        if (iconFile != null) {
0987:                            File dest = new File(mResourcesDir, iconFile
0988:                                    .getName());
0989:                            if (mVerbose)
0990:                                log("Copying document icon file to \""
0991:                                        + bundlePath(dest) + "\"");
0992:                            mFileUtils.copyFile(iconFile, dest);
0993:                        }
0994:                    }
0995:                } catch (IOException ex) {
0996:                    throw new BuildException("Cannot copy document icon file: "
0997:                            + ex);
0998:                }
0999:
1000:                // Copy application jar(s) from the "jars" attribute (if any)
1001:                processJarAttrs();
1002:
1003:                // Copy application jar(s) from the nested jarfileset element(s)
1004:                processJarFileSets();
1005:
1006:                // Copy application jar(s) from the nested jarfilelist element(s)
1007:                processJarFileLists();
1008:
1009:                // Copy executable(s) from the "execs" attribute (if any)
1010:                processExecAttrs();
1011:
1012:                // Copy executable(s) from the nested execfileset element(s)
1013:                processExecFileSets();
1014:
1015:                // Copy executable(s) from the nested execfilelist element(s)
1016:                processExecFileLists();
1017:
1018:                // Copy resource(s) from the nested resourcefileset element(s)
1019:                processResourceFileSets();
1020:
1021:                // Copy resource(s) from the nested javafileset element(s)
1022:                processJavaFileSets();
1023:
1024:                // Copy resource(s) from the nested resourcefilelist element(s)
1025:                processResourceFileLists();
1026:
1027:                // Copy resource(s) from the nested javafilelist element(s)
1028:                processJavaFileLists();
1029:
1030:                // Add external classpath references from the extraclasspath attributes
1031:                processExtraClassPathAttrs();
1032:
1033:                // Add external classpath references from the nested
1034:                // extraclasspathfileset element(s)
1035:                processExtraClassPathFileSets();
1036:
1037:                // Add external classpath references from the nested
1038:                // extraclasspathfilelist attributes
1039:                processExtraClassPathFileLists();
1040:
1041:                // Copy HelpBooks into place
1042:                copyHelpBooks();
1043:
1044:                // Copy the JavaApplicationStub file from the Java system directory to
1045:                // the MacOS directory
1046:                copyApplicationStub();
1047:
1048:                // Create the Info.plist file
1049:                writeInfoPlist();
1050:
1051:                // Create the PkgInfo file
1052:                writePkgInfo();
1053:
1054:                // Done!
1055:            }
1056:
1057:            /***************************************************************************
1058:             * Private utility methods.
1059:             **************************************************************************/
1060:
1061:            private void setExecutable(File f) {
1062:
1063:                Chmod chmodTask = new Chmod();
1064:                chmodTask.setProject(getProject());
1065:                chmodTask.setFile(f);
1066:                chmodTask.setPerm("ugo+rx");
1067:
1068:                if (mVerbose)
1069:                    log("Setting \"" + bundlePath(f) + "\" to executable");
1070:
1071:                chmodTask.execute();
1072:
1073:            }
1074:
1075:            /**
1076:             * Utility method to determine whether this app bundle is targeting a 1.3 or
1077:             * 1.4 VM. The Mac OS X 1.3 VM uses different Java property names from the
1078:             * 1.4 VM to hint at native Mac OS X look and feel options. For example, on
1079:             * 1.3 the Java property to tell the VM to display Swing menu bars as screen
1080:             * menus is "com.apple.macos.useScreenMenuBar". Under 1.4, it becomes
1081:             * "apple.laf.useScreenMenuBar". Such is the price of progress, I suppose.
1082:             * 
1083:             * Obviously, this logic may need refactoring in the future.
1084:             */
1085:
1086:            private boolean useOldPropertyNames() {
1087:                return (bundleProperties.getJVMVersion().startsWith("1.3"));
1088:            }
1089:
1090:            private void processJarAttrs() throws BuildException {
1091:
1092:                try {
1093:
1094:                    for (Iterator jarIter = mJarAttrs.iterator(); jarIter
1095:                            .hasNext();) {
1096:                        File src = (File) jarIter.next();
1097:                        File dest = new File(mJavaDir, src.getName());
1098:
1099:                        if (mVerbose)
1100:                            log("Copying JAR file to \"" + bundlePath(dest)
1101:                                    + "\"");
1102:
1103:                        mFileUtils.copyFile(src, dest);
1104:                        bundleProperties.addToClassPath(dest.getName());
1105:                    }
1106:                } catch (IOException ex) {
1107:                    throw new BuildException("Cannot copy jar file: " + ex);
1108:                }
1109:            }
1110:
1111:            private void processJarFileSets() throws BuildException {
1112:
1113:                for (Iterator jarIter = mJarFileSets.iterator(); jarIter
1114:                        .hasNext();) {
1115:
1116:                    FileSet fs = (FileSet) jarIter.next();
1117:
1118:                    Project p = fs.getProject();
1119:                    File srcDir = fs.getDir(p);
1120:                    FileScanner ds = fs.getDirectoryScanner(p);
1121:                    fs.setupDirectoryScanner(ds, p);
1122:                    ds.scan();
1123:
1124:                    String[] files = ds.getIncludedFiles();
1125:
1126:                    try {
1127:
1128:                        for (int i = 0; i < files.length; i++) {
1129:                            String fileName = files[i];
1130:                            File src = new File(srcDir, fileName);
1131:                            File dest = new File(mJavaDir, fileName);
1132:
1133:                            if (mVerbose)
1134:                                log("Copying JAR file to \"" + bundlePath(dest)
1135:                                        + "\"");
1136:
1137:                            mFileUtils.copyFile(src, dest);
1138:                            bundleProperties.addToClassPath(fileName);
1139:                        }
1140:
1141:                    } catch (IOException ex) {
1142:                        throw new BuildException("Cannot copy jar file: " + ex);
1143:                    }
1144:                }
1145:            }
1146:
1147:            private void processJarFileLists() throws BuildException {
1148:
1149:                for (Iterator jarIter = mJarFileLists.iterator(); jarIter
1150:                        .hasNext();) {
1151:                    FileList fl = (FileList) jarIter.next();
1152:                    Project p = fl.getProject();
1153:                    File srcDir = fl.getDir(p);
1154:                    String[] files = fl.getFiles(p);
1155:
1156:                    try {
1157:
1158:                        for (int i = 0; i < files.length; i++) {
1159:                            String fileName = files[i];
1160:                            File src = new File(srcDir, fileName);
1161:                            File dest = new File(mJavaDir, fileName);
1162:
1163:                            if (mVerbose)
1164:                                log("Copying JAR file to \"" + bundlePath(dest)
1165:                                        + "\"");
1166:
1167:                            mFileUtils.copyFile(src, dest);
1168:                            bundleProperties.addToClassPath(fileName);
1169:                        }
1170:                    } catch (IOException ex) {
1171:                        throw new BuildException("Cannot copy jar file: " + ex);
1172:                    }
1173:                }
1174:            }
1175:
1176:            private void processExtraClassPathAttrs() throws BuildException {
1177:
1178:                for (Iterator jarIter = mExtraClassPathAttrs.iterator(); jarIter
1179:                        .hasNext();) {
1180:                    File src = (File) jarIter.next();
1181:                    bundleProperties.addToExtraClassPath(src.getPath());
1182:                }
1183:            }
1184:
1185:            private void processExtraClassPathFileSets() throws BuildException {
1186:
1187:                for (Iterator jarIter = mExtraClassPathFileSets.iterator(); jarIter
1188:                        .hasNext();) {
1189:                    FileSet fs = (FileSet) jarIter.next();
1190:                    Project p = fs.getProject();
1191:                    File srcDir = fs.getDir(p);
1192:                    FileScanner ds = fs.getDirectoryScanner(p);
1193:                    fs.setupDirectoryScanner(ds, p);
1194:                    ds.scan();
1195:
1196:                    String[] files = ds.getIncludedFiles();
1197:
1198:                    for (int i = 0; i < files.length; i++) {
1199:                        File f = new File(srcDir, files[i]);
1200:                        bundleProperties.addToExtraClassPath(f.getPath());
1201:                    }
1202:                }
1203:            }
1204:
1205:            private void processExtraClassPathFileLists() throws BuildException {
1206:
1207:                for (Iterator jarIter = mExtraClassPathFileLists.iterator(); jarIter
1208:                        .hasNext();) {
1209:                    FileList fl = (FileList) jarIter.next();
1210:                    Project p = fl.getProject();
1211:                    File srcDir = fl.getDir(p);
1212:                    String[] files = fl.getFiles(p);
1213:
1214:                    for (int i = 0; i < files.length; i++) {
1215:                        File f = new File(srcDir, files[i]);
1216:                        bundleProperties.addToExtraClassPath(f.getPath());
1217:                    }
1218:                }
1219:            }
1220:
1221:            private void processExecAttrs() throws BuildException {
1222:
1223:                try {
1224:
1225:                    for (Iterator execIter = mExecAttrs.iterator(); execIter
1226:                            .hasNext();) {
1227:                        File src = (File) execIter.next();
1228:                        File dest = new File(mMacOsDir, src.getName());
1229:
1230:                        if (mVerbose)
1231:                            log("Copying exec file to \"" + bundlePath(dest)
1232:                                    + "\"");
1233:
1234:                        mFileUtils.copyFile(src, dest);
1235:                        setExecutable(dest);
1236:                    }
1237:                } catch (IOException ex) {
1238:                    throw new BuildException("Cannot copy exec file: " + ex);
1239:                }
1240:            }
1241:
1242:            // Methods for copying FileSets into the application bundle ///////////////////////////////
1243:
1244:            // Files for the Contents/MacOS directory
1245:            private void processExecFileSets() {
1246:                processCopyingFileSets(mExecFileSets, mMacOsDir, true);
1247:            }
1248:
1249:            // Files for the Contents/Resources directory
1250:            private void processResourceFileSets() {
1251:                processCopyingFileSets(mResourceFileSets, mResourcesDir, false);
1252:            }
1253:
1254:            // Files for the Contents/Resources/Java directory
1255:            private void processJavaFileSets() {
1256:                processCopyingFileSets(mJavaFileSets, mJavaDir, false);
1257:            }
1258:
1259:            private void processCopyingFileSets(List fileSets, File targetdir,
1260:                    boolean setExec) {
1261:
1262:                for (Iterator execIter = fileSets.iterator(); execIter
1263:                        .hasNext();) {
1264:                    FileSet fs = (FileSet) execIter.next();
1265:                    Project p = fs.getProject();
1266:                    File srcDir = fs.getDir(p);
1267:                    FileScanner ds = fs.getDirectoryScanner(p);
1268:                    fs.setupDirectoryScanner(ds, p);
1269:                    ds.scan();
1270:
1271:                    String[] files = ds.getIncludedFiles();
1272:
1273:                    if (files.length == 0) {
1274:                        // this is probably an error -- warn about it
1275:                        System.err
1276:                                .println("WARNING: fileset for copying from directory "
1277:                                        + srcDir + ": no files found");
1278:                    } else {
1279:                        try {
1280:                            for (int i = 0; i < files.length; i++) {
1281:                                String fileName = files[i];
1282:                                File src = new File(srcDir, fileName);
1283:                                File dest = new File(targetdir, fileName);
1284:
1285:                                if (mVerbose)
1286:                                    log("Copying "
1287:                                            + (setExec ? "exec" : "resource")
1288:                                            + " file to \"" + bundlePath(dest)
1289:                                            + "\"");
1290:
1291:                                mFileUtils.copyFile(src, dest);
1292:                                if (setExec)
1293:                                    setExecutable(dest);
1294:                            }
1295:                        } catch (IOException ex) {
1296:                            throw new BuildException("Cannot copy file: " + ex);
1297:                        }
1298:                    }
1299:                }
1300:            }
1301:
1302:            // Methods for copying FileLists into the application bundle /////////////////////////////
1303:
1304:            // Files for the Contents/MacOS directory
1305:            private void processExecFileLists() throws BuildException {
1306:                processCopyingFileLists(mExecFileLists, mMacOsDir, true);
1307:            }
1308:
1309:            // Files for the Contents/Resources directory
1310:            private void processResourceFileLists() throws BuildException {
1311:                processCopyingFileLists(mResourceFileLists, mResourcesDir,
1312:                        false);
1313:            }
1314:
1315:            // Files for the Contents/Resources/Java directory
1316:            private void processJavaFileLists() throws BuildException {
1317:                processCopyingFileLists(mJavaFileLists, mJavaDir, false);
1318:            }
1319:
1320:            private void processCopyingFileLists(List fileLists,
1321:                    File targetDir, boolean setExec) throws BuildException {
1322:
1323:                for (Iterator execIter = fileLists.iterator(); execIter
1324:                        .hasNext();) {
1325:
1326:                    FileList fl = (FileList) execIter.next();
1327:                    Project p = fl.getProject();
1328:                    File srcDir = fl.getDir(p);
1329:                    String[] files = fl.getFiles(p);
1330:
1331:                    if (files.length == 0) {
1332:                        // this is probably an error -- warn about it
1333:                        System.err
1334:                                .println("WARNING: filelist for copying from directory "
1335:                                        + srcDir + ": no files found");
1336:                    } else {
1337:                        try {
1338:                            for (int i = 0; i < files.length; i++) {
1339:                                String fileName = files[i];
1340:                                File src = new File(srcDir, fileName);
1341:                                File dest = new File(targetDir, fileName);
1342:
1343:                                if (mVerbose)
1344:                                    log("Copying "
1345:                                            + (setExec ? "exec" : "resource")
1346:                                            + " file to \"" + bundlePath(dest)
1347:                                            + "\"");
1348:
1349:                                mFileUtils.copyFile(src, dest);
1350:                                if (setExec)
1351:                                    setExecutable(dest);
1352:                            }
1353:                        } catch (IOException ex) {
1354:                            throw new BuildException("Cannot copy jar file: "
1355:                                    + ex);
1356:                        }
1357:                    }
1358:                }
1359:            }
1360:
1361:            private void copyHelpBooks() {
1362:
1363:                for (Iterator itor = mHelpBooks.iterator(); itor.hasNext();) {
1364:
1365:                    HelpBook helpBook = (HelpBook) itor.next();
1366:
1367:                    String folderName = helpBook.getFolderName();
1368:                    String name = helpBook.getName();
1369:                    String locale = helpBook.getLocale();
1370:
1371:                    List fileLists = helpBook.getFileLists();
1372:                    List fileSets = helpBook.getFileSets();
1373:
1374:                    File helpBookDir = null;
1375:
1376:                    if (locale == null) {
1377:
1378:                        // Set the Bundle entries for a nonlocalized Help Book
1379:                        if (folderName != null)
1380:                            bundleProperties
1381:                                    .setCFBundleHelpBookFolder(folderName);
1382:
1383:                        if (name != null)
1384:                            bundleProperties.setCFBundleHelpBookName(name);
1385:
1386:                        // The non-localized Help Book is top level "/Resources"
1387:                        helpBookDir = new File(mResourcesDir, folderName);
1388:                        helpBookDir.mkdir();
1389:
1390:                        if (mVerbose)
1391:                            log("Creating Help Book at \""
1392:                                    + bundlePath(helpBookDir) + "\"");
1393:
1394:                    } else {
1395:
1396:                        // The localized Help Book is "/Resources/locale.lproj"
1397:
1398:                        File lproj = new File(mResourcesDir, locale + ".lproj");
1399:                        lproj.mkdir();
1400:                        helpBookDir = new File(lproj, folderName);
1401:                        helpBookDir.mkdir();
1402:
1403:                        if (mVerbose)
1404:                            log("Creating Help Book for \"" + locale
1405:                                    + "\" at \"" + bundlePath(helpBookDir)
1406:                                    + "\"");
1407:
1408:                        // Create a local file to override the Bundle settings
1409:                        File infoPList = new File(lproj, "InfoPlist.strings");
1410:                        PrintWriter writer = null;
1411:                        try {
1412:                            writer = new PrintWriter(new FileWriter(infoPList));
1413:                            writer.println("CFBundleHelpBookFolder = \""
1414:                                    + folderName + "\";");
1415:                            writer.println("CFBundleHelpBookName = \"" + name
1416:                                    + "\";");
1417:                            writer.println("CFBundleName = \""
1418:                                    + bundleProperties.getCFBundleName()
1419:                                    + "\";");
1420:                        } catch (IOException ioe) {
1421:                            throw new BuildException(
1422:                                    "IOException in writing Help Book locale: "
1423:                                            + locale);
1424:                        } finally {
1425:                            mFileUtils.close(writer);
1426:                        }
1427:                    }
1428:
1429:                    // Write the Help Book source files into the bundle
1430:
1431:                    processCopyingFileSets(fileSets, helpBookDir, false);
1432:                    processCopyingFileLists(fileLists, helpBookDir, false);
1433:
1434:                }
1435:            }
1436:
1437:            // Copy the application stub into the bundle
1438:            // /////////////////////////////////////////////
1439:
1440:            private void copyApplicationStub() throws BuildException {
1441:
1442:                File newStubFile = new File(mMacOsDir, bundleProperties
1443:                        .getCFBundleExecutable());
1444:
1445:                if (mVerbose)
1446:                    log("Copying Java application stub to \""
1447:                            + bundlePath(newStubFile) + "\"");
1448:
1449:                try {
1450:                    mFileUtils.copyFile(mStubFile, newStubFile);
1451:                } catch (IOException ex) {
1452:                    throw new BuildException(
1453:                            "Cannot copy Java Application Stub: " + ex);
1454:                }
1455:
1456:                // Set the permissions on the stub file to executable
1457:
1458:                setExecutable(newStubFile);
1459:            }
1460:
1461:            private void writeInfoPlist() throws BuildException {
1462:                PropertyListWriter listWriter = new PropertyListWriter(
1463:                        bundleProperties);
1464:                File infoPlist = new File(mContentsDir, "Info.plist");
1465:
1466:                listWriter.writeFile(infoPlist);
1467:
1468:                if (mVerbose)
1469:                    log("Creating \"" + bundlePath(infoPlist) + "\" file");
1470:
1471:                if (mShowPlist) {
1472:                    try {
1473:                        BufferedReader in = new BufferedReader(new FileReader(
1474:                                infoPlist));
1475:                        String str;
1476:                        while ((str = in.readLine()) != null)
1477:                            log(str);
1478:                        in.close();
1479:                    } catch (IOException e) {
1480:                        throw new BuildException(e);
1481:                    }
1482:                }
1483:            }
1484:
1485:            //
1486:            // Write the PkgInfo file into the application bundle
1487:            //
1488:
1489:            private void writePkgInfo() throws BuildException {
1490:                File pkgInfo = new File(mContentsDir, "PkgInfo");
1491:                PrintWriter writer = null;
1492:
1493:                try {
1494:                    writer = new PrintWriter(new BufferedWriter(new FileWriter(
1495:                            pkgInfo)));
1496:                    writer.print(bundleProperties.getCFBundlePackageType());
1497:                    writer.println(bundleProperties.getCFBundleSignature());
1498:                    writer.flush();
1499:                } catch (IOException ex) {
1500:                    throw new BuildException("Cannot create PkgInfo file: "
1501:                            + ex);
1502:                } finally {
1503:                    mFileUtils.close(writer);
1504:                }
1505:            }
1506:
1507:            private String bundlePath(File bundleFile) {
1508:
1509:                String rootPath = bundleDir.getAbsolutePath();
1510:                String thisPath = bundleFile.getAbsolutePath();
1511:
1512:                return thisPath.substring(rootPath.length());
1513:
1514:            }
1515:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.