1   /*
2    * Copyright (C) The MetaClass Group. All rights reserved.
3    *
4    * This software is published under the terms of the Spice
5    * Software License version 1.1, a copy of which has been included
6    * with this distribution in the LICENSE.txt file.
7    */
8   package org.codehaus.metaclass.tools.compiler;
9   
10  import java.io.ByteArrayInputStream;
11  import java.io.File;
12  import java.io.FileInputStream;
13  import java.io.FileOutputStream;
14  import java.io.IOException;
15  import junit.framework.TestCase;
16  import org.codehaus.metaclass.io.MetaClassIOBinary;
17  import org.codehaus.metaclass.model.Attribute;
18  import org.codehaus.metaclass.model.ClassDescriptor;
19  import org.codehaus.metaclass.model.FieldDescriptor;
20  import org.codehaus.metaclass.model.MethodDescriptor;
21  import org.codehaus.metaclass.tools.qdox.DefaultQDoxAttributeInterceptor;
22  import org.codehaus.metaclass.tools.qdox.DeletingAttributeInterceptor;
23  
24  /***
25   * @author Peter Donald
26   * @version $Revision: 1.11 $ $Date: 2003/12/11 08:41:51 $
27   */
28  public class ClassDescriptorCompilerTestCase
29      extends TestCase
30  {
31      public void testNonNullInShutdownInputStream()
32          throws Exception
33      {
34          final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
35          task.shutdownStream( new ByteArrayInputStream( new byte[ 0 ] ) );
36      }
37  
38      public void testSetNullMonitor()
39          throws Exception
40      {
41          final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
42          try
43          {
44              task.setMonitor( null );
45          }
46          catch( final NullPointerException npe )
47          {
48              assertEquals( "npe.message", "monitor", npe.getMessage() );
49              return;
50          }
51          fail( "Expected to fail due to npe" );
52      }
53  
54      public void testAddNullSourceFile()
55          throws Exception
56      {
57          final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
58          try
59          {
60              task.addSourceFile( null );
61          }
62          catch( final NullPointerException npe )
63          {
64              assertEquals( "npe.message", "sourceFile", npe.getMessage() );
65              return;
66          }
67          fail( "Expected to fail due to npe" );
68      }
69  
70      public void testAddNullFilter()
71          throws Exception
72      {
73          final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
74          try
75          {
76              task.addFilter( null );
77          }
78          catch( final NullPointerException npe )
79          {
80              assertEquals( "npe.message", "filter", npe.getMessage() );
81              return;
82          }
83          fail( "Expected to fail due to npe" );
84      }
85  
86      public void testAddNullInterceptor()
87          throws Exception
88      {
89          final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
90          try
91          {
92              task.addInterceptor( null );
93          }
94          catch( final NullPointerException npe )
95          {
96              assertEquals( "npe.message", "interceptor", npe.getMessage() );
97              return;
98          }
99          fail( "Expected to fail due to npe" );
100     }
101 
102     public void testSetMetaClassIO()
103         throws Exception
104     {
105         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
106         try
107         {
108             task.setMetaClassIO( null );
109         }
110         catch( final NullPointerException npe )
111         {
112             assertEquals( "npe.message", "metaClassIO", npe.getMessage() );
113             return;
114         }
115         fail( "Expected to fail due to npe" );
116     }
117 
118     public void testFailToWriteClassDescriptors()
119         throws Exception
120     {
121         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
122         final MockMonitor mockMonitor = new MockMonitor();
123         task.setMonitor( mockMonitor );
124         task.setMetaClassIO( new MockIO() );
125         task.setDestDir( generateDirectory() );
126         final ClassDescriptor descriptor =
127             new ClassDescriptor( "test",
128                                  Attribute.EMPTY_SET,
129                                  Attribute.EMPTY_SET,
130                                  FieldDescriptor.EMPTY_SET,
131                                  MethodDescriptor.EMPTY_SET );
132         task.writeClassDescriptor( descriptor );
133         assertTrue( "error writing descriptor", mockMonitor.isError() );
134     }
135 
136     public void testNullDestDir()
137         throws Exception
138     {
139         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
140         try
141         {
142             task.execute();
143         }
144         catch( final Exception e )
145         {
146             assertEquals( "DestDir not specified", e.getMessage() );
147             return;
148         }
149         fail( "Expected execute to fail as no destdir specified." );
150     }
151 
152     public void testFileAsDestDir()
153         throws Exception
154     {
155         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
156         final File baseDirectory = getBaseDirectory();
157         final File destDir =
158             File.createTempFile( "mgtest", ".tmp", baseDirectory )
159             .getCanonicalFile();
160         task.setDestDir( destDir );
161         try
162         {
163             task.execute();
164         }
165         catch( final Exception e )
166         {
167             assertEquals( "DestDir (" + destDir + ") is not a directory.",
168                           e.getMessage() );
169             return;
170         }
171         fail( "Expected execute to fail as destdir specified by file." );
172     }
173 
174     public void testDestDirNoExistAndNoCreate()
175         throws Exception
176     {
177         if( -1 != System.getProperty( "os.name" ).indexOf( "Windows" ) )
178         {
179             //Read-Only directorys still allow java to write
180             //to them under windows
181             return;
182         }
183         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
184         final File baseDirectory = getBaseDirectory();
185         final File secondBaseDir = new File( baseDirectory, "subDir1" );
186         secondBaseDir.mkdirs();
187         secondBaseDir.setReadOnly();
188         final File destDir = new File( secondBaseDir, "subDir" );
189         assertFalse( "destDir.exists()", destDir.exists() );
190 
191         task.setDestDir( destDir );
192         try
193         {
194             task.execute();
195         }
196         catch( final Exception e )
197         {
198             assertEquals( "DestDir (" + destDir + ") could not be created.",
199                           e.getMessage() );
200             return;
201         }
202         fail( "Expected execute to fail as destdir could not be created." );
203     }
204 
205     public void testNoSourceFiles()
206         throws Exception
207     {
208         final File destDirectory = generateDirectory();
209 
210         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
211         task.setDestDir( destDirectory );
212         task.execute();
213 
214         assertEquals( "generated dirs", 0, destDirectory.listFiles().length );
215     }
216 
217     public void testSingleSourceFile()
218         throws Exception
219     {
220         final String source =
221             "package com.biz;\n" +
222             "\n" +
223             "/**\n" +
224             " * @anAttribute\n" +
225             " */\n" +
226             "public class MyClass\n" +
227             "{\n" +
228             "}\n";
229 
230         final File sourceDirectory = generateDirectory();
231         final File destDirectory = generateDirectory();
232 
233         final String sourceFilename =
234             sourceDirectory +
235             File.separator +
236             "com" +
237             File.separator +
238             "biz" +
239             File.separator +
240             "MyClass.java";
241         final File sourceFile = new File( sourceFilename );
242         sourceFile.getParentFile().mkdirs();
243         final FileOutputStream output = new FileOutputStream( sourceFile );
244         output.write( source.getBytes() );
245         output.close();
246 
247         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
248         task.setDestDir( destDirectory );
249         task.addSourceFile( sourceFile );
250         task.setMetaClassIO( new MetaClassIOBinary() );
251         task.execute();
252         final String destFilename =
253             destDirectory +
254             File.separator +
255             "com" +
256             File.separator +
257             "biz" +
258             File.separator +
259             "MyClass" +
260             MetaClassIOBinary.EXTENSION;
261         final File destFile = new File( destFilename );
262 
263         assertTrue( "destFile.exists()", destFile.exists() );
264         final MetaClassIOBinary io = new MetaClassIOBinary();
265         final FileInputStream input = new FileInputStream( destFile );
266         final ClassDescriptor descriptor = io.deserializeClass( input );
267         assertEquals( "descriptor.name",
268                       "com.biz.MyClass",
269                       descriptor.getName() );
270         assertEquals( "descriptor.attributes.length",
271                       1,
272                       descriptor.getAttributes().length );
273         assertEquals( "descriptor.attributes[0].name",
274                       "anAttribute",
275                       descriptor.getAttributes()[ 0 ].getName() );
276         assertEquals( "descriptor.methods.length",
277                       0,
278                       descriptor.getMethods().length );
279         assertEquals( "descriptor.fields.length",
280                       0,
281                       descriptor.getFields().length );
282     }
283 
284     public void testSingleSourceFileInWrongDirectory()
285         throws Exception
286     {
287         final String source =
288             "package com.biz;\n" +
289             "\n" +
290             "/**\n" +
291             " * @anAttribute\n" +
292             " */\n" +
293             "public class MyClass\n" +
294             "{\n" +
295             "}\n";
296 
297         final File sourceDirectory = generateDirectory();
298         final File destDirectory = generateDirectory();
299 
300         final String sourceFilename =
301             sourceDirectory +
302             File.separator +
303             "com" +
304             File.separator +
305             "MyClass.java";
306         final File sourceFile = new File( sourceFilename );
307         sourceFile.getParentFile().mkdirs();
308         final FileOutputStream output = new FileOutputStream( sourceFile );
309         output.write( source.getBytes() );
310         output.close();
311 
312         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
313         task.setDestDir( destDirectory );
314         task.addSourceFile( sourceFile );
315         task.setMetaClassIO( new MetaClassIOBinary() );
316         task.execute();
317         final String destFilename =
318             destDirectory +
319             File.separator +
320             "com" +
321             File.separator +
322             "biz" +
323             File.separator +
324             "MyClass" +
325             MetaClassIOBinary.EXTENSION;
326         final File destFile = new File( destFilename );
327 
328         assertTrue( "destFile.exists()", destFile.exists() );
329         final MetaClassIOBinary io = new MetaClassIOBinary();
330         final FileInputStream input = new FileInputStream( destFile );
331         final ClassDescriptor descriptor = io.deserializeClass( input );
332         assertEquals( "descriptor.name",
333                       "com.biz.MyClass",
334                       descriptor.getName() );
335         assertEquals( "descriptor.attributes.length",
336                       1,
337                       descriptor.getAttributes().length );
338         assertEquals( "descriptor.attributes[0].name",
339                       "anAttribute",
340                       descriptor.getAttributes()[ 0 ].getName() );
341         assertEquals( "descriptor.methods.length",
342                       0,
343                       descriptor.getMethods().length );
344         assertEquals( "descriptor.fields.length",
345                       0,
346                       descriptor.getFields().length );
347     }
348 
349     public void testNonExistentSourceFile()
350         throws Exception
351     {
352         final File destDirectory = generateDirectory();
353 
354         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
355         task.setDestDir( destDirectory );
356         task.addSourceFile( new File( "noExist.txt" ) );
357         task.setMetaClassIO( new MetaClassIOBinary() );
358         final MockMonitor monitor = new MockMonitor();
359         task.setMonitor( monitor );
360         task.execute();
361         assertEquals( true, monitor.isError() );
362     }
363 
364     public void testSingleSourceFileWithPassThroughInterceptor()
365         throws Exception
366     {
367         final String source =
368             "package com.biz;\n" +
369             "\n" +
370             "/**\n" +
371             " * @anAttribute\n" +
372             " */\n" +
373             "public class MyClass\n" +
374             "{\n" +
375             "}\n";
376 
377         final File sourceDirectory = generateDirectory();
378         final File destDirectory = generateDirectory();
379 
380         final String sourceFilename =
381             sourceDirectory +
382             File.separator +
383             "com" +
384             File.separator +
385             "biz" +
386             File.separator +
387             "MyClass.java";
388         final File sourceFile = new File( sourceFilename );
389         sourceFile.getParentFile().mkdirs();
390         final FileOutputStream output = new FileOutputStream( sourceFile );
391         output.write( source.getBytes() );
392         output.close();
393 
394         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
395         task.setDestDir( destDirectory );
396         task.addSourceFile( sourceFile );
397         task.addInterceptor( new DefaultQDoxAttributeInterceptor() );
398         task.setMetaClassIO( new MetaClassIOBinary() );
399         task.execute();
400         final String destFilename =
401             destDirectory +
402             File.separator +
403             "com" +
404             File.separator +
405             "biz" +
406             File.separator +
407             "MyClass" +
408             MetaClassIOBinary.EXTENSION;
409         final File destFile = new File( destFilename );
410 
411         assertTrue( "destFile.exists()", destFile.exists() );
412         final MetaClassIOBinary io = new MetaClassIOBinary();
413         final FileInputStream input = new FileInputStream( destFile );
414         final ClassDescriptor descriptor = io.deserializeClass( input );
415         assertEquals( "descriptor.name",
416                       "com.biz.MyClass",
417                       descriptor.getName() );
418         assertEquals( "descriptor.attributes.length",
419                       1,
420                       descriptor.getAttributes().length );
421         assertEquals( "descriptor.attributes[0].name",
422                       "anAttribute",
423                       descriptor.getAttributes()[ 0 ].getName() );
424         assertEquals( "descriptor.methods.length",
425                       0,
426                       descriptor.getMethods().length );
427         assertEquals( "descriptor.fields.length",
428                       0,
429                       descriptor.getFields().length );
430     }
431 
432     public void testSingleSourceFileWithExceptingInterceptor()
433         throws Exception
434     {
435         final String source =
436             "package com.biz;\n" +
437             "\n" +
438             "/**\n" +
439             " * @anAttribute\n" +
440             " */\n" +
441             "public class MyClass\n" +
442             "{\n" +
443             "}\n";
444 
445         final File sourceDirectory = generateDirectory();
446         final File destDirectory = generateDirectory();
447 
448         final String sourceFilename =
449             sourceDirectory +
450             File.separator +
451             "com" +
452             File.separator +
453             "biz" +
454             File.separator +
455             "MyClass.java";
456         final File sourceFile = new File( sourceFilename );
457         sourceFile.getParentFile().mkdirs();
458         final FileOutputStream output = new FileOutputStream( sourceFile );
459         output.write( source.getBytes() );
460         output.close();
461 
462         final ClassDescriptorCompiler compiler = new ClassDescriptorCompiler();
463         compiler.setDestDir( destDirectory );
464         compiler.addSourceFile( sourceFile );
465         final MockMonitor monitor = new MockMonitor();
466         compiler.setMonitor( monitor );
467         compiler.addInterceptor( new ExceptingInterceptor() );
468         compiler.setMetaClassIO( new MetaClassIOBinary() );
469         compiler.execute();
470         final String destFilename =
471             destDirectory +
472             File.separator +
473             "com" +
474             File.separator +
475             "biz" +
476             File.separator +
477             "MyClass" +
478             MetaClassIOBinary.EXTENSION;
479         final File destFile = new File( destFilename );
480 
481         assertTrue( "destFile.exists()", !destFile.exists() );
482         assertTrue( "monitor.isError()", monitor.isError() );
483     }
484 
485     public void testSingleSourceFileWithDeletingInterceptor()
486         throws Exception
487     {
488         final String source =
489             "package com.biz;\n" +
490             "\n" +
491             "/**\n" +
492             " * @anAttribute\n" +
493             " * @deleteme\n" +
494             " */\n" +
495             "public class MyClass\n" +
496             "{\n" +
497             "}\n";
498 
499         final File sourceDirectory = generateDirectory();
500         final File destDirectory = generateDirectory();
501 
502         final String sourceFilename =
503             sourceDirectory +
504             File.separator +
505             "com" +
506             File.separator +
507             "biz" +
508             File.separator +
509             "MyClass.java";
510         final File sourceFile = new File( sourceFilename );
511         sourceFile.getParentFile().mkdirs();
512         final FileOutputStream output = new FileOutputStream( sourceFile );
513         output.write( source.getBytes() );
514         output.close();
515 
516         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
517         task.setDestDir( destDirectory );
518         task.addSourceFile( sourceFile );
519         task.addInterceptor( new DeletingAttributeInterceptor() );
520         task.setMetaClassIO( new MetaClassIOBinary() );
521         task.execute();
522         final String destFilename =
523             destDirectory +
524             File.separator +
525             "com" +
526             File.separator +
527             "biz" +
528             File.separator +
529             "MyClass" +
530             MetaClassIOBinary.EXTENSION;
531         final File destFile = new File( destFilename );
532 
533         assertTrue( "destFile.exists()", destFile.exists() );
534         final MetaClassIOBinary io = new MetaClassIOBinary();
535         final FileInputStream input = new FileInputStream( destFile );
536         final ClassDescriptor descriptor = io.deserializeClass( input );
537         assertEquals( "descriptor.name",
538                       "com.biz.MyClass",
539                       descriptor.getName() );
540         assertEquals( "descriptor.attributes.length",
541                       1,
542                       descriptor.getAttributes().length );
543         assertEquals( "descriptor.attributes[0].name",
544                       "anAttribute",
545                       descriptor.getAttributes()[ 0 ].getName() );
546         assertEquals( "descriptor.methods.length",
547                       0,
548                       descriptor.getMethods().length );
549         assertEquals( "descriptor.fields.length",
550                       0,
551                       descriptor.getFields().length );
552     }
553 
554     public void testSingleSourceFileWithDeletingFilter()
555         throws Exception
556     {
557         final String source =
558             "package com.biz;\n" +
559             "\n" +
560             "/**\n" +
561             " * @anAttribute\n" +
562             " * @deleteme\n" +
563             " */\n" +
564             "public class MyClass\n" +
565             "{\n" +
566             "}\n";
567 
568         final File sourceDirectory = generateDirectory();
569         final File destDirectory = generateDirectory();
570 
571         final String sourceFilename =
572             sourceDirectory +
573             File.separator +
574             "com" +
575             File.separator +
576             "biz" +
577             File.separator +
578             "MyClass.java";
579         final File sourceFile = new File( sourceFilename );
580         sourceFile.getParentFile().mkdirs();
581         final FileOutputStream output = new FileOutputStream( sourceFile );
582         output.write( source.getBytes() );
583         output.close();
584 
585         final ClassDescriptorCompiler task = new ClassDescriptorCompiler();
586         task.setDestDir( destDirectory );
587         task.addSourceFile( sourceFile );
588         task.addInterceptor( new DeletingAttributeInterceptor() );
589         task.addFilter( new DeletingFilter() );
590         task.setMetaClassIO( new MetaClassIOBinary() );
591         task.execute();
592         final String destFilename =
593             destDirectory +
594             File.separator +
595             "com" +
596             File.separator +
597             "biz" +
598             File.separator +
599             "MyClass" +
600             MetaClassIOBinary.EXTENSION;
601         final File destFile = new File( destFilename );
602 
603         assertTrue( "!destFile.exists()", !destFile.exists() );
604     }
605 
606     private static final File generateDirectory()
607         throws IOException
608     {
609         final File baseDirectory = getBaseDirectory();
610         final File dir =
611             File.createTempFile( "mgtest", ".tmp", baseDirectory )
612             .getCanonicalFile();
613         dir.delete();
614         dir.mkdirs();
615         assertTrue( "dir.exists()", dir.exists() );
616         return dir;
617     }
618 
619     private static final File getBaseDirectory()
620     {
621         final String tempDir = System.getProperty( "java.io.tmpdir" );
622         final String baseDir = System.getProperty( "basedir", tempDir );
623 
624         final File base = new File( baseDir ).getAbsoluteFile();
625         final String pathname =
626             base + File.separator + "target" + File.separator + "test-data";
627         final File dir = new File( pathname );
628         dir.mkdirs();
629         return dir;
630     }
631 }