View Javadoc

1   /*************************************************************************
2    *
3    * $Id: Jad.java,v 1.1.1.1 2004/05/19 12:07:30 pra Exp $
4    *
5    * Copyright (c) 2001 Sun Microsystems, Inc.  All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer.
13   *
14   * 2. Redistributions in binary form must reproduce the above copyright
15   *    notice, this list of conditions and the following disclaimer in
16   *    the documentation and/or other materials provided with the
17   *    distribution.
18   *
19   * 3. The end-user documentation included with the redistribution,
20   *    if any, must include the following acknowledgment:
21   *       "This product includes software developed by the
22   *       Sun Microsystems, Inc. for Project JXTA."
23   *    Alternately, this acknowledgment may appear in the software itself,
24   *    if and wherever such third-party acknowledgments normally appear.
25   *
26   * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
27   *    must not be used to endorse or promote products derived from this
28   *    software without prior written permission. For written
29   *    permission, please contact Project JXTA at http://www.jxta.org.
30   *
31   * 5. Products derived from this software may not be called "JXTA",
32   *    nor may "JXTA" appear in their name, without prior written
33   *    permission of Sun.
34   *
35   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38   * DISCLAIMED.  IN NO EVENT SHALL SUN MICROSYSTEMS OR
39   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46   * SUCH DAMAGE.
47   *
48   * ====================================================================
49   *
50   * This software consists of voluntary contributions made by many
51   * individuals on behalf of Project JXTA.  For more
52   * information on Project JXTA, please see
53   * <http://www.jxta.org/>.
54   *
55   * This license is based on the BSD license adopted by the Apache
56   * Foundation.
57   **********************************************************************/
58  
59  package org.backsource.utils.ant;
60  
61  import java.io.File;
62  import java.io.FileReader;
63  import java.io.FileWriter;
64  import java.io.BufferedReader;
65  import java.io.BufferedWriter;
66  import java.io.IOException;
67  import java.util.Hashtable;
68  import java.util.Vector;
69  import java.util.Date;
70  import java.text.SimpleDateFormat;
71  import org.apache.tools.ant.Task;
72  import org.apache.tools.ant.BuildException;
73  
74  public final class Jad extends Task {
75  
76      // the separators used between key/value pairs in the JAD/JAM files
77      private static final String JAD_SEPARATOR = ":";
78      private static final String JAM_SEPARATOR = "=";
79  
80      private File jarFile = null;
81      private File jadFile = null;
82  
83      // is the JAD file a JAM file? (used by NTT DoCoMo's iMode)
84      private boolean isJam = false;
85      private String separator = JAD_SEPARATOR;
86  
87      public Jad() {
88      }
89  
90      public synchronized void setJad(File jadFile) {
91          this.jadFile = jadFile;
92      }
93  
94      public synchronized void setJar(File jarFile) {
95          this.jarFile = jarFile;
96      }
97  
98      public synchronized void execute() throws BuildException {
99          try {
100             tryExecute();
101         } catch (IOException ex) {
102             throw new BuildException(ex);
103         }
104     }
105 
106     private void tryExecute() throws IOException {
107 
108         if (!jarFile.exists()) {
109             throw new BuildException("Cannot find JAR file: " + 
110                                      jarFile.getName());
111         }
112 
113         if (!jadFile.canRead()) {
114             throw new BuildException("Cannot read JAD file: " + 
115                                      jadFile.getName());
116         }
117 
118         if (!jadFile.canWrite()) {
119             throw new BuildException("Cannot write to JAD file: " + 
120                                      jadFile.getName());
121         }
122 
123 	String jadFileExt = jadFile.getName().toLowerCase();
124 	if (jadFileExt.endsWith("jam")) {
125 	    isJam = true;
126 	    separator = JAM_SEPARATOR;
127 	}
128 
129         Hashtable map = new Hashtable();
130         Vector keys = new Vector();
131 
132         FileReader fileReader = new FileReader(jadFile);
133         BufferedReader br = new BufferedReader(fileReader);
134         try {
135             for (String line = br.readLine(); 
136                  line != null; 
137                  line = br.readLine()) {
138                 int colon = line.indexOf(separator);
139                 if (colon < 0) {
140                     throw new BuildException("Garbled JAD: missing '" +
141 					     separator + "' in " + line);
142                 }
143                 String key = line.substring(0, colon).trim();
144                 String value = line.substring(colon + 1).trim();
145                 putInOrder(key, value, map, keys);
146             }
147         } finally {
148             br.close();
149         }
150 
151         // update or insert if missing
152 	if (isJam) {
153 	    putInOrder("AppSize", Long.toString(jarFile.length()),
154 		       map, keys);
155 
156 	    // iMode needs a "LastModified" entry in the JAM file
157 	    Date now = new Date();
158 	    // the specific time format for iMode
159 	    // Locale.US is convenient to avoid kanji-characters representing a day of week.
160 	    SimpleDateFormat df = 
161 		new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", java.util.Locale.US);
162 	    putInOrder("LastModified", df.format(now), map, keys);
163 	} else {
164 	    putInOrder("MIDlet-Jar-Size", Long.toString(jarFile.length()),
165 		       map, keys);
166 	}
167 
168         FileWriter fileWriter = new FileWriter(jadFile);
169         BufferedWriter bw = new BufferedWriter(fileWriter);
170         try {
171             int keySize = keys.size();
172             for (int i=0; i < keySize; i++) {
173                 String key = (String) keys.elementAt(i);
174                 String value = (String) map.get(key);
175                 bw.write(key);
176                 bw.write(separator + " ");
177                 bw.write(value);
178                 bw.newLine();
179             }
180         } finally {
181             bw.close();
182         }
183     }
184 
185     /*** Update value or insert if missing. Preserves insertion order. */
186     private void putInOrder(Object key, Object value, 
187                             Hashtable map, Vector keys) {
188         if (map.put(key, value) == null) {
189             keys.addElement(key);
190         }
191     }
192 }