~ubuntu-branches/ubuntu/maverick/eucalyptus/maverick

« back to all changes in this revision

Viewing changes to clc/modules/msgs/src/main/java/com/eucalyptus/binding/InternalSoapBindingGenerator.java

  • Committer: Bazaar Package Importer
  • Author(s): Dave Walker (Daviey)
  • Date: 2010-07-21 17:27:10 UTC
  • mfrom: (1.1.38 upstream)
  • Revision ID: james.westby@ubuntu.com-20100721172710-7xv07dmdqgivc3t9
Tags: 2.0~bzr1211-0ubuntu1
* New major upstream version merge, 2.0 (r1211).
* debian/patches/:
  - 01-wsdl-stubs.patch, debian/wsdl.md5sums: wsdl stubs updated.
  - 02-Makefile.patch: Updated to reflect new code layout.
  - 07-local_support_euca_conf-in.patch: Updated to reflect new code layout.
  - 08-ubuntu-default-networking.patch: Refreshed.
  - 09-small-128-192MB.patch: Updated to point to new location.
  - 10-disable-iscsi.patch: Refreshed.
  - 11-state-cleanup-memleakfix.patch: Removed, fixed upstream.
  - 15-fix-default-ramdisk.patch: Updated to point to new location.
  - 16-kvm_libvirt_xml_default_use_kvm.patch: Updated to reflect changes.
  - 17-fix_walrus_OOM_errors.patch: Removed, fixed upstream.
  - 18-priv_security.patch: Updated to reflect upstream changes.
  - 20-brute-force-webui.patch: Updated to reflect upstream changes. 
  - 21-eucalyptus-1.7-with-gwt-1.6.4.patch: New patch, allows 
    eucalyptus-1.7 to be built against gwt 1.6.4. Based on patch courtesy 
    of Dmitrii Zagorodnov, upstream. (LP: #597330)
* debian/eucalyptus-java-common.links: 
  - Changed symlink for groovy, point to groovy.all.jar, making compatiable 
    with groovy versions >1.7. (LP: #595421)
  - Added ant.jar & jetty-rewrite-handler.jar as they are now required.
* debian/control
  - & debian/build-jars: Added libjavassist-java and libjetty-extra-java as 
    build dependencies.
  - Added libjetty-extra-java as a dependency of eucalyptus-java-common
* The binary resulting jar's have been renamed from eucalyptus-*-1.6.2.jar
  to eucalyptus-*-main.jar:    
  - debian/eucalyptus-cc.upstart
  - debian/eucalyptus-cloud.install
  - debian/eucalyptus-common.eucalyptus.upstart
  - debian/eucalyptus-java-common.install
  - debian/eucalyptus-network.upstart
  - debian/eucalyptus-sc.install
  - debian/eucalyptus-walrus.install
* debian/eucalyptus-java-common.install: New upstream jars that have been
  installed:
  - eucalyptus-db-hsqldb-ext-main.jar
  - eucalyptus-component-main.jar
* debian/control:
  - Updated Standards Version to 3.8.4 (no change)
  - Updated the upstream Homepage to: http://open.eucalyptus.com/
  - Changed Vcs-Bzr to reflect new location of Ubuntu hosted development branch.
  - Made the Build Dependency of groovy and the binary eucalyptus-java-common
    package depend on version >=1.7.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package com.eucalyptus.binding;
 
2
 
 
3
import java.io.File;
 
4
import java.io.FileNotFoundException;
 
5
import java.io.PrintWriter;
 
6
import java.lang.reflect.Field;
 
7
import java.lang.reflect.ParameterizedType;
 
8
import java.lang.reflect.Type;
 
9
import java.util.ArrayList;
 
10
import java.util.Deque;
 
11
import java.util.HashMap;
 
12
import java.util.LinkedList;
 
13
import java.util.List;
 
14
import java.util.Map;
 
15
import org.apache.log4j.Logger;
 
16
import javassist.Modifier;
 
17
import com.google.common.base.Predicate;
 
18
import com.google.common.collect.Iterables;
 
19
 
 
20
public class InternalSoapBindingGenerator extends BindingGenerator {
 
21
  private static Logger            LOG          = Logger.getLogger( InternalSoapBindingGenerator.class );
 
22
  private final String             ns           = "http://msgs.eucalyptus.com";
 
23
  private static String            INDENT       = "";
 
24
  private final File               outFile;
 
25
  private PrintWriter              out;
 
26
  private String                   bindingName;
 
27
  private int                      indent       = 0;
 
28
  private Map<String, TypeBinding> typeBindings = new HashMap<String, TypeBinding>( ) {
 
29
                                                  {
 
30
                                                    put( Integer.class.getCanonicalName( ), new IntegerTypeBinding( ) );
 
31
                                                    put( Boolean.class.getCanonicalName( ), new BooleanTypeBinding( ) );
 
32
                                                    put( String.class.getCanonicalName( ), new StringTypeBinding( ) );
 
33
                                                    put( Long.class.getCanonicalName( ), new LongTypeBinding( ) );
 
34
                                                    put( "boolean", new BooleanTypeBinding( ) );
 
35
                                                    put( "int", new IntegerTypeBinding( ) );
 
36
                                                    put( "long", new LongTypeBinding( ) );
 
37
                                                    put( java.util.Date.class.getCanonicalName( ), new StringTypeBinding( ) );
 
38
                                                  }
 
39
                                                };
 
40
  
 
41
  private static List<String>      badClasses   = new ArrayList<String>( ) {
 
42
                                                  {
 
43
                                                    add( ".*HttpResponseStatus" );
 
44
                                                    add( ".*Closure" );
 
45
                                                    add( ".*Channel" );
 
46
                                                    add( ".*\\.JiBX_*" );
 
47
                                                  }
 
48
                                                };
 
49
  private static List<String>      badFields    = new ArrayList<String>( ) {
 
50
                                                  {
 
51
                                                    add( "__.*" );
 
52
                                                    add( "\\w*\\$\\w*\\$*.*" );
 
53
                                                    add( "class\\$.*" );
 
54
                                                    add( "metaClass" );
 
55
                                                    add( "JiBX_.*" );
 
56
                                                  }
 
57
                                                };
 
58
  
 
59
  public InternalSoapBindingGenerator( ) {
 
60
    this.outFile = new File( "modules/msgs/src/main/resources/msgs-binding.xml" );
 
61
    if ( outFile.exists( ) ) {
 
62
      outFile.delete( );
 
63
    }
 
64
    try {
 
65
      this.out = new PrintWriter( outFile );
 
66
    } catch ( FileNotFoundException e ) {
 
67
      e.printStackTrace( System.err );
 
68
      System.exit( -1 );
 
69
    }
 
70
    this.bindingName = this.ns.replaceAll( "(http://)|(/$)", "" ).replaceAll( "[./-]", "_" );
 
71
    this.out.write( "<binding xmlns:euca=\"" + ns + "\" name=\"" + bindingName + "\">\n" );
 
72
    this.out.write( "  <namespace uri=\"" + ns + "\" default=\"elements\" prefix=\"euca\"/>\n" );
 
73
    this.out.flush( );
 
74
  }
 
75
  
 
76
  public ElemItem peek( ) {
 
77
    return this.elemStack.peek( );
 
78
  }
 
79
  
 
80
  @Override
 
81
  public void processClass( Class klass ) {
 
82
    if ( BindingGenerator.DATA_TYPE.isAssignableFrom( klass ) || BindingGenerator.MSG_TYPE.isAssignableFrom( klass ) ) {
 
83
      String mapping = new RootObjectTypeBinding( klass ).process( );
 
84
      out.write( mapping );
 
85
      out.flush( );
 
86
    }
 
87
  }
 
88
  
 
89
  @Override
 
90
  public void close( ) {
 
91
    this.out.write( "</binding>" );
 
92
    this.out.flush( );
 
93
    this.out.close( );
 
94
  }
 
95
  
 
96
  public TypeBinding getTypeBinding( Field field ) {
 
97
    Class itsType = field.getType( );
 
98
    if ( this.isIgnored( field ) ) {
 
99
      return new NoopTypeBinding( field );
 
100
    } else if ( List.class.isAssignableFrom( itsType ) ) {
 
101
      Class listType = getTypeArgument( field );
 
102
      if ( listType == null ) {
 
103
        System.err.printf( "IGNORE: %-70s [type=%s] NO GENERIC TYPE FOR LIST\n", field.getDeclaringClass( ).getCanonicalName( ) + "."+ field.getName( ), listType );
 
104
        return new NoopTypeBinding( field );        
 
105
      } else if ( typeBindings.containsKey( listType.getCanonicalName( ) ) ) {
 
106
        return new CollectionTypeBinding( field.getName( ), typeBindings.get( listType.getCanonicalName( ) ) );
 
107
      } else if ( BindingGenerator.DATA_TYPE.isAssignableFrom( listType ) ) {
 
108
        return new CollectionTypeBinding( field.getName( ), new ObjectTypeBinding( field.getName( ), listType ) );
 
109
      } else {
 
110
        System.err.printf( "IGNORE: %-70s [type=%s] LIST'S GENERIC TYPE DOES NOT CONFORM TO EucalyptusData\n", field.getDeclaringClass( ).getCanonicalName( ) + "."+ field.getName( ), listType.getCanonicalName( ) );
 
111
        return new NoopTypeBinding( field );        
 
112
      }
 
113
    } else if ( typeBindings.containsKey( itsType.getCanonicalName( ) ) ) {
 
114
      TypeBinding t = typeBindings.get( itsType.getCanonicalName( ) );
 
115
      try {
 
116
        t = typeBindings.get( itsType.getCanonicalName( ) ).getClass( ).newInstance( );
 
117
      } catch ( Exception e ) {}
 
118
      return t.value( field.getName( ) );
 
119
    } else if ( BindingGenerator.DATA_TYPE.isAssignableFrom( field.getType( ) ) ) {
 
120
      return new ObjectTypeBinding( field );
 
121
    } else {
 
122
      System.err.printf( "IGNORE: %-70s [type=%s] TYPE DOES NOT CONFORM TO EucalyptusData\n", field.getDeclaringClass( ).getCanonicalName( ) + "."+ field.getName( ), field.getType( ).getCanonicalName( ) );
 
123
      return new NoopTypeBinding( field );
 
124
    }
 
125
  }
 
126
  
 
127
  class RootObjectTypeBinding extends TypeBinding {
 
128
    private Class   type;
 
129
    private boolean abs;
 
130
    
 
131
    public RootObjectTypeBinding( Class type ) {
 
132
      InternalSoapBindingGenerator.this.indent = 2;
 
133
      this.type = type;
 
134
      if ( Object.class.equals( type.getSuperclass( ) ) ) {
 
135
        this.abs = true;
 
136
      } else if ( type.getSuperclass( ).getSimpleName( ).equals( "EucalyptusData" ) ) {
 
137
        this.abs = true;
 
138
      } else {
 
139
        this.abs = false;
 
140
      }
 
141
    }
 
142
    
 
143
    @Override
 
144
    public String getTypeName( ) {
 
145
      return type.getCanonicalName( );
 
146
    }
 
147
    
 
148
    public String process( ) {
 
149
      if( this.type.getCanonicalName( ) == null ) {
 
150
        new RuntimeException( "" + this.type ).printStackTrace( );
 
151
      } else {
 
152
        this.elem( Elem.mapping );
 
153
        if ( this.abs ) {
 
154
          this.attr( "abstract", "true" );
 
155
        } else {
 
156
          this.attr( "name", this.type.getSimpleName( ) ).attr( "extends", this.type.getSuperclass( ).getCanonicalName( ) );
 
157
        }
 
158
        this.attr( "class", this.type.getCanonicalName( ) );
 
159
        if( BindingGenerator.MSG_TYPE.isAssignableFrom( this.type.getSuperclass( ) ) || BindingGenerator.DATA_TYPE.isAssignableFrom( this.type.getSuperclass( ) ) ) {
 
160
          this.elem( Elem.structure ).attr( "map-as", this.type.getSuperclass().getCanonicalName( ) ).end( );
 
161
        }
 
162
        for ( Field f : type.getDeclaredFields( ) ) {
 
163
          TypeBinding tb = getTypeBinding( f );
 
164
          if ( !( tb instanceof NoopTypeBinding ) ) {
 
165
            System.out.printf( "BOUND:  %-70s [type=%s:%s]\n", f.getDeclaringClass( ).getCanonicalName( ) +"."+ f.getName( ), tb.getTypeName( ), f.getType( ).getCanonicalName( ) );          
 
166
            this.append( tb.toString( ) );
 
167
          }
 
168
        }
 
169
        this.end( );
 
170
      }
 
171
      return this.toString( );
 
172
    }
 
173
  }
 
174
  
 
175
  @SuppressWarnings( "unchecked" )
 
176
  public static Class getTypeArgument( Field f ) {
 
177
    Type t = f.getGenericType( );
 
178
    if ( t != null && t instanceof ParameterizedType ) {
 
179
      Type tv = ( ( ParameterizedType ) t ).getActualTypeArguments( )[0];
 
180
      if ( tv instanceof Class ) {
 
181
        return ( ( Class ) tv );
 
182
      }
 
183
    }
 
184
    return null;
 
185
  }
 
186
  
 
187
  abstract class TypeBinding {
 
188
    private StringBuilder buf = new StringBuilder( );
 
189
    
 
190
    public abstract String getTypeName( );
 
191
    
 
192
    private TypeBinding reindent( int delta ) {
 
193
      InternalSoapBindingGenerator.this.indent += delta;
 
194
      INDENT = "";
 
195
      for ( int i = 0; i < indent; i++ ) {
 
196
        INDENT += "  ";
 
197
      }
 
198
      return this;
 
199
    }
 
200
    
 
201
    private TypeBinding indent( String addMe ) {
 
202
      this.reindent( +1 ).append( INDENT ).append( addMe );
 
203
      return this;
 
204
    }
 
205
    
 
206
    private TypeBinding outdent( String addMe ) {
 
207
      this.reindent( -1 ).append( INDENT ).append( addMe );
 
208
      return this;
 
209
    }
 
210
    
 
211
    protected TypeBinding append( Object o ) {
 
212
      this.buf.append( ""+o );
 
213
      return this;
 
214
    }
 
215
    
 
216
    protected TypeBinding eolIn( ) {
 
217
      this.append( "\n" ).indent( INDENT );
 
218
      return this;
 
219
    }
 
220
    
 
221
    protected TypeBinding eolOut( ) {
 
222
      this.append( "\n" ).outdent( INDENT );
 
223
      return this;
 
224
    }
 
225
    
 
226
    protected TypeBinding eol( ) {
 
227
      this.append( "\n" ).append( INDENT );
 
228
      return this;
 
229
    }
 
230
    
 
231
    protected TypeBinding value( String name ) {
 
232
      this.elem( Elem.value ).attr( "name", name ).attr( "field", name ).attr( "usage", "optional" ).attr( "style", "element" ).end( );
 
233
      return this;
 
234
    }
 
235
    
 
236
    private TypeBinding begin( ) {
 
237
      ElemItem top = InternalSoapBindingGenerator.this.elemStack.peek( );
 
238
      if ( top != null && top.children ) {
 
239
        this.eol( );
 
240
      } else if ( top != null && !top.children ) {
 
241
        this.append( ">" ).eolIn( );
 
242
        top.children = true;
 
243
      } else {
 
244
        this.eolIn( );
 
245
      }
 
246
      return this;
 
247
    }
 
248
    
 
249
    protected TypeBinding elem( Elem name ) {
 
250
      this.begin( ).append( "<" ).append( name.toString( ) ).append( " " );
 
251
      InternalSoapBindingGenerator.this.elemStack.push( new ElemItem( name, InternalSoapBindingGenerator.this.indent, false ) );
 
252
      return this;
 
253
    }
 
254
    
 
255
    protected TypeBinding end( ) {
 
256
      ElemItem top = InternalSoapBindingGenerator.this.elemStack.pop( );
 
257
      if ( top != null && top.children ) {
 
258
        this.eolOut( ).append( "</" ).append( top.name.toString( ) ).append( ">" );
 
259
      } else if ( top != null && !top.children ) {
 
260
        this.append( "/>" );
 
261
      } else {
 
262
        this.append( "/>" );
 
263
      }
 
264
      return this;
 
265
    }
 
266
    
 
267
    protected TypeBinding attr( String name, String value ) {
 
268
      this.append( name ).append( "=\"" ).append( value ).append( "\" " );
 
269
      return this;
 
270
    }
 
271
    
 
272
    public String toString( ) {
 
273
      String s = buf.toString( );
 
274
      buf = new StringBuilder( buf.capacity( ) );
 
275
      return s;
 
276
    }
 
277
    
 
278
    protected TypeBinding collection( String name ) {
 
279
      this.elem( Elem.structure ).attr( "name", name ).attr( "usage", "optional" );
 
280
      this.elem( Elem.collection ).attr( "factory", "com.eucalyptus.binding.Binding.listFactory" ).attr( "field", name )
 
281
          .attr( "item-type", this.getTypeName( ) ).attr( "usage", "required" );
 
282
      this.elem( Elem.structure ).attr( "name", "item" );
 
283
      this.elem( Elem.value ).attr( "name", "entry" ).end( ).end( ).end( ).end( );
 
284
      return this;
 
285
    }
 
286
    
 
287
  }
 
288
  
 
289
  public boolean isIgnored( final Field field ) {
 
290
    final int mods = field.getModifiers( );
 
291
    final String name = field.getName( );
 
292
    final String type = field.getType( ).getSimpleName( );
 
293
    if ( Modifier.isFinal( mods ) ) {
 
294
      LOG.debug( "Ignoring field with bad type: " + field.getDeclaringClass( ).getCanonicalName( ) + "." + name + " of type " + type
 
295
                 + " due to: final modifier" );
 
296
    } else if ( Modifier.isStatic( mods ) ) {
 
297
      LOG.debug( "Ignoring field with bad type: " + field.getDeclaringClass( ).getCanonicalName( ) + "." + name + " of type " + type
 
298
                 + " due to: static modifier" );
 
299
    }
 
300
    boolean ret = Iterables.any( badClasses, new Predicate<String>( ) {
 
301
      @Override
 
302
      public boolean apply( String arg0 ) {
 
303
        if ( type.matches( arg0 ) ) {
 
304
          LOG.debug( "Ignoring field with bad type: " + field.getDeclaringClass( ).getCanonicalName( ) + "." + name + " of type " + type + " due to: " + arg0 );
 
305
          return true;
 
306
        } else {
 
307
          return false;
 
308
        }
 
309
      }
 
310
    } );
 
311
    ret |= Iterables.any( badFields, new Predicate<String>( ) {
 
312
      @Override
 
313
      public boolean apply( String arg0 ) {
 
314
        if ( name.matches( arg0 ) ) {
 
315
          LOG.debug( "Ignoring field with bad name: " + field.getDeclaringClass( ).getCanonicalName( ) + "." + name + " of type " + type + " due to: " + arg0 );
 
316
          return true;
 
317
        } else {
 
318
          return false;
 
319
        }
 
320
      }
 
321
    } );
 
322
    
 
323
    return ret;
 
324
  }
 
325
  
 
326
  private class ElemItem {
 
327
    Elem    name;
 
328
    int     indent;
 
329
    boolean children;
 
330
    
 
331
    public ElemItem( Elem name, int indent, boolean children ) {
 
332
      this.name = name;
 
333
      this.indent = indent;
 
334
      this.children = children;
 
335
    }
 
336
    
 
337
    @Override
 
338
    public String toString( ) {
 
339
      return String.format( "ElemItem [name=%s, indent=%s, children=%s]", this.name, this.indent, Boolean.valueOf( children ) );
 
340
    }
 
341
    
 
342
  }
 
343
  
 
344
  private Deque<ElemItem> elemStack = new LinkedList<ElemItem>( );
 
345
  
 
346
  enum Elem {
 
347
    structure, collection, value, mapping, binding
 
348
  }
 
349
  class IgnoredTypeBinding extends NoopTypeBinding {
 
350
 
 
351
    public IgnoredTypeBinding( Field field ) {
 
352
      super( field );
 
353
    }
 
354
  }  
 
355
  class NoopTypeBinding extends TypeBinding {
 
356
    private String name;
 
357
    private Class  type;
 
358
    
 
359
    public NoopTypeBinding( Field field ) {
 
360
      this.name = field.getName( );
 
361
      this.type = field.getType( );
 
362
    }
 
363
    
 
364
    @Override
 
365
    public String toString( ) {
 
366
      return "";
 
367
    }
 
368
    
 
369
    @Override
 
370
    public String getTypeName( ) {
 
371
      return "NOOP";
 
372
    }
 
373
    
 
374
  }
 
375
  
 
376
  class ObjectTypeBinding extends TypeBinding {
 
377
    private String name;
 
378
    private Class  type;
 
379
    
 
380
    public ObjectTypeBinding( String name, Class type ) {
 
381
      this.name = name;
 
382
      this.type = type;
 
383
    }
 
384
    
 
385
    public ObjectTypeBinding( Field field ) {
 
386
      this.name = field.getName( );
 
387
      this.type = field.getType( );
 
388
    }
 
389
    
 
390
    @Override
 
391
    protected TypeBinding collection( String name ) {
 
392
      this.elem( Elem.structure ).attr( "name", name ).attr( "usage", "optional" );
 
393
      this.elem( Elem.collection ).attr( "factory", "com.eucalyptus.binding.Binding.listFactory" ).attr( "field", name ).attr( "usage", "required" );
 
394
      this.elem( Elem.structure ).attr( "name", "item" ).attr( "map-as", type.getCanonicalName( ) );
 
395
      this.end( ).end( ).end( );
 
396
      return this;
 
397
    }
 
398
    
 
399
    @Override
 
400
    public String getTypeName( ) {
 
401
      return this.type.getCanonicalName( );
 
402
    }
 
403
    
 
404
    public String toString( ) {
 
405
      this.elem( Elem.structure ).attr( "name", this.name ).attr( "field", this.name ).attr( "map-as", this.type.getCanonicalName( ) ).attr( "usage",
 
406
                                                                                                                                             "optional" ).end( );
 
407
      return super.toString( );
 
408
    }
 
409
    
 
410
  }
 
411
  
 
412
  class CollectionTypeBinding extends TypeBinding {
 
413
    private TypeBinding type;
 
414
    private String      name;
 
415
    
 
416
    public CollectionTypeBinding( String name, TypeBinding type ) {
 
417
      this.name = name;
 
418
      this.type = type;
 
419
      LOG.debug( "Found list type: " + type.getClass( ).getCanonicalName( ) );
 
420
    }
 
421
    
 
422
    @Override
 
423
    public String getTypeName( ) {
 
424
      return type.getTypeName( );
 
425
    }
 
426
    
 
427
    @Override
 
428
    public String toString( ) {
 
429
      LOG.debug( "Found list type: " + this.type.getTypeName( ) + " for name: " + name );
 
430
      String ret = this.type.collection( this.name ).buf.toString( );
 
431
      this.type.collection( this.name ).buf = new StringBuilder( );
 
432
      return ret;
 
433
    }
 
434
    
 
435
  }
 
436
  
 
437
  class IntegerTypeBinding extends TypeBinding {
 
438
    @Override
 
439
    public String getTypeName( ) {
 
440
      return Integer.class.getCanonicalName( );
 
441
    }
 
442
  }
 
443
  
 
444
  class LongTypeBinding extends TypeBinding {
 
445
    @Override
 
446
    public String getTypeName( ) {
 
447
      return Long.class.getCanonicalName( );
 
448
    }
 
449
  }
 
450
  
 
451
  class StringTypeBinding extends TypeBinding {
 
452
    @Override
 
453
    public String getTypeName( ) {
 
454
      return String.class.getCanonicalName( );
 
455
    }
 
456
  }
 
457
  
 
458
  class BooleanTypeBinding extends TypeBinding {
 
459
    @Override
 
460
    public String getTypeName( ) {
 
461
      return Boolean.class.getCanonicalName( );
 
462
    }
 
463
  }
 
464
  
 
465
}