View Javadoc

1   /*
2    * Copyright (c) 2001-2005,
3    * RedVerst Group, ISP RAS http://www.ispras.ru
4    * All rights reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions are met:
8    *
9    * 1. Redistributions of source code must retain the above copyright notice, this
10   *    list of conditions and the following disclaimer.
11   *
12   * 2. Redistributions in binary form must reproduce the above copyright notice,
13   *    this list of conditions and the following disclaimer in the documentation
14   *    and/or other materials provided with the distribution.
15   *
16   * 3. The names "ATP", "TreeDL", "RedVerst", "ISP RAS"
17   *    may not be used to endorse or promote products derived from this software
18   *    without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  
32  package com.unitesk.atp.treedl;
33  
34  import java.io.File;
35  import java.util.StringTokenizer;
36  
37  import com.unitesk.atp.dynattrs.Accessor;
38  import com.unitesk.atp.text.generation.DefaultFunction;
39  import com.unitesk.atp.tool.Tool;
40  import com.unitesk.atp.treedl.TDL.*;
41  
42  /*
43   * Auxilary methods for java text generation
44   *
45   * @author <A href="mailto:demakov@ispras.ru">Alexey Demakov</A>
46   * @version $Id: JavaTextGenerator.java,v 1.17 2005/09/08 16:19:43 all-x Exp $
47   */
48  public abstract class JavaTextGenerator extends TextGenerator
49  {
50      private static StringBuffer sb = new StringBuffer();
51      
52      public synchronized static String getOutFileName( String outputDir, String outClassName )
53      {
54          String separator = System.getProperty( "file.separator" );
55  
56          StringTokenizer st = new StringTokenizer( outClassName, "." );
57          sb.setLength(0);
58          sb.append( outputDir );
59          while( st.hasMoreTokens() )
60          {
61              sb.append( separator );
62              sb.append( st.nextToken() );
63          }
64  
65          return sb.toString();
66      }
67      
68      public void setOutDir( String outDir )
69      {
70          setOutFile( new File( getOutFileName( outDir, getOutClassName() ) + ".java" ) );
71      }    
72  
73      /*
74       * capitalized field name
75       */
76      public class NameFunction extends DefaultFunction
77      {
78          /*
79           * arg is ID
80           */
81          public void process( Object arg )
82          {
83              generator.txtAsIs(
84                  Accessor.capitalize( ((ID)arg).getValue() )
85              );
86          }
87      }
88  
89      /*
90       * list type -> element type
91       */
92      public class ElementTypeFunction extends DefaultFunction
93      {
94          public void process( Object arg )
95          {
96              Object oldVar = generator.setVariable( "", arg );
97              try
98              {
99                  if( arg instanceof NodeType )
100                 {
101                     generator.txt( "${type}" );
102                 } else
103                 if( arg instanceof NameType )
104                 {
105                     generator.txt( "${name}" );
106                 } else
107                 if( arg instanceof PredefinedType )
108                 {
109                     generator.txt( "${PredefinedTypeName:kind}" );
110                 } else {
111                     throw new ClassCastException( arg.toString() );
112                 }
113             }
114             finally
115             {
116                 generator.setVariable( "", oldVar );
117             }
118         }
119     }
120 
121     /*
122      * list type with elements of primitive type -> 
123      * reference type for element type
124      */
125     public class ElementObjectTypeFunction extends DefaultFunction
126     {
127         public void process( Object arg )
128         {
129             if( arg instanceof NameType )
130             {
131                 String name = JavaLanguageDescription.normalizeType
132                                   ( ((NameType)arg).getName() );                
133                 if( name.equals( "int" ) )
134                 {
135                     generator.txtAsIs( "Integer" );
136                 } else
137                 if( name.equals( "char" ) )
138                 {
139                     generator.txtAsIs( "Character" );
140                 } else {
141                     generator.txtAsIs( Accessor.capitalize( name ) );
142                 }
143             } else
144             if( arg instanceof PredefinedType )
145             {
146                 switch( ((PredefinedType)arg).getKind().key() )
147                 {
148                 case PredefinedTypeKind.Key.BOOL:
149                     generator.txtAsIs( "Boolean" );
150                     break;
151                 case PredefinedTypeKind.Key.CHAR:
152                     generator.txtAsIs( "Character" );
153                     break;
154                 case PredefinedTypeKind.Key.SHORT:
155                     generator.txtAsIs( "Short" );
156                     break;
157                 case PredefinedTypeKind.Key.INT:
158                     generator.txtAsIs( "Integer" );
159                     break;
160                 case PredefinedTypeKind.Key.LONG:
161                     generator.txtAsIs( "Long" );
162                     break;
163                 case PredefinedTypeKind.Key.FLOAT:
164                     generator.txtAsIs( "Float" );
165                     break;
166                 case PredefinedTypeKind.Key.DOUBLE:
167                     generator.txtAsIs( "Double" );
168                     break;
169                 default:
170                     throw new IllegalArgumentException
171                               ( "PredefinedTypeKind = " +arg );
172                 }
173             } else {
174                 throw new ClassCastException( arg.toString() );
175             }
176         }
177     }
178     
179     public class PredefinedTypeNameFunction extends DefaultFunction
180     {
181         public void process( Object arg )
182         {
183             switch( ((PredefinedTypeKind)arg).key() )
184             {
185             case PredefinedTypeKind.Key.OBJECT:
186                 generator.txtAsIs( "Object" );
187                 break;
188             case PredefinedTypeKind.Key.BOOL:
189                 generator.txtAsIs( "boolean" );
190                 break;
191             case PredefinedTypeKind.Key.STRING:
192                 generator.txtAsIs( "String" );
193                 break;
194             case PredefinedTypeKind.Key.CHAR:
195                 generator.txtAsIs( "char" );
196                 break;
197             case PredefinedTypeKind.Key.SHORT:
198                 generator.txtAsIs( "short" );
199                 break;
200             case PredefinedTypeKind.Key.INT:
201                 generator.txtAsIs( "int" );
202                 break;
203             case PredefinedTypeKind.Key.LONG:
204                 generator.txtAsIs( "long" );
205                 break;
206             case PredefinedTypeKind.Key.FLOAT:
207                 generator.txtAsIs( "float" );
208                 break;
209             case PredefinedTypeKind.Key.DOUBLE:
210                 generator.txtAsIs( "double" );
211                 break;
212             default:
213                 throw new IllegalArgumentException
214                           ( "PredefinedTypeKind = " +arg );
215             }
216         }
217     }
218 
219     protected void block()
220     {
221         txt( "{" );
222         incIndent();
223     }
224 
225     protected void unblock()
226     {
227         popIndent();
228         txt( "}" );
229     }
230 
231     protected void block_nl()
232     {
233         block(); nl();
234     }
235 
236     protected void unblock_nl()
237     {
238         unblock(); nl();
239     }
240 
241     protected void generateHeader()
242     {
243         setVariable( "pm", pm );
244         setVariable( "generator", this );
245 
246         txt( "// Generated by ${.pm.name}" ); txtif( pm instanceof Tool, ", version ${.pm.version}" ); nl();
247         txt( "// using generator ${.generator.name} = ${.generator.class.name}, version ${.generator.version}" ); nl();
248         txt( "// from file: ${.generator.module.file.name}" ); nl();
249         nl();
250 
251         setVariable( "pm", null );
252         setVariable( "generator", null );
253         
254         setVariable( "EnumClass", "com.unitesk.atp.tree.TreeClass.EnumClass" );
255         setVariable( "Node", "com.unitesk.atp.tree.Node" );
256         setVariable( "Visitor", "com.unitesk.atp.tree.Visitor" );
257         setVariable( "Keyed", "com.unitesk.atp.tree.Keyed" );
258     }
259 
260     public void visitNodeType( NodeType node )
261     {
262         txtif( node.checkCardinality( Cardinality.LIST )
263              , "java.util.List/*${type}*/"
264              , "${type}" 
265              );
266     }
267 
268     public void visitPredefinedType( PredefinedType node )
269     {
270         txtif( node.checkCardinality( Cardinality.LIST )
271              , "java.util.List/*${PredefinedTypeName:kind}*/"
272              , "${PredefinedTypeName:kind}" 
273              );
274     }
275 
276     public void visitNameType( NameType node )
277     {
278         txtif( node.checkCardinality( Cardinality.LIST )
279              ,   "java.util.List/*"
280                    // remove nested comments
281                  + JavaLanguageDescription.normalizeType( node.getName() )
282                  + "*/"
283              , "${name}" 
284              );
285     }
286 
287     public void visitTypeRef( TypeRef node )
288     {
289         if( node.getType() == TDL_Module.getRootNodeType() )
290         {
291             txt( "${.Node}" );
292         } else {
293             txtif( node.getModule() != module, "${module.root.name}." );
294             txt( "${name}" );
295         }
296     }
297 
298     public void visitOperationRef( OperationRef node )
299     {
300         txtif( node.getModule() != module, "${module.root.name}." );
301         txt( "${name}" );
302     }
303 
304     public void visitID( ID node )
305     {
306         txt( "${value}" );
307     }
308 
309     public void visitQID( QID node )
310     {
311         txt( "${value}" );
312     }
313 
314     public void visitCode( Code node )
315     {
316         txt( "${code}" );
317     }
318 }