KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > dotnet > Ildasm


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.optional.dotnet;
19
20 import org.apache.tools.ant.types.EnumeratedAttribute;
21 import org.apache.tools.ant.BuildException;
22 import org.apache.tools.ant.Task;
23 import org.apache.tools.ant.Project;
24 import org.apache.tools.ant.util.FileUtils;
25
26 import java.io.File JavaDoc;
27
28 /**
29  * Task to take a .NET or Mono -generated managed executable and turn it
30  * into ILASM assembly code. Useful when converting imported typelibs into
31  * assembler before patching and recompiling, as one has to do when doing
32  * advanced typelib work.
33  * <p>
34  * As well as generating the named output file, the ildasm program
35  * will also generate resource files <code>Icons.resources</code>
36  * <code>Message.resources</code> and a .res file whose filename stub is derived
37  * from the source in ways to obscure to determine.
38  * There is no way to control whether or not these files are created, or where they are created
39  * (they are created in the current directory; their names come from inside the
40  * executable and may be those used by the original developer). This task
41  * creates the resources in the directory specified by <code>resourceDir</code> if
42  * set, else in the same directory as the <code>destFile</code>.
43  *
44  * <p>
45  * This task requires the .NET SDK installed and ildasm on the path.
46  * To disassemble using alternate CLR systems, set the executable attribute
47  * to the name/path of the alternate implementation -one that must
48  * support all the classic ildasm commands.
49  *
50  * <p>
51  * Dependency logic: the task executes the command if the output file is missing
52  * or older than the source file. It does not take into account changes
53  * in the options of the task, or timestamp differences in resource files.
54  * When the underlying ildasm executable fails for some reason, it leaves the
55  * .il file in place with some error message. To prevent this from confusing
56  * the dependency logic, the file specified by the <code>dest</code>
57  * attribute is <i>always</i> deleted after an unsuccessful build.
58  * @ant.task category="dotnet"
59  */

60 public class Ildasm extends Task {
61
62     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
63
64     /**
65      * source file (mandatory)
66      */

67     private File JavaDoc sourceFile;
68
69     /**
70      * dest file (mandatory)
71      */

72     private File JavaDoc destFile;
73     /**
74      * progress bar switch
75      */

76     private boolean progressBar = false;
77
78     /**
79      * what is our encoding
80      */

81     private String JavaDoc encoding;
82
83     /**
84      * /bytes flag for byte markup
85      */

86
87     private boolean bytes = false;
88
89     /**
90      * line numbers? /linenum
91      */

92     private boolean linenumbers = false;
93
94     /**
95      * /raweh flag for raw exception handling
96      */

97     private boolean rawExceptionHandling = false;
98
99     /**
100      * show the source; /source
101      */

102     private boolean showSource = false;
103
104     /**
105      * /quoteallnames to quote all names
106      */

107     private boolean quoteallnames = false;
108
109     /**
110      * /header for header information
111      */

112     private boolean header = false;
113
114     /**
115      * when false, sets the /noil attribute
116      * to suppress assembly info
117      */

118     private boolean assembler = true;
119
120     /**
121      * include metadata
122      * /tokens
123      */

124
125     private boolean metadata = false;
126
127     /**
128      * what visibility do we want.
129      *
130      */

131     private String JavaDoc visibility;
132
133     /**
134      * specific item to disassemble
135      */

136
137     private String JavaDoc item;
138
139     /**
140      * override for the executable
141      */

142     private String JavaDoc executable = "ildasm";
143
144     /**
145      * name of the directory for resources to be created. We cannot control
146      * their names, but we can say where they get created. If not set, the
147      * directory of the dest file is used
148      */

149     private File JavaDoc resourceDir;
150
151
152     /**
153      * Set the name of the directory for resources to be created. We cannot control
154      * their names, but we can say where they get created. If not set, the
155      * directory of the dest file is used
156      * @param resourceDir the directory in which to create resources.
157      */

158     public void setResourceDir(File JavaDoc resourceDir) {
159         this.resourceDir = resourceDir;
160     }
161
162     /**
163      * override the name of the executable (normally ildasm) or set
164      * its full path. Do not set a relative path, as the ugly hacks
165      * needed to create resource files in the dest directory
166      * force us to change to this directory before running the application.
167      * i.e use &lt;property location&gt to create an absolute path from a
168      * relative one before setting this value.
169      * @param executable the name of the executable to use.
170      */

171     public void setExecutable(String JavaDoc executable) {
172         this.executable = executable;
173     }
174
175     /**
176      * Select the output encoding: ascii, utf8 or unicode
177      * @param encoding the enumerated value.
178      */

179     public void setEncoding(EncodingTypes encoding) {
180         this.encoding = encoding.getValue();
181     }
182
183     /**
184      * enable (default) or disable assembly language in the output
185      * @param assembler a <code>boolean</code> value.
186      */

187     public void setAssembler(boolean assembler) {
188         this.assembler = assembler;
189     }
190
191     /**
192      * enable or disable (default) the original bytes as comments
193      * @param bytes a <code>boolean</code> value.
194      */

195     public void setBytes(boolean bytes) {
196         this.bytes = bytes;
197     }
198
199     /**
200      * the output file (required)
201      * @param destFile the destination file.
202      */

203     public void setDestFile(File JavaDoc destFile) {
204         this.destFile = destFile;
205     }
206
207     /**
208      * include header information; default false.
209      * @param header a <code>boolean</code> value.
210      */

211     public void setHeader(boolean header) {
212         this.header = header;
213     }
214
215     /**
216      * name a single item to decode; a class or a method
217      * e.g item="Myclass::method" or item="namespace1::namespace2::Myclass:method(void(int32))
218      * @param item the item to decode.
219      */

220     public void setItem(String JavaDoc item) {
221         this.item = item;
222     }
223
224     /**
225      * include line number information; default=false
226      * @param linenumbers a <code>boolean</code> value.
227      */

228     public void setLinenumbers(boolean linenumbers) {
229         this.linenumbers = linenumbers;
230     }
231
232     /**
233      * include metadata information
234      * @param metadata a <code>boolean</code> value.
235      */

236     public void setMetadata(boolean metadata) {
237         this.metadata = metadata;
238     }
239
240     /**
241      * show a graphical progress bar in a window during the process; off by default
242      * @param progressBar a <code>boolean</code> value.
243      */

244     public void setProgressBar(boolean progressBar) {
245         this.progressBar = progressBar;
246     }
247
248     /**
249      * quote all names.
250      * @param quoteallnames a <code>boolean</code> value.
251      */

252     public void setQuoteallnames(boolean quoteallnames) {
253         this.quoteallnames = quoteallnames;
254     }
255
256     /**
257      * enable raw exception handling (default = false)
258      * @param rawExceptionHandling a <code>boolean</code> value.
259      */

260     public void setRawExceptionHandling(boolean rawExceptionHandling) {
261         this.rawExceptionHandling = rawExceptionHandling;
262     }
263
264     /**
265      * include the source as comments (default=false)
266      * @param showSource a <code>boolean</code> value.
267      */

268     public void setShowSource(boolean showSource) {
269         this.showSource = showSource;
270     }
271
272     /**
273      * the file to disassemble -required
274      * @param sourceFile the file to disassemble.
275      */

276     public void setSourceFile(File JavaDoc sourceFile) {
277         this.sourceFile = sourceFile;
278     }
279
280     /**
281      * alternate name for sourceFile
282      * @param sourceFile the source file.
283      */

284     public void setSrcFile(File JavaDoc sourceFile) {
285         setSourceFile(sourceFile);
286     }
287     /**
288      * This method sets the visibility options. It chooses one
289      * or more of the following, with + signs to concatenate them:
290      * <pre>
291      * pub : Public
292      * pri : Private
293      * fam : Family
294      * asm : Assembly
295      * faa : Family and Assembly
296      * foa : Family or Assembly
297      * psc : Private Scope
298      *</pre>
299      * e.g. visibility="pub+pri".
300      * Family means <code>protected</code> in C#;
301      * @param visibility the options to use.
302      */

303     public void setVisibility(String JavaDoc visibility) {
304         this.visibility = visibility;
305     }
306
307     /**
308      * verify that source and dest are ok
309      */

310     private void validate() {
311         if (sourceFile == null || !sourceFile.exists() || !sourceFile.isFile()) {
312             throw new BuildException("invalid source");
313         }
314         if (destFile == null || destFile.isDirectory()) {
315             throw new BuildException("invalid dest");
316         }
317         if (resourceDir != null
318                 && (!resourceDir.exists() || !resourceDir.isDirectory())) {
319             throw new BuildException("invalid resource directory");
320         }
321     }
322
323     /**
324      * Test for disassembly being needed; use existence and granularity
325      * correct date stamps
326      * @return true iff a rebuild is required.
327      */

328     private boolean isDisassemblyNeeded() {
329         if (!destFile.exists()) {
330             log("Destination file does not exist: a build is required",
331                     Project.MSG_VERBOSE);
332             return true;
333         }
334         long sourceTime = sourceFile.lastModified();
335         long destTime = destFile.lastModified();
336         if (sourceTime > (destTime + FILE_UTILS.getFileTimestampGranularity())) {
337             log("Source file is newer than the dest file: a rebuild is required",
338                     Project.MSG_VERBOSE);
339             return true;
340         } else {
341             log("The .il file is up to date", Project.MSG_VERBOSE);
342             return false;
343         }
344
345     }
346     /**
347      * do the work
348      * @throws BuildException if there is an error.
349      */

350     public void execute() throws BuildException {
351         log("This task is deprecated and will be removed in a future version\n"
352             + "of Ant. It is now part of the .NET Antlib:\n"
353             + "http://ant.apache.org/antlibs/dotnet/index.html",
354             Project.MSG_WARN);
355         validate();
356         if (!isDisassemblyNeeded()) {
357             return;
358         }
359         NetCommand command = new NetCommand(this, "ildasm", executable);
360         command.setFailOnError(true);
361         //fill in args
362
command.addArgument("/text");
363         command.addArgument("/out=" + destFile.toString());
364         if (!progressBar) {
365             command.addArgument("/nobar");
366         }
367         if (linenumbers) {
368             command.addArgument("/linenum");
369         }
370         if (showSource) {
371             command.addArgument("/source");
372         }
373         if (quoteallnames) {
374             command.addArgument("/quoteallnames");
375         }
376         if (header) {
377             command.addArgument("/header");
378         }
379         if (!assembler) {
380             command.addArgument("/noil");
381         }
382         if (metadata) {
383             command.addArgument("/tokens");
384         }
385         command.addArgument("/item:", item);
386         if (rawExceptionHandling) {
387             command.addArgument("/raweh");
388         }
389         command.addArgument(EncodingTypes.getEncodingOption(encoding));
390         if (bytes) {
391             command.addArgument("/bytes");
392         }
393         command.addArgument("/vis:", visibility);
394
395         //add the source file
396
command.addArgument(sourceFile.getAbsolutePath());
397
398         //determine directory: resourceDir if set,
399
//the dir of the destFile if not
400
File JavaDoc execDir = resourceDir;
401         if (execDir == null) {
402             execDir = destFile.getParentFile();
403         }
404         command.setDirectory(execDir);
405
406         //now run
407
try {
408             command.runCommand();
409         } catch (BuildException e) {
410             //forcibly delete the output file in case of trouble
411
if (destFile.exists()) {
412                 log("Deleting destination file as it may be corrupt");
413                 destFile.delete();
414             }
415             //then rethrow the exception
416
throw e;
417         }
418
419     }
420
421     /**
422      * encoding options; the default is ascii
423      */

424     public static class EncodingTypes extends EnumeratedAttribute {
425         /** Unicode */
426         public static final String JavaDoc UNICODE = "unicode";
427         /** UTF8 */
428         public static final String JavaDoc UTF8 = "utf8";
429         /** ASCII */
430         public static final String JavaDoc ASCII = "ascii";
431         /** {@inheritDoc}. */
432         public String JavaDoc[] getValues() {
433             return new String JavaDoc[]{
434                 ASCII,
435                 UTF8,
436                 UNICODE,
437             };
438         }
439
440         /**
441          * This method maps from an encoding enum to an encoding option.
442          * @param enumValue the value to use.
443          * @return The encoding option indicated by the enum value.
444          */

445         public static String JavaDoc getEncodingOption(String JavaDoc enumValue) {
446             if (UNICODE.equals(enumValue)) {
447                 return "/unicode";
448             }
449             if (UTF8.equals(enumValue)) {
450                 return "/utf8";
451             }
452             return null;
453         }
454     }
455
456     /**
457      * visibility options for decoding
458      */

459     public static class VisibilityOptions extends EnumeratedAttribute {
460         /** {@inheritDoc}. */
461         public String JavaDoc[] getValues() {
462             return new String JavaDoc[]{
463                 "pub", //Public
464
"pri", //Private
465
"fam", //Family
466
"asm", //Assembly
467
"faa", //Family and Assembly
468
"foa", //Family or Assembly
469
"psc", //Private Scope
470
};
471         }
472
473     }
474 }
475
Popular Tags