Added support for source code generation from identity statement, grouping statement... 78/478/2
authorMartin Vitez <mvitez@cisco.com>
Thu, 13 Jun 2013 15:25:18 +0000 (17:25 +0200)
committerMartin Vitez <mvitez@cisco.com>
Fri, 14 Jun 2013 10:49:35 +0000 (12:49 +0200)
Introduce new BaseIdentity class as base for all classes generated from identity statements.
Introduce new WildcardType interface to add possibility to generate wildcard java type parameters in generated code.
Updated tests.

Change-Id: I99de20dc4268be43ec9966461aeb75521fe5dd6c
Signed-off-by: Martin Vitez <mvitez@cisco.com>
23 files changed:
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/Types.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/GeneratedTOBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/Constants.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/yang/abstract-topology@2013-02-08.yang
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferIdentityObject.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/WildcardType.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTOBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataNodeContainerBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java
opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/BaseIdentity.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/DataNodeIterator.java

index 863770d2c747bc8dfe2ff10f6130af811e7f1211..b89dbb44ac786756b60d866c02459097bbe615b4 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.sal.binding.generator.impl;
 
 import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
 import org.opendaylight.controller.binding.generator.util.Types;
+import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
@@ -23,6 +24,7 @@ import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
 import org.opendaylight.controller.yang.model.util.DataNodeIterator;
 import org.opendaylight.controller.yang.model.util.ExtendedType;
+import org.opendaylight.controller.yang.model.util.SchemaContextUtil;
 
 import java.util.*;
 import java.util.concurrent.Future;
@@ -65,6 +67,8 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             generatedTypes.addAll(allAugmentsToGenTypes(module));
             generatedTypes.addAll(allRPCMethodsToGenType(module));
             generatedTypes.addAll(allNotificationsToGenType(module));
+            generatedTypes.addAll(allIdentitiesToGenTypes(module, context));
+            generatedTypes.addAll(allGroupingsToGenTypes(module));
         }
         return generatedTypes;
     }
@@ -100,6 +104,9 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             generatedTypes.addAll(allAugmentsToGenTypes(contextModule));
             generatedTypes.addAll(allRPCMethodsToGenType(contextModule));
             generatedTypes.addAll(allNotificationsToGenType(contextModule));
+            generatedTypes.addAll(allIdentitiesToGenTypes(contextModule,
+                    context));
+            generatedTypes.addAll(allGroupingsToGenTypes(contextModule));
 
             if (modules.contains(contextModule)) {
                 filteredGenTypes.addAll(generatedTypes);
@@ -397,6 +404,84 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return genNotifyTypes;
     }
 
+    private List<Type> allIdentitiesToGenTypes(final Module module,
+            final SchemaContext context) {
+        List<Type> genTypes = new ArrayList<Type>();
+
+        final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
+
+        final String basePackageName = moduleNamespaceToPackageName(module);
+
+        if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
+            for (final IdentitySchemaNode identity : schemaIdentities) {
+                genTypes.add(identityToGenType(basePackageName, identity,
+                        context));
+            }
+        }
+        return genTypes;
+    }
+
+    private GeneratedType identityToGenType(final String basePackageName,
+            IdentitySchemaNode identity, SchemaContext context) {
+        if (identity == null) {
+            return null;
+        }
+
+        final String packageName = packageNameForGeneratedType(basePackageName,
+                identity.getPath());
+
+        final String genTypeName = parseToClassName(identity.getQName()
+                .getLocalName());
+        final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(
+                packageName, genTypeName);
+
+        IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
+        if (baseIdentity != null) {
+            Module baseIdentityParentModule = SchemaContextUtil.findParentModule(
+                    context, baseIdentity);
+
+            final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
+            final String returnTypeName = parseToClassName(baseIdentity
+                    .getQName().getLocalName());
+
+            GeneratedTransferObject gto = new GeneratedTOBuilderImpl(
+                    returnTypePkgName, returnTypeName).toInstance();
+            newType.addExtendsType(gto);
+        } else {
+            newType.addExtendsType(Types.getBaseIdentityTO());
+        }
+
+        return newType.toIdentityInstance();
+    }
+
+    private List<Type> allGroupingsToGenTypes(Module module) {
+        final List<Type> genTypes = new ArrayList<Type>();
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        Set<GroupingDefinition> groupings = module.getGroupings();
+        if (groupings != null && !groupings.isEmpty()) {
+            for (final GroupingDefinition grouping : groupings) {
+                genTypes.add(groupingToGenType(basePackageName, grouping));
+            }
+        }
+        return genTypes;
+    }
+
+    private GeneratedType groupingToGenType(final String basePackageName,
+            GroupingDefinition grouping) {
+        if (grouping == null) {
+            return null;
+        }
+
+        final String packageName = packageNameForGeneratedType(basePackageName,
+                grouping.getPath());
+        final Set<DataSchemaNode> schemaNodes = grouping.getChildNodes();
+        final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(
+                packageName, grouping);
+
+        resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
+        return typeBuilder.toInstance();
+    }
+
     private EnumTypeDefinition enumTypeDefFromExtendedType(
             final TypeDefinition<?> typeDefinition) {
         if (typeDefinition != null) {
index 03824efed06ed868709cf696e96d231e74a57c12..96069c273c071b96d3594b484055f0c32913a6f1 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilde
 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
+import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.*;
 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
@@ -103,7 +104,8 @@ public final class TypeProviderImpl implements TypeProvider {
                 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) baseTypeDef;
                 returnType = provideTypeForLeafref(leafref);
             } else if (baseTypeDef instanceof IdentityrefTypeDefinition) {
-
+                final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition)typeDefinition;
+                returnType = returnTypeForIdentityref(idref);
             } else if (baseTypeDef instanceof EnumTypeDefinition) {
                 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef;
                 returnType = resolveEnumFromTypeDefinition(enumTypeDef,
@@ -128,7 +130,8 @@ public final class TypeProviderImpl implements TypeProvider {
                 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
                 returnType = provideTypeForLeafref(leafref);
             } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
-
+                final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition)typeDefinition;
+                returnType = returnTypeForIdentityref(idref);
             } else {
                 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
                         .javaTypeForSchemaDefinitionType(typeDefinition);
@@ -142,6 +145,29 @@ public final class TypeProviderImpl implements TypeProvider {
 //        }
         return returnType;
     }
+    
+    private Type returnTypeForIdentityref(IdentityrefTypeDefinition idref) {
+        QName baseIdQName = idref.getIdentity();
+        Module module = schemaContext.findModuleByNamespace(baseIdQName.getNamespace());
+        IdentitySchemaNode identity = null;
+        for(IdentitySchemaNode id : module.getIdentities()) {
+            if(id.getQName().equals(baseIdQName)) {
+                identity = id;
+            }
+        }
+        if(identity == null) {
+            throw new IllegalArgumentException("Target identity '" + baseIdQName + "' do not exists");
+        }
+
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
+        final String genTypeName = parseToClassName(identity.getQName().getLocalName());
+
+        Type baseType = Types.typeForClass(Class.class);
+        Type paramType = Types.wildcardTypeFor(packageName, genTypeName);
+        Type returnType = Types.parameterizedTypeFor(baseType, paramType);
+        return returnType;
+    }
 
     public Type generatedTypeForExtendedDefinitionType(
             final TypeDefinition<?> typeDefinition) {
index 26be94351c67b9db724d7fd27a44abfbf26c9051..2e5bbf0a07a6f0a73d41af7f92c510880aae6963 100644 (file)
@@ -11,11 +11,15 @@ import java.util.List;
 import java.util.Map;\r
 import java.util.Set;\r
 \r
+import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;\r
 import org.opendaylight.controller.sal.binding.model.api.ConcreteType;\r
+import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;\r
 import org.opendaylight.controller.sal.binding.model.api.ParameterizedType;\r
 import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.sal.binding.model.api.WildcardType;\r
 import org.opendaylight.controller.yang.binding.Augmentable;\r
 import org.opendaylight.controller.yang.binding.Augmentation;\r
+import org.opendaylight.controller.yang.binding.BaseIdentity;\r
 import org.opendaylight.controller.yang.binding.DataObject;\r
 \r
 public final class Types {\r
@@ -36,7 +40,7 @@ public final class Types {
 \r
     /**\r
      * Returns an instance of {@link ConcreteType} describing the class\r
-     * \r
+     *\r
      * @param cls\r
      *            Class to describe\r
      * @return Description of class\r
@@ -49,7 +53,7 @@ public final class Types {
     /**\r
      * Returns an instance of {@link ParameterizedType} describing the typed\r
      * {@link Map}<K,V>\r
-     * \r
+     *\r
      * @param keyType\r
      *            Key Type\r
      * @param valueType\r
@@ -63,7 +67,7 @@ public final class Types {
     /**\r
      * Returns an instance of {@link ParameterizedType} describing the typed\r
      * {@link Set}<V> with concrete type of value.\r
-     * \r
+     *\r
      * @param valueType\r
      *            Value Type\r
      * @return Description of generic type instance of Set\r
@@ -75,7 +79,7 @@ public final class Types {
     /**\r
      * Returns an instance of {@link ParameterizedType} describing the typed\r
      * {@link List}<V> with concrete type of value.\r
-     * \r
+     *\r
      * @param valueType\r
      *            Value Type\r
      * @return Description of type instance of List\r
@@ -84,8 +88,15 @@ public final class Types {
         return parameterizedTypeFor(LIST_TYPE, valueType);\r
     }\r
 \r
+    public static GeneratedTransferObject getBaseIdentityTO() {\r
+        Class<BaseIdentity> cls = BaseIdentity.class;\r
+        GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(cls.getPackage().getName(),\r
+                cls.getSimpleName());\r
+        return gto.toInstance();\r
+    }\r
+\r
     /**\r
-     * \r
+     *\r
      * @param type\r
      * @param parameters\r
      * @return\r
@@ -94,17 +105,21 @@ public final class Types {
             Type... parameters) {\r
         return new ParametrizedTypeImpl(type, parameters);\r
     }\r
-    \r
+\r
+    public static WildcardType wildcardTypeFor(String packageName, String typeName) {\r
+        return new WildcardTypeImpl(packageName, typeName);\r
+    }\r
+\r
     public static ParameterizedType augmentableTypeFor(Type valueType) {\r
         final Type augmentable = typeForClass(Augmentable.class);\r
         return parameterizedTypeFor(augmentable, valueType);\r
     }\r
-    \r
+\r
     public static ParameterizedType augmentationTypeFor(Type valueType) {\r
         final Type augmentation = typeForClass(Augmentation.class);\r
         return parameterizedTypeFor(augmentation, valueType);\r
     }\r
-    \r
+\r
     private static class ConcreteTypeImpl extends AbstractBaseType implements\r
             ConcreteType {\r
         private ConcreteTypeImpl(String pkName, String name) {\r
@@ -135,4 +150,12 @@ public final class Types {
         }\r
 \r
     }\r
+\r
+    private static class WildcardTypeImpl extends AbstractBaseType\r
+            implements WildcardType {\r
+        public WildcardTypeImpl(String packageName, String typeName) {\r
+            super(packageName, typeName);\r
+        }\r
+    }\r
+\r
 }\r
index 558fb438504eda14a3c64b1b793f71f3f0a28e60..f1683fdc6435e86ccb98ea36389c1a24053b9d13 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.controller.sal.binding.model.api.AnnotationType;
 import org.opendaylight.controller.sal.binding.model.api.Constant;
 import org.opendaylight.controller.sal.binding.model.api.Enumeration;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferIdentityObject;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.controller.sal.binding.model.api.MethodSignature;
 import org.opendaylight.controller.sal.binding.model.api.Type;
@@ -26,11 +27,11 @@ import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedP
 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
 import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder;
 
-public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
+public class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
     private String packageName;
     private final String name;
     private String comment = "";
-    
+
     private GeneratedTransferObject extendsType;
     private final List<Type> implementsTypes = new ArrayList<Type>();
     private final List<EnumBuilder> enumerations = new ArrayList<EnumBuilder>();
@@ -81,7 +82,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
         }
         return null;
     }
-    
+
     @Override
     public boolean addImplementsType(final Type genType) {
         if (genType != null) {
@@ -98,7 +99,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
         }
         return false;
     }
-    
+
     @Override
     public EnumBuilder addEnumeration(String name) {
         final String innerPackageName = packageName + "." + this.name;
@@ -149,10 +150,20 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
 
     @Override
     public GeneratedTransferObject toInstance() {
-        return new GeneratedTransferObjectImpl(packageName, name, comment, 
-                annotationBuilders, extendsType, implementsTypes, constantDefintions, enumerations,
-                methodDefinitions, properties, equalsProperties,
-                hashProperties, toStringProperties);
+        return new GeneratedTransferObjectImpl(packageName, name, comment,
+                annotationBuilders, extendsType, implementsTypes,
+                constantDefintions, enumerations, methodDefinitions,
+                properties, equalsProperties, hashProperties,
+                toStringProperties);
+    }
+
+    @Override
+    public GeneratedTransferObject toIdentityInstance() {
+        return new GeneratedTransferIdentityObjectImpl(packageName, name, comment,
+                annotationBuilders, extendsType, implementsTypes,
+                constantDefintions, enumerations, methodDefinitions,
+                properties, equalsProperties, hashProperties,
+                toStringProperties);
     }
 
     private static final class GeneratedPropertyBuilderImpl implements
@@ -227,8 +238,9 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
 
         @Override
         public GeneratedProperty toInstance(final Type definingType) {
-            return new GeneratedPropertyImpl(name, comment, annotationBuilders, definingType,
-                    returnType, isFinal, isReadOnly, parameters, accessModifier);
+            return new GeneratedPropertyImpl(name, comment, annotationBuilders,
+                    definingType, returnType, isFinal, isReadOnly, parameters,
+                    accessModifier);
         }
     }
 
@@ -244,9 +256,10 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
         private final boolean isReadOnly;
         private final List<MethodSignature.Parameter> parameters;
         private final AccessModifier modifier;
-        
+
         public GeneratedPropertyImpl(final String name, final String comment,
-                final List<AnnotationTypeBuilder> annotationBuilders, final Type parent, final Type returnType,
+                final List<AnnotationTypeBuilder> annotationBuilders,
+                final Type parent, final Type returnType,
                 final boolean isFinal, final boolean isReadOnly,
                 final List<Parameter> parameters, final AccessModifier modifier) {
             super();
@@ -284,7 +297,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
         public List<AnnotationType> getAnnotations() {
             return annotations;
         }
-        
+
         @Override
         public Type getReturnType() {
             return returnType;
@@ -310,8 +323,6 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
             return isFinal;
         }
 
-        
-
         @Override
         public int hashCode() {
             final int prime = 31;
@@ -354,7 +365,8 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
                 if (other.returnType != null) {
                     return false;
                 }
-            } else if (!returnType.getPackageName().equals(other.returnType.getPackageName())) {
+            } else if (!returnType.getPackageName().equals(
+                    other.returnType.getPackageName())) {
                 return false;
             } else if (!returnType.getName().equals(other.returnType.getName())) {
                 return false;
@@ -394,7 +406,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
         }
     }
 
-    private static final class GeneratedTransferObjectImpl implements
+    private static class GeneratedTransferObjectImpl implements
             GeneratedTransferObject {
 
         private final String packageName;
@@ -412,8 +424,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
         private final List<Type> implementsTypes;
 
         public GeneratedTransferObjectImpl(final String packageName,
-                final String name,
-                final String comment,
+                final String name, final String comment,
                 final List<AnnotationTypeBuilder> annotationBuilders,
                 final GeneratedTransferObject extendsType,
                 final List<Type> implementsTypes,
@@ -430,7 +441,8 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
             this.comment = comment;
             this.annotations = toUnmodifiableAnnotations(annotationBuilders);
             this.extendsType = extendsType;
-            this.implementsTypes = Collections.unmodifiableList(implementsTypes);
+            this.implementsTypes = Collections
+                    .unmodifiableList(implementsTypes);
             this.constants = toUnmodifiableConstant(constantBuilders);
             this.enumerations = toUnmodifiableEnumerations(enumBuilders);
             this.properties = toUnmodifiableProperties(propBuilers);
@@ -499,17 +511,17 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
         public Type getParentType() {
             return null;
         }
-        
+
         @Override
         public String getComment() {
             return comment;
         }
-        
+
         @Override
         public List<AnnotationType> getAnnotations() {
             return annotations;
         }
-        
+
         @Override
         public List<Type> getImplements() {
             return implementsTypes;
@@ -519,7 +531,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
         public GeneratedTransferObject getExtends() {
             return extendsType;
         }
-        
+
         @Override
         public List<Enumeration> getEnumDefintions() {
             return enumerations;
@@ -623,4 +635,26 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder {
             return builder.toString();
         }
     }
+
+    private static final class GeneratedTransferIdentityObjectImpl extends
+            GeneratedTransferObjectImpl implements
+            GeneratedTransferIdentityObject {
+        public GeneratedTransferIdentityObjectImpl(final String packageName,
+                final String name, final String comment,
+                final List<AnnotationTypeBuilder> annotationBuilders,
+                final GeneratedTransferObject extendsType,
+                final List<Type> implementsTypes,
+                final List<ConstantBuilder> constantBuilders,
+                final List<EnumBuilder> enumBuilders,
+                final List<MethodSignatureBuilder> methodBuilders,
+                final List<GeneratedPropertyBuilder> propBuilers,
+                final List<GeneratedPropertyBuilder> equalsBuilers,
+                final List<GeneratedPropertyBuilder> hashCodeBuilers,
+                final List<GeneratedPropertyBuilder> stringBuilers) {
+            super(packageName, name, comment, annotationBuilders, extendsType,
+                    implementsTypes, constantBuilders, enumBuilders,
+                    methodBuilders, propBuilers, equalsBuilers,
+                    hashCodeBuilers, stringBuilers);
+        }
+    }
 }
index 0dcaa71c139be25d46bdaa250d07e9270dc13dd5..aaeec40604a61c264afef7d23e5f7111b115a1ef 100644 (file)
@@ -19,6 +19,7 @@ import java.util.Map;
 import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;
 import org.opendaylight.controller.sal.binding.model.api.Enumeration;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferIdentityObject;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.controller.sal.binding.model.api.Type;
 
@@ -29,6 +30,8 @@ public final class ClassCodeGenerator implements CodeGenerator {
     @Override
     public Writer generate(Type type) throws IOException {
         final Writer writer = new StringWriter();
+        boolean isIdentity = type instanceof GeneratedTransferIdentityObject;
+
         if (type instanceof GeneratedTransferObject) {
             GeneratedTransferObject genTO = (GeneratedTransferObject) type;            
             imports = GeneratorUtil.createImports(genTO);
@@ -47,7 +50,7 @@ public final class ClassCodeGenerator implements CodeGenerator {
             writer.write(NL);
 
             writer.write(GeneratorUtil.createClassDeclaration(genTO, "",
-                    imports));
+                    imports, isIdentity));
             writer.write(NL);
             writer.write(NL);
             
@@ -66,7 +69,7 @@ public final class ClassCodeGenerator implements CodeGenerator {
                 }
                 writer.write(NL);
                 writer.write(GeneratorUtil.createConstructor(genTO, TAB,
-                        imports) + NL);
+                        imports, isIdentity) + NL);
                 writer.write(NL);
                 for (GeneratedProperty field : fields) {
                     writer.write(GeneratorUtil.createGetter(field, TAB,
index bd94c20ffb5b3bbdc5aaf06905771d2e18d9aa24..e5cb97f1a6e4fb7181a875f5342a40f06a7d7e87 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.sal.java.api.generator;
 
 final class Constants {
-
     public static final String IFC = "interface";
     public static final String CLASS = "class";
     public static final String PKG = "package";
@@ -24,11 +23,13 @@ final class Constants {
     public static final String COMMA = ",";
     public static final String NL = "\n";
     public static final String SC = ";";
-    public static final String TAB = "\t";
+    public static final String TAB = "    ";
 
     public static final String PUBLIC = "public";
     public static final String PRIVATE = "private";
+    public static final String PROTECTED = "protected";
     public static final String STATIC = "static";
+    public static final String ABSTRACT = "abstract";
     public static final String FINAL = "final";
     public static final String EXTENDS = "extends";
     public static final String IMPLEMENTS = "implements";
index bb4bbbaf789191e29ff6e87a446595f84ee5bd5c..5b3b17dbf6c73334fe471dd3e797f8a18e228749 100644 (file)
@@ -26,670 +26,692 @@ import org.opendaylight.controller.sal.binding.model.api.MethodSignature;
 import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter;
 import org.opendaylight.controller.sal.binding.model.api.ParameterizedType;
 import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.sal.binding.model.api.WildcardType;
 
 public final class GeneratorUtil {
 
-       private GeneratorUtil() {
-       }
-
-       public static String createIfcDeclaration(final GeneratedType genType,
-                       final String indent,
-                       final Map<String, LinkedHashMap<String, Integer>> availableImports) {
-               return createFileDeclaration(IFC, genType, indent, availableImports);
-       }
-
-       public static String createClassDeclaration(
-                       final GeneratedTransferObject genTransferObject,
-                       final String indent,
-                       final Map<String, LinkedHashMap<String, Integer>> availableImports) {
-               return createFileDeclaration(CLASS, genTransferObject, indent,
-                               availableImports);
-       }
-
-       public static String createPackageDeclaration(final String packageName) {
-               return PKG + GAP + packageName + SC;
-       }
-
-       private static String createFileDeclaration(final String type,
-                       final GeneratedType genType, final String indent,
-                       final Map<String, LinkedHashMap<String, Integer>> availableImports) {
-               final StringBuilder builder = new StringBuilder();
-               final String currentPkg = genType.getPackageName();
-
-               createComment(builder, genType.getComment(), indent);
-
-               if (!genType.getAnnotations().isEmpty()) {
-                       final List<AnnotationType> annotations = genType.getAnnotations();
-                       appendAnnotations(builder, annotations);
-                       builder.append(NL);
-               }
-               builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP);
-
-               if (genType instanceof GeneratedTransferObject) {
-                       GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
-
-                       if (genTO.getExtends() != null) {
-                               builder.append(EXTENDS + GAP);
-                               builder.append(genTO.getExtends() + GAP);
-                       }
-               }
-
-               final List<Type> genImplements = genType.getImplements();
-               if (!genImplements.isEmpty()) {
-                       if (genType instanceof GeneratedTransferObject) {
-                               builder.append(IMPLEMENTS + GAP);
-                       } else {
-                               builder.append(EXTENDS + GAP);
-                       }
-                       builder.append(getExplicitType(genImplements.get(0),
-                                       availableImports, currentPkg));
-
-                       for (int i = 1; i < genImplements.size(); ++i) {
-                               builder.append(", ");
-                               builder.append(getExplicitType(genImplements.get(i),
-                                               availableImports, currentPkg));
-                       }
-               }
-
-               builder.append(GAP + LCB);
-               return builder.toString();
-       }
-
-       private static StringBuilder appendAnnotations(final StringBuilder builder,
-                       final List<AnnotationType> annotations) {
-               if ((builder != null) && (annotations != null)) {
-                       for (final AnnotationType annotation : annotations) {
-                               builder.append("@");
-                               builder.append(annotation.getPackageName());
-                               builder.append(".");
-                               builder.append(annotation.getName());
-
-                               if (annotation.containsParameters()) {
-                                       builder.append("(");
-                                       final List<AnnotationType.Parameter> parameters = annotation
-                                                       .getParameters();
-                                       appendAnnotationParams(builder, parameters);
-                                       builder.append(")");
-                               }
-                       }
-               }
-               return builder;
-       }
-
-       private static StringBuilder appendAnnotationParams(
-                       final StringBuilder builder,
-                       final List<AnnotationType.Parameter> parameters) {
-               if (parameters != null) {
-                       int i = 0;
-                       for (final AnnotationType.Parameter param : parameters) {
-                               if (param == null) {
-                                       continue;
-                               }
-                               if (i > 0) {
-                                       builder.append(", ");
-                               }
-                               final String paramName = param.getName();
-                               if (param.getValue() != null) {
-                                       builder.append(paramName);
-                                       builder.append(" = ");
-                                       builder.append(param.getValue());
-                               } else {
-                                       builder.append(paramName);
-                                       builder.append(" = {");
-                                       final List<String> values = param.getValues();
-                                       builder.append(values.get(0));
-                                       for (int j = 1; j < values.size(); ++j) {
-                                               builder.append(", ");
-                                               builder.append(values.get(j));
-                                       }
-                                       builder.append("}");
-                               }
-                               i++;
-                       }
-               }
-               return builder;
-       }
-
-       public static String createConstant(final Constant constant,
-                       final String indent,
-                       final Map<String, LinkedHashMap<String, Integer>> availableImports,
-                       final String currentPkg) {
-               final StringBuilder builder = new StringBuilder();
-               builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP);
-               builder.append(getExplicitType(constant.getType(), availableImports,
-                               currentPkg) + GAP + constant.getName());
-               builder.append(GAP + "=" + GAP);
-               builder.append(constant.getValue() + SC);
-               return builder.toString();
-       }
-
-       public static String createField(final GeneratedProperty property,
-                       final String indent,
-                       Map<String, LinkedHashMap<String, Integer>> availableImports,
-                       final String currentPkg) {
-               final StringBuilder builder = new StringBuilder();
-               builder.append(indent);
-               if (!property.getAnnotations().isEmpty()) {
-                       final List<AnnotationType> annotations = property.getAnnotations();
-                       appendAnnotations(builder, annotations);
-                       builder.append(NL);
-               }
-               builder.append(indent + PRIVATE + GAP);
-               builder.append(getExplicitType(property.getReturnType(),
-                               availableImports, currentPkg) + GAP + property.getName());
-               builder.append(SC);
-               return builder.toString();
-       }
-
-       /**
-        * Create method declaration in interface.
-        * 
-        * @param method
-        * @param indent
-        * @return
-        */
-       public static String createMethodDeclaration(final MethodSignature method,
-                       final String indent,
-                       Map<String, LinkedHashMap<String, Integer>> availableImports,
-                       final String currentPkg) {
-               final StringBuilder builder = new StringBuilder();
-
-               if (method == null) {
-                       throw new IllegalArgumentException(
-                                       "Method Signature parameter MUST be specified and cannot be NULL!");
-               }
-
-               final String comment = method.getComment();
-               final String name = method.getName();
-               if (name == null) {
-                       throw new IllegalStateException("Method Name cannot be NULL!");
-               }
-
-               final Type type = method.getReturnType();
-               if (type == null) {
-                       throw new IllegalStateException(
-                                       "Method Return type cannot be NULL!");
-               }
-
-               final List<Parameter> parameters = method.getParameters();
-
-               createComment(builder, comment, indent);
-               builder.append(NL);
-               builder.append(indent);
-
-               if (!method.getAnnotations().isEmpty()) {
-                       final List<AnnotationType> annotations = method.getAnnotations();
-                       appendAnnotations(builder, annotations);
-                       builder.append(NL);
-               }
-
-               builder.append(indent
-                               + getExplicitType(type, availableImports, currentPkg) + GAP
-                               + name);
-               builder.append(LB);
-               for (int i = 0; i < parameters.size(); i++) {
-                       Parameter p = parameters.get(i);
-                       String separator = COMMA;
-                       if (i + 1 == parameters.size()) {
-                               separator = "";
-                       }
-                       builder.append(getExplicitType(p.getType(), availableImports,
-                                       currentPkg) + GAP + p.getName() + separator);
-               }
-               builder.append(RB);
-               builder.append(SC);
-
-               return builder.toString();
-       }
-
-       public static String createConstructor(
-                       GeneratedTransferObject genTransferObject, final String indent,
-                       Map<String, LinkedHashMap<String, Integer>> availableImports) {
-               final StringBuilder builder = new StringBuilder();
-
-               final String currentPkg = genTransferObject.getPackageName();
-               final List<GeneratedProperty> properties = genTransferObject
-                               .getProperties();
-               final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
-               for (final GeneratedProperty property : properties) {
-                       if (property.isReadOnly()) {
-                               ctorParams.add(property);
-                       }
-               }
-
-               builder.append(indent);
-               builder.append(PUBLIC);
-               builder.append(GAP);
-               builder.append(genTransferObject.getName());
-               builder.append(LB);
-
-               if (!ctorParams.isEmpty()) {
-                       builder.append(getExplicitType(ctorParams.get(0).getReturnType(),
-                                       availableImports, currentPkg));
-                       builder.append(" ");
-                       builder.append(ctorParams.get(0).getName());
-                       for (int i = 1; i < ctorParams.size(); ++i) {
-                               final GeneratedProperty param = ctorParams.get(i);
-                               builder.append(", ");
-                               builder.append(getExplicitType(param.getReturnType(),
-                                               availableImports, currentPkg));
-                               builder.append(GAP);
-                               builder.append(param.getName());
-                       }
-               }
-               builder.append(RB + GAP + LCB + NL + indent + TAB + "super();" + NL);
-               if (!ctorParams.isEmpty()) {
-                       for (final GeneratedProperty property : ctorParams) {
-                               builder.append(indent);
-                               builder.append(TAB);
-                               builder.append("this.");
-                               builder.append(property.getName());
-                               builder.append(" = ");
-                               builder.append(property.getName());
-                               builder.append(SC);
-                               builder.append(NL);
-                       }
-               }
-               builder.append(indent);
-               builder.append(RCB);
-               return builder.toString();
-       }
-
-       public static String createGetter(final GeneratedProperty property,
-                       final String indent,
-                       Map<String, LinkedHashMap<String, Integer>> availableImports,
-                       final String currentPkg) {
-               final StringBuilder builder = new StringBuilder();
-
-               final Type type = property.getReturnType();
-               final String varName = property.getName();
-               final char first = Character.toUpperCase(varName.charAt(0));
-               final String methodName = "get" + first + varName.substring(1);
-
-               builder.append(indent + PUBLIC + GAP
-                               + getExplicitType(type, availableImports, currentPkg) + GAP
-                               + methodName);
-               builder.append(LB + RB + LCB + NL);
-
-               String currentIndent = indent + TAB;
-
-               builder.append(currentIndent + "return " + varName + SC + NL);
-
-               builder.append(indent + RCB);
-               return builder.toString();
-       }
-
-       public static String createSetter(final GeneratedProperty property,
-                       final String indent,
-                       Map<String, LinkedHashMap<String, Integer>> availableImports,
-                       String currentPkg) {
-               final StringBuilder builder = new StringBuilder();
-
-               final Type type = property.getReturnType();
-               final String varName = property.getName();
-               final char first = Character.toUpperCase(varName.charAt(0));
-               final String methodName = "set" + first + varName.substring(1);
-
-               builder.append(indent + PUBLIC + GAP + "void" + GAP + methodName);
-               builder.append(LB + getExplicitType(type, availableImports, currentPkg)
-                               + GAP + varName + RB + LCB + NL);
-               String currentIndent = indent + TAB;
-               builder.append(currentIndent + "this." + varName + " = " + varName + SC
-                               + NL);
-               builder.append(indent + RCB);
-               return builder.toString();
-       }
-
-       public static String createHashCode(
-                       final List<GeneratedProperty> properties, final String indent) {
-               StringBuilder builder = new StringBuilder();
-               builder.append(indent + "public int hashCode() {" + NL);
-               builder.append(indent + TAB + "final int prime = 31;" + NL);
-               builder.append(indent + TAB + "int result = 1;" + NL);
-
-               for (GeneratedProperty property : properties) {
-                       String fieldName = property.getName();
-                       builder.append(indent + TAB + "result = prime * result + (("
-                                       + fieldName + " == null) ? 0 : " + fieldName
-                                       + ".hashCode());" + NL);
-               }
-
-               builder.append(indent + TAB + "return result;" + NL);
-               builder.append(indent + RCB + NL);
-               return builder.toString();
-       }
-
-       public static String createEquals(final GeneratedTransferObject type,
-                       final List<GeneratedProperty> properties, final String indent) {
-               StringBuilder builder = new StringBuilder();
-               final String indent1 = indent + TAB;
-               final String indent2 = indent1 + TAB;
-               final String indent3 = indent2 + TAB;
-
-               builder.append(indent + "public boolean equals(Object obj) {" + NL);
-               builder.append(indent1 + "if (this == obj) {" + NL);
-               builder.append(indent2 + "return true;" + NL);
-               builder.append(indent1 + "}" + NL);
-               builder.append(indent1 + "if (obj == null) {" + NL);
-               builder.append(indent2 + "return false;" + NL);
-               builder.append(indent1 + "}" + NL);
-               builder.append(indent1 + "if (getClass() != obj.getClass()) {" + NL);
-               builder.append(indent2 + "return false;" + NL);
-               builder.append(indent1 + "}" + NL);
-
-               String typeStr = type.getName();
-               builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;"
-                               + NL);
-
-               for (GeneratedProperty property : properties) {
-                       String fieldName = property.getName();
-                       builder.append(indent1 + "if (" + fieldName + " == null) {" + NL);
-                       builder.append(indent2 + "if (other." + fieldName + " != null) {"
-                                       + NL);
-                       builder.append(indent3 + "return false;" + NL);
-                       builder.append(indent2 + "}" + NL);
-                       builder.append(indent1 + "} else if (!" + fieldName
-                                       + ".equals(other." + fieldName + ")) {" + NL);
-                       builder.append(indent2 + "return false;" + NL);
-                       builder.append(indent1 + "}" + NL);
-               }
-
-               builder.append(indent1 + "return true;" + NL);
-
-               builder.append(indent + RCB + NL);
-               return builder.toString();
-       }
-
-       public static String createToString(final GeneratedTransferObject type,
-                       final List<GeneratedProperty> properties, final String indent) {
-               StringBuilder builder = new StringBuilder();
-               builder.append(indent);
-               builder.append("public String toString() {");
-               builder.append(NL);
-               builder.append(indent);
-               builder.append(TAB);
-               builder.append("StringBuilder builder = new StringBuilder();");
-               builder.append(NL);
-               builder.append(indent);
-               builder.append(TAB);
-               builder.append("builder.append(\"");
-               builder.append(type.getName());
-               builder.append(" [");
-
-               boolean first = true;
-               for (GeneratedProperty property : properties) {
-                       if (first) {
-                               builder.append(property.getName());
-                               builder.append("=\");");
-                               builder.append(NL);
-                               builder.append(indent);
-                               builder.append(TAB);
-                               builder.append("builder.append(");
-                               builder.append(property.getName());
-                               builder.append(");");
-                               first = false;
-                       } else {
-                               builder.append(NL);
-                               builder.append(indent);
-                               builder.append(TAB);
-                               builder.append("builder.append(\", ");
-                               builder.append(property.getName());
-                               builder.append("=\");");
-                               builder.append(NL);
-                               builder.append(indent);
-                               builder.append(TAB);
-                               builder.append("builder.append(");
-                               builder.append(property.getName());
-                               builder.append(");");
-                       }
-               }
-               builder.append(NL);
-               builder.append(indent);
-               builder.append(TAB);
-               builder.append("builder.append(\"]\");");
-               builder.append(NL);
-               builder.append(indent);
-               builder.append(TAB);
-               builder.append("return builder.toString();");
-
-               builder.append(NL);
-               builder.append(indent);
-               builder.append(RCB);
-               builder.append(NL);
-               return builder.toString();
-       }
-
-       public static String createEnum(final Enumeration enumeration,
-                       final String indent) {
-               if (enumeration == null || indent == null)
-                       throw new IllegalArgumentException();
-               final StringBuilder builder = new StringBuilder(indent + PUBLIC + GAP
-                               + ENUM + GAP + enumeration.getName() + GAP + LCB + NL);
-
-               String separator = COMMA + NL;
-               final List<Pair> values = enumeration.getValues();
-
-               for (int i = 0; i < values.size(); i++) {
-                       if (i + 1 == values.size()) {
-                               separator = SC;
-                       }
-                       builder.append(indent + TAB + values.get(i).getName() + LB
-                                       + values.get(i).getValue() + RB + separator);
-               }
-               builder.append(NL);
-               builder.append(NL);
-               final String ENUMERATION_NAME = "value";
-               final String ENUMERATION_TYPE = "int";
-               builder.append(indent + TAB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME
-                               + SC);
-               builder.append(NL);
-               builder.append(indent + TAB + PRIVATE + GAP + enumeration.getName()
-                               + LB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME + RB + GAP
-                               + LCB + NL);
-               builder.append(indent + TAB + TAB + "this." + ENUMERATION_NAME + GAP
-                               + "=" + GAP + ENUMERATION_NAME + SC + NL);
-               builder.append(indent + TAB + RCB + NL);
-
-               builder.append(indent + RCB);
-               builder.append(NL);
-               return builder.toString();
-       }
-
-       private static String getExplicitType(final Type type,
-                       Map<String, LinkedHashMap<String, Integer>> availableImports,
-                       final String currentPkg) {
-               if (type == null) {
-                       throw new IllegalArgumentException(
-                                       "Type parameter MUST be specified and cannot be NULL!");
-               }
-               String packageName = type.getPackageName();
-
-               LinkedHashMap<String, Integer> imports = availableImports.get(type
-                               .getName());
-
-               if ((imports != null && packageName
-                               .equals(findMaxValue(imports).get(0)))
-                               || packageName.equals(currentPkg)) {
-                       final StringBuilder builder = new StringBuilder(type.getName());
-                       if (type instanceof ParameterizedType) {
-                               ParameterizedType pType = (ParameterizedType) type;
-                               Type[] pTypes = pType.getActualTypeArguments();
-                               builder.append("<");
-                               builder.append(getParameters(pTypes, availableImports,
-                                               currentPkg));
-                               builder.append(">");
-                       }
-                       if (builder.toString().equals("Void")) {
-                               return "void";
-                       }
-                       return builder.toString();
-               } else {
-                       final StringBuilder builder = new StringBuilder();
-                       if (packageName.startsWith("java.lang")) {
-                               builder.append(type.getName());
-                       } else {
+    private GeneratorUtil() {
+    }
+
+    public static String createIfcDeclaration(final GeneratedType genType,
+            final String indent,
+            final Map<String, LinkedHashMap<String, Integer>> availableImports) {
+        return createFileDeclaration(IFC, genType, indent, availableImports,
+                false);
+    }
+
+    public static String createClassDeclaration(
+            final GeneratedTransferObject genTransferObject,
+            final String indent,
+            final Map<String, LinkedHashMap<String, Integer>> availableImports,
+            boolean isIdentity) {
+        return createFileDeclaration(CLASS, genTransferObject, indent,
+                availableImports, isIdentity);
+    }
+
+    public static String createPackageDeclaration(final String packageName) {
+        return PKG + GAP + packageName + SC;
+    }
+
+    private static String createFileDeclaration(final String type,
+            final GeneratedType genType, final String indent,
+            final Map<String, LinkedHashMap<String, Integer>> availableImports,
+            boolean isIdentity) {
+        final StringBuilder builder = new StringBuilder();
+        final String currentPkg = genType.getPackageName();
+
+        createComment(builder, genType.getComment(), indent);
+
+        if (!genType.getAnnotations().isEmpty()) {
+            final List<AnnotationType> annotations = genType.getAnnotations();
+            appendAnnotations(builder, annotations);
+            builder.append(NL);
+        }
+
+        if (isIdentity) {
+            if (!(CLASS.equals(type))) {
+                throw new IllegalArgumentException(
+                        "'identity' has to be generated as a class");
+            }
+            builder.append(PUBLIC + GAP + ABSTRACT + GAP + type + GAP
+                    + genType.getName() + GAP);
+        } else {
+            builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP);
+        }
+
+        if (genType instanceof GeneratedTransferObject) {
+            GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
+
+            if (genTO.getExtends() != null) {
+                builder.append(EXTENDS + GAP);
+                String gtoString = getExplicitType(genTO.getExtends(), availableImports, currentPkg);
+                builder.append(gtoString + GAP);
+            }
+        }
+
+        final List<Type> genImplements = genType.getImplements();
+        if (!genImplements.isEmpty()) {
+            if (genType instanceof GeneratedTransferObject) {
+                builder.append(IMPLEMENTS + GAP);
+            } else {
+                builder.append(EXTENDS + GAP);
+            }
+            builder.append(getExplicitType(genImplements.get(0),
+                    availableImports, currentPkg));
+
+            for (int i = 1; i < genImplements.size(); ++i) {
+                builder.append(", ");
+                builder.append(getExplicitType(genImplements.get(i),
+                        availableImports, currentPkg));
+            }
+        }
+
+        builder.append(GAP + LCB);
+        return builder.toString();
+    }
+
+    private static StringBuilder appendAnnotations(final StringBuilder builder,
+            final List<AnnotationType> annotations) {
+        if ((builder != null) && (annotations != null)) {
+            for (final AnnotationType annotation : annotations) {
+                builder.append("@");
+                builder.append(annotation.getPackageName());
+                builder.append(".");
+                builder.append(annotation.getName());
+
+                if (annotation.containsParameters()) {
+                    builder.append("(");
+                    final List<AnnotationType.Parameter> parameters = annotation
+                            .getParameters();
+                    appendAnnotationParams(builder, parameters);
+                    builder.append(")");
+                }
+            }
+        }
+        return builder;
+    }
+
+    private static StringBuilder appendAnnotationParams(
+            final StringBuilder builder,
+            final List<AnnotationType.Parameter> parameters) {
+        if (parameters != null) {
+            int i = 0;
+            for (final AnnotationType.Parameter param : parameters) {
+                if (param == null) {
+                    continue;
+                }
+                if (i > 0) {
+                    builder.append(", ");
+                }
+                final String paramName = param.getName();
+                if (param.getValue() != null) {
+                    builder.append(paramName);
+                    builder.append(" = ");
+                    builder.append(param.getValue());
+                } else {
+                    builder.append(paramName);
+                    builder.append(" = {");
+                    final List<String> values = param.getValues();
+                    builder.append(values.get(0));
+                    for (int j = 1; j < values.size(); ++j) {
+                        builder.append(", ");
+                        builder.append(values.get(j));
+                    }
+                    builder.append("}");
+                }
+                i++;
+            }
+        }
+        return builder;
+    }
+
+    public static String createConstant(final Constant constant,
+            final String indent,
+            final Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
+        final StringBuilder builder = new StringBuilder();
+        builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP);
+        builder.append(getExplicitType(constant.getType(), availableImports,
+                currentPkg) + GAP + constant.getName());
+        builder.append(GAP + "=" + GAP);
+        builder.append(constant.getValue() + SC);
+        return builder.toString();
+    }
+
+    public static String createField(final GeneratedProperty property,
+            final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
+        final StringBuilder builder = new StringBuilder();
+        if (!property.getAnnotations().isEmpty()) {
+            final List<AnnotationType> annotations = property.getAnnotations();
+            appendAnnotations(builder, annotations);
+            builder.append(NL);
+        }
+        builder.append(indent + PRIVATE + GAP);
+        builder.append(getExplicitType(property.getReturnType(),
+                availableImports, currentPkg) + GAP + property.getName());
+        builder.append(SC);
+        return builder.toString();
+    }
+
+    /**
+     * Create method declaration in interface.
+     * 
+     * @param method
+     * @param indent
+     * @return
+     */
+    public static String createMethodDeclaration(final MethodSignature method,
+            final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
+        final StringBuilder builder = new StringBuilder();
+
+        if (method == null) {
+            throw new IllegalArgumentException(
+                    "Method Signature parameter MUST be specified and cannot be NULL!");
+        }
+
+        final String comment = method.getComment();
+        final String name = method.getName();
+        if (name == null) {
+            throw new IllegalStateException("Method Name cannot be NULL!");
+        }
+
+        final Type type = method.getReturnType();
+        if (type == null) {
+            throw new IllegalStateException(
+                    "Method Return type cannot be NULL!");
+        }
+
+        final List<Parameter> parameters = method.getParameters();
+
+        createComment(builder, comment, indent);
+        builder.append(NL);
+        builder.append(indent);
+
+        if (!method.getAnnotations().isEmpty()) {
+            final List<AnnotationType> annotations = method.getAnnotations();
+            appendAnnotations(builder, annotations);
+            builder.append(NL);
+        }
+
+        builder.append(indent
+                + getExplicitType(type, availableImports, currentPkg) + GAP
+                + name);
+        builder.append(LB);
+        for (int i = 0; i < parameters.size(); i++) {
+            Parameter p = parameters.get(i);
+            String separator = COMMA;
+            if (i + 1 == parameters.size()) {
+                separator = "";
+            }
+            builder.append(getExplicitType(p.getType(), availableImports,
+                    currentPkg) + GAP + p.getName() + separator);
+        }
+        builder.append(RB);
+        builder.append(SC);
+
+        return builder.toString();
+    }
+
+    public static String createConstructor(
+            GeneratedTransferObject genTransferObject, final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            boolean isIdentity) {
+        final StringBuilder builder = new StringBuilder();
+
+        final String currentPkg = genTransferObject.getPackageName();
+        final List<GeneratedProperty> properties = genTransferObject
+                .getProperties();
+        final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
+        for (final GeneratedProperty property : properties) {
+            if (property.isReadOnly()) {
+                ctorParams.add(property);
+            }
+        }
+
+        builder.append(indent);
+        builder.append(isIdentity ? PROTECTED : PUBLIC);
+        builder.append(GAP);
+        builder.append(genTransferObject.getName());
+        builder.append(LB);
+
+        if (!ctorParams.isEmpty()) {
+            builder.append(getExplicitType(ctorParams.get(0).getReturnType(),
+                    availableImports, currentPkg));
+            builder.append(" ");
+            builder.append(ctorParams.get(0).getName());
+            for (int i = 1; i < ctorParams.size(); ++i) {
+                final GeneratedProperty param = ctorParams.get(i);
+                builder.append(", ");
+                builder.append(getExplicitType(param.getReturnType(),
+                        availableImports, currentPkg));
+                builder.append(GAP);
+                builder.append(param.getName());
+            }
+        }
+        builder.append(RB + GAP + LCB + NL + indent + TAB + "super();" + NL);
+        if (!ctorParams.isEmpty()) {
+            for (final GeneratedProperty property : ctorParams) {
+                builder.append(indent);
+                builder.append(TAB);
+                builder.append("this.");
+                builder.append(property.getName());
+                builder.append(" = ");
+                builder.append(property.getName());
+                builder.append(SC);
+                builder.append(NL);
+            }
+        }
+        builder.append(indent);
+        builder.append(RCB);
+        return builder.toString();
+    }
+
+    public static String createGetter(final GeneratedProperty property,
+            final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
+        final StringBuilder builder = new StringBuilder();
+
+        final Type type = property.getReturnType();
+        final String varName = property.getName();
+        final char first = Character.toUpperCase(varName.charAt(0));
+        final String methodName = "get" + first + varName.substring(1);
+
+        builder.append(indent + PUBLIC + GAP
+                + getExplicitType(type, availableImports, currentPkg) + GAP
+                + methodName);
+        builder.append(LB + RB + LCB + NL);
+
+        String currentIndent = indent + TAB;
+
+        builder.append(currentIndent + "return " + varName + SC + NL);
+
+        builder.append(indent + RCB);
+        return builder.toString();
+    }
+
+    public static String createSetter(final GeneratedProperty property,
+            final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            String currentPkg) {
+        final StringBuilder builder = new StringBuilder();
+
+        final Type type = property.getReturnType();
+        final String varName = property.getName();
+        final char first = Character.toUpperCase(varName.charAt(0));
+        final String methodName = "set" + first + varName.substring(1);
+
+        builder.append(indent + PUBLIC + GAP + "void" + GAP + methodName);
+        builder.append(LB + getExplicitType(type, availableImports, currentPkg)
+                + GAP + varName + RB + LCB + NL);
+        String currentIndent = indent + TAB;
+        builder.append(currentIndent + "this." + varName + " = " + varName + SC
+                + NL);
+        builder.append(indent + RCB);
+        return builder.toString();
+    }
+
+    public static String createHashCode(
+            final List<GeneratedProperty> properties, final String indent) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(indent + "public int hashCode() {" + NL);
+        builder.append(indent + TAB + "final int prime = 31;" + NL);
+        builder.append(indent + TAB + "int result = 1;" + NL);
+
+        for (GeneratedProperty property : properties) {
+            String fieldName = property.getName();
+            builder.append(indent + TAB + "result = prime * result + (("
+                    + fieldName + " == null) ? 0 : " + fieldName
+                    + ".hashCode());" + NL);
+        }
+
+        builder.append(indent + TAB + "return result;" + NL);
+        builder.append(indent + RCB + NL);
+        return builder.toString();
+    }
+
+    public static String createEquals(final GeneratedTransferObject type,
+            final List<GeneratedProperty> properties, final String indent) {
+        StringBuilder builder = new StringBuilder();
+        final String indent1 = indent + TAB;
+        final String indent2 = indent1 + TAB;
+        final String indent3 = indent2 + TAB;
+
+        builder.append(indent + "public boolean equals(Object obj) {" + NL);
+        builder.append(indent1 + "if (this == obj) {" + NL);
+        builder.append(indent2 + "return true;" + NL);
+        builder.append(indent1 + "}" + NL);
+        builder.append(indent1 + "if (obj == null) {" + NL);
+        builder.append(indent2 + "return false;" + NL);
+        builder.append(indent1 + "}" + NL);
+        builder.append(indent1 + "if (getClass() != obj.getClass()) {" + NL);
+        builder.append(indent2 + "return false;" + NL);
+        builder.append(indent1 + "}" + NL);
+
+        String typeStr = type.getName();
+        builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;"
+                + NL);
+
+        for (GeneratedProperty property : properties) {
+            String fieldName = property.getName();
+            builder.append(indent1 + "if (" + fieldName + " == null) {" + NL);
+            builder.append(indent2 + "if (other." + fieldName + " != null) {"
+                    + NL);
+            builder.append(indent3 + "return false;" + NL);
+            builder.append(indent2 + "}" + NL);
+            builder.append(indent1 + "} else if (!" + fieldName
+                    + ".equals(other." + fieldName + ")) {" + NL);
+            builder.append(indent2 + "return false;" + NL);
+            builder.append(indent1 + "}" + NL);
+        }
+
+        builder.append(indent1 + "return true;" + NL);
+
+        builder.append(indent + RCB + NL);
+        return builder.toString();
+    }
+
+    public static String createToString(final GeneratedTransferObject type,
+            final List<GeneratedProperty> properties, final String indent) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(indent);
+        builder.append("public String toString() {");
+        builder.append(NL);
+        builder.append(indent);
+        builder.append(TAB);
+        builder.append("StringBuilder builder = new StringBuilder();");
+        builder.append(NL);
+        builder.append(indent);
+        builder.append(TAB);
+        builder.append("builder.append(\"");
+        builder.append(type.getName());
+        builder.append(" [");
+
+        boolean first = true;
+        for (GeneratedProperty property : properties) {
+            if (first) {
+                builder.append(property.getName());
+                builder.append("=\");");
+                builder.append(NL);
+                builder.append(indent);
+                builder.append(TAB);
+                builder.append("builder.append(");
+                builder.append(property.getName());
+                builder.append(");");
+                first = false;
+            } else {
+                builder.append(NL);
+                builder.append(indent);
+                builder.append(TAB);
+                builder.append("builder.append(\", ");
+                builder.append(property.getName());
+                builder.append("=\");");
+                builder.append(NL);
+                builder.append(indent);
+                builder.append(TAB);
+                builder.append("builder.append(");
+                builder.append(property.getName());
+                builder.append(");");
+            }
+        }
+        builder.append(NL);
+        builder.append(indent);
+        builder.append(TAB);
+        builder.append("builder.append(\"]\");");
+        builder.append(NL);
+        builder.append(indent);
+        builder.append(TAB);
+        builder.append("return builder.toString();");
+
+        builder.append(NL);
+        builder.append(indent);
+        builder.append(RCB);
+        builder.append(NL);
+        return builder.toString();
+    }
+
+    public static String createEnum(final Enumeration enumeration,
+            final String indent) {
+        if (enumeration == null || indent == null)
+            throw new IllegalArgumentException();
+        final StringBuilder builder = new StringBuilder(indent + PUBLIC + GAP
+                + ENUM + GAP + enumeration.getName() + GAP + LCB + NL);
+
+        String separator = COMMA + NL;
+        final List<Pair> values = enumeration.getValues();
+
+        for (int i = 0; i < values.size(); i++) {
+            if (i + 1 == values.size()) {
+                separator = SC;
+            }
+            builder.append(indent + TAB + values.get(i).getName() + LB
+                    + values.get(i).getValue() + RB + separator);
+        }
+        builder.append(NL);
+        builder.append(NL);
+        final String ENUMERATION_NAME = "value";
+        final String ENUMERATION_TYPE = "int";
+        builder.append(indent + TAB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME
+                + SC);
+        builder.append(NL);
+        builder.append(indent + TAB + PRIVATE + GAP + enumeration.getName()
+                + LB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME + RB + GAP
+                + LCB + NL);
+        builder.append(indent + TAB + TAB + "this." + ENUMERATION_NAME + GAP
+                + "=" + GAP + ENUMERATION_NAME + SC + NL);
+        builder.append(indent + TAB + RCB + NL);
+
+        builder.append(indent + RCB);
+        builder.append(NL);
+        return builder.toString();
+    }
+
+    private static String getExplicitType(final Type type,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
+        if (type == null) {
+            throw new IllegalArgumentException(
+                    "Type parameter MUST be specified and cannot be NULL!");
+        }
+        String packageName = type.getPackageName();
+
+        LinkedHashMap<String, Integer> imports = availableImports.get(type
+                .getName());
+
+        if ((imports != null && packageName
+                .equals(findMaxValue(imports).get(0)))
+                || packageName.equals(currentPkg)) {
+            final StringBuilder builder = new StringBuilder(type.getName());
+            if (type instanceof ParameterizedType) {
+                ParameterizedType pType = (ParameterizedType) type;
+                Type[] pTypes = pType.getActualTypeArguments();
+                builder.append("<");
+                builder.append(getParameters(pTypes, availableImports,
+                        currentPkg));
+                builder.append(">");
+            }
+            if (builder.toString().equals("Void")) {
+                return "void";
+            }
+            return builder.toString();
+        } else {
+            final StringBuilder builder = new StringBuilder();
+            if (packageName.startsWith("java.lang")) {
+                builder.append(type.getName());
+            } else {
                 if (!packageName.isEmpty()) {
                     builder.append(packageName + "." + type.getName());
                 } else {
                     builder.append(type.getName());
                 }
 
-                       }
-                       if (type instanceof ParameterizedType) {
-                               ParameterizedType pType = (ParameterizedType) type;
-                               Type[] pTypes = pType.getActualTypeArguments();
-                               builder.append("<");
-                               builder.append(getParameters(pTypes, availableImports,
-                                               currentPkg));
-                               builder.append(">");
-                       }
-                       if (builder.toString().equals("Void")) {
-                               return "void";
-                       }
-                       return builder.toString();
-               }
-       }
-
-       private static String getParameters(final Type[] pTypes,
-                       Map<String, LinkedHashMap<String, Integer>> availableImports,
-                       String currentPkg) {
-               final StringBuilder builder = new StringBuilder();
-               for (int i = 0; i < pTypes.length; i++) {
-                       Type t = pTypes[i];
-
-                       String separator = COMMA;
-                       if (i + 1 == pTypes.length) {
-                               separator = "";
-                       }
-                       builder.append(getExplicitType(t, availableImports, currentPkg)
-                                       + separator);
-               }
-               return builder.toString();
-       }
-
-       private static List<String> findMaxValue(
-                       LinkedHashMap<String, Integer> imports) {
-               final List<String> result = new ArrayList<String>();
-
-               int maxValue = 0;
-               int currentValue = 0;
-               for (Map.Entry<String, Integer> entry : imports.entrySet()) {
-                       currentValue = entry.getValue();
-                       if (currentValue > maxValue) {
-                               result.clear();
-                               result.add(entry.getKey());
-                       } else if (currentValue == maxValue) {
-                               result.add(entry.getKey());
-                       }
-               }
-               return result;
-       }
-
-       private static void createComment(final StringBuilder builder,
-                       final String comment, final String indent) {
-               if (comment != null && comment.length() > 0) {
-                       builder.append(indent + "/*" + NL);
-                       builder.append(indent + comment + NL);
-                       builder.append(indent + "*/" + NL);
-               }
-       }
-
-       public static Map<String, LinkedHashMap<String, Integer>> createImports(
-                       GeneratedType genType) {
-               final Map<String, LinkedHashMap<String, Integer>> imports = new HashMap<String, LinkedHashMap<String, Integer>>();
-               final String genTypePkg = genType.getPackageName();
-
-               final List<Constant> constants = genType.getConstantDefinitions();
-               final List<MethodSignature> methods = genType.getMethodDefinitions();
-               List<Type> impl = genType.getImplements();
-
-               // IMPLEMENTATIONS
-               if (impl != null) {
-                       for (Type t : impl) {
-                               addTypeToImports(t, imports, genTypePkg);
-                       }
-               }
-
-               // CONSTANTS
-               if (constants != null) {
-                       for (Constant c : constants) {
-                               Type ct = c.getType();
-                               addTypeToImports(ct, imports, genTypePkg);
-                       }
-               }
-
-               // METHODS
-               if (methods != null) {
-                       for (MethodSignature m : methods) {
-                               Type ct = m.getReturnType();
-                               addTypeToImports(ct, imports, genTypePkg);
-                               for (MethodSignature.Parameter p : m.getParameters()) {
-                                       addTypeToImports(p.getType(), imports, genTypePkg);
-                               }
-                       }
-               }
-
-               // PROPERTIES
-               if (genType instanceof GeneratedTransferObject) {
-                       GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
-
-                       List<GeneratedProperty> props = genTO.getProperties();
-                       if (props != null) {
-                               for (GeneratedProperty prop : props) {
-                                       Type pt = prop.getReturnType();
-                                       addTypeToImports(pt, imports, genTypePkg);
-                               }
-                       }
-               }
-
-               return imports;
-       }
-
-       private static void addTypeToImports(Type type,
-                       Map<String, LinkedHashMap<String, Integer>> importedTypes,
-                       String genTypePkg) {
-               String typeName = type.getName();
-               String typePkg = type.getPackageName();
+            }
+            if (type instanceof ParameterizedType) {
+                ParameterizedType pType = (ParameterizedType) type;
+                Type[] pTypes = pType.getActualTypeArguments();
+                builder.append("<");
+                builder.append(getParameters(pTypes, availableImports,
+                        currentPkg));
+                builder.append(">");
+            }
+            if (builder.toString().equals("Void")) {
+                return "void";
+            }
+            return builder.toString();
+        }
+    }
+
+    private static String getParameters(final Type[] pTypes,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            String currentPkg) {
+        final StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < pTypes.length; i++) {
+            Type t = pTypes[i];
+
+            String separator = COMMA;
+            if (i + 1 == pTypes.length) {
+                separator = "";
+            }
+            
+            String wildcardParam = "";
+            if(t instanceof WildcardType) {
+                wildcardParam = "? extends ";
+            }
+            
+            builder.append(wildcardParam + getExplicitType(t, availableImports, currentPkg)
+                    + separator);
+        }
+        return builder.toString();
+    }
+
+    private static List<String> findMaxValue(
+            LinkedHashMap<String, Integer> imports) {
+        final List<String> result = new ArrayList<String>();
+
+        int maxValue = 0;
+        int currentValue = 0;
+        for (Map.Entry<String, Integer> entry : imports.entrySet()) {
+            currentValue = entry.getValue();
+            if (currentValue > maxValue) {
+                result.clear();
+                result.add(entry.getKey());
+                maxValue = currentValue;
+            } else if (currentValue == maxValue) {
+                result.add(entry.getKey());
+            }
+        }
+        return result;
+    }
+
+    private static void createComment(final StringBuilder builder,
+            final String comment, final String indent) {
+        if (comment != null && comment.length() > 0) {
+            builder.append(indent + "/*" + NL);
+            builder.append(indent + comment + NL);
+            builder.append(indent + "*/" + NL);
+        }
+    }
+
+    public static Map<String, LinkedHashMap<String, Integer>> createImports(
+            GeneratedType genType) {
+        final Map<String, LinkedHashMap<String, Integer>> imports = new HashMap<String, LinkedHashMap<String, Integer>>();
+        final String genTypePkg = genType.getPackageName();
+
+        final List<Constant> constants = genType.getConstantDefinitions();
+        final List<MethodSignature> methods = genType.getMethodDefinitions();
+        List<Type> impl = genType.getImplements();
+
+        // IMPLEMENTATIONS
+        if (impl != null) {
+            for (Type t : impl) {
+                addTypeToImports(t, imports, genTypePkg);
+            }
+        }
+
+        // CONSTANTS
+        if (constants != null) {
+            for (Constant c : constants) {
+                Type ct = c.getType();
+                addTypeToImports(ct, imports, genTypePkg);
+            }
+        }
+
+        // METHODS
+        if (methods != null) {
+            for (MethodSignature m : methods) {
+                Type ct = m.getReturnType();
+                addTypeToImports(ct, imports, genTypePkg);
+                for (MethodSignature.Parameter p : m.getParameters()) {
+                    addTypeToImports(p.getType(), imports, genTypePkg);
+                }
+            }
+        }
+
+        // PROPERTIES
+        if (genType instanceof GeneratedTransferObject) {
+            GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
+
+            List<GeneratedProperty> props = genTO.getProperties();
+            if (props != null) {
+                for (GeneratedProperty prop : props) {
+                    Type pt = prop.getReturnType();
+                    addTypeToImports(pt, imports, genTypePkg);
+                }
+            }
+        }
+
+        return imports;
+    }
+
+    private static void addTypeToImports(Type type,
+            Map<String, LinkedHashMap<String, Integer>> importedTypes,
+            String genTypePkg) {
+        String typeName = type.getName();
+        String typePkg = type.getPackageName();
                if (typePkg.startsWith("java.lang") || typePkg.equals(genTypePkg) ||
                 typePkg.isEmpty()) {
-                       return;
-               }
-               LinkedHashMap<String, Integer> packages = importedTypes.get(typeName);
-               if (packages == null) {
-                       packages = new LinkedHashMap<String, Integer>();
-                       packages.put(typePkg, 1);
-                       importedTypes.put(typeName, packages);
-               } else {
-                       Integer occurrence = packages.get(typePkg);
-                       if (occurrence == null) {
-                               packages.put(typePkg, 1);
-                       } else {
-                               occurrence++;
-                               packages.put(typePkg, occurrence);
-                       }
-               }
-
-               if (type instanceof ParameterizedType) {
-                       ParameterizedType pt = (ParameterizedType) type;
-                       Type[] params = pt.getActualTypeArguments();
-                       for (Type param : params) {
-                               addTypeToImports(param, importedTypes, genTypePkg);
-                       }
-               }
-       }
-
-       public static List<String> createImportLines(
-                       Map<String, LinkedHashMap<String, Integer>> imports) {
-               List<String> importLines = new ArrayList<String>();
-
-               for (Map.Entry<String, LinkedHashMap<String, Integer>> entry : imports
-                               .entrySet()) {
-                       String typeName = entry.getKey();
-                       LinkedHashMap<String, Integer> typePkgMap = entry.getValue();
-                       String typePkg = typePkgMap.keySet().iterator().next();
-                       importLines.add("import " + typePkg + "." + typeName + SC);
-               }
-               return importLines;
-       }
+            return;
+        }
+        LinkedHashMap<String, Integer> packages = importedTypes.get(typeName);
+        if (packages == null) {
+            packages = new LinkedHashMap<String, Integer>();
+            packages.put(typePkg, 1);
+            importedTypes.put(typeName, packages);
+        } else {
+            Integer occurrence = packages.get(typePkg);
+            if (occurrence == null) {
+                packages.put(typePkg, 1);
+            } else {
+                occurrence++;
+                packages.put(typePkg, occurrence);
+            }
+        }
+
+        if (type instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) type;
+            Type[] params = pt.getActualTypeArguments();
+            for (Type param : params) {
+                addTypeToImports(param, importedTypes, genTypePkg);
+            }
+        }
+    }
+
+    public static List<String> createImportLines(
+            Map<String, LinkedHashMap<String, Integer>> imports) {
+        List<String> importLines = new ArrayList<String>();
+
+        for (Map.Entry<String, LinkedHashMap<String, Integer>> entry : imports
+                .entrySet()) {
+            String typeName = entry.getKey();
+            LinkedHashMap<String, Integer> typePkgMap = entry.getValue();
+            String typePkg = typePkgMap.keySet().iterator().next();
+            importLines.add("import " + typePkg + "." + typeName + SC);
+        }
+        return importLines;
+    }
 
 }
index 7ed1f9950383076e01dd7eda51e468ba2e7d1798..8bdf32706bef854692088ea601e2a3c2afe15e86 100644 (file)
@@ -138,4 +138,34 @@ module abstract-topology {
             }
         }
     }
-}
\ No newline at end of file
+    
+    identity crypto-base {
+        description "crypto-base description";
+    }
+    
+    identity crypto-alg {
+        base crypto-base;
+        description "crypto-alg description";
+    }
+    
+    grouping target {
+        container nodes {
+            leaf source {
+                type int8;
+            }
+            leaf target {
+                type int16;
+            }
+        }
+        leaf id {
+            type string;
+        }
+    }
+    
+    leaf idreftest {
+        type identityref {
+            base crypto-alg;
+        }
+    }
+    
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferIdentityObject.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferIdentityObject.java
new file mode 100644 (file)
index 0000000..80bed83
--- /dev/null
@@ -0,0 +1,6 @@
+package org.opendaylight.controller.sal.binding.model.api;
+
+public interface GeneratedTransferIdentityObject extends
+        GeneratedTransferObject {
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/WildcardType.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/WildcardType.java
new file mode 100644 (file)
index 0000000..ad08c2f
--- /dev/null
@@ -0,0 +1,5 @@
+package org.opendaylight.controller.sal.binding.model.api;
+
+public interface WildcardType extends Type  {
+
+}
index c01425407d0248e9b38039004cbddef179adb6cc..fc3495e184565f052f5b8a21a3f6577f1bac5e0f 100644 (file)
@@ -13,9 +13,9 @@ import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject
 
  */
 public interface GeneratedTOBuilder extends GeneratedTypeBuilder {
-    
+
     public boolean addExtendsType(final GeneratedTransferObject genTransObj);
-    
+
     public GeneratedPropertyBuilder addProperty(final String name);
 
     public boolean addEqualsIdentity(final GeneratedPropertyBuilder property);
@@ -26,4 +26,7 @@ public interface GeneratedTOBuilder extends GeneratedTypeBuilder {
 
     @Override
     public GeneratedTransferObject toInstance();
+
+    public GeneratedTransferObject toIdentityInstance();
+
 }
index 1c4a4acde47907545a63001102c251357be8cd03..c295c0eafdc824f68b04249f463cbc4630a42c10 100644 (file)
@@ -19,9 +19,13 @@ import org.opendaylight.controller.yang.parser.util.RefineHolder;
  */
 public interface UsesNodeBuilder extends Builder {
 
-    String getGroupingPathString();
+    String getGroupingName();
 
-    SchemaPath getGroupingPath();
+    void setGroupingPath(SchemaPath groupingPath);
+
+    SchemaPath getPath();
+
+    void setPath(SchemaPath path);
 
     Set<AugmentationSchemaBuilder> getAugmentations();
 
index e5ba8b17ccfe1f872070e491cf9c6396d8623557..775751a166ef7d2c58a9565d3cd9bb1bef5692c4 100644 (file)
@@ -68,6 +68,11 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
         return childNodes;
     }
 
+    @Override
+    public Set<GroupingBuilder> getGroupings() {
+        return groupings;
+    }
+
     @Override
     public void addGrouping(GroupingBuilder grouping) {
         groupings.add(grouping);
index ba9609b4db7f03eea305ae6b64bda80bc66b5fba..ec9c35c1bd37c14f97cc93994174bfb10c7f384d 100644 (file)
@@ -290,6 +290,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder
             }
         }
 
+        @Override
         public String getDefault() {
             return defaultStr;
         }
@@ -298,6 +299,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder
             this.defaultStr = defaultStr;
         }
 
+        @Override
         public String getUnits() {
             return unitsStr;
         }
index 67e4c6fb72cef7e1e1dd5d566a72992fb31dea6e..fa307972d49c7be12e57a12f7d9a9901881075b5 100644 (file)
@@ -240,6 +240,17 @@ public class ModuleBuilder implements Builder {
         return typedefs;
     }
 
+    public Set<GroupingBuilder> getModuleGroupings() {
+        final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();
+        for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings
+                .entrySet()) {
+            if (entry.getKey().size() == 2) {
+                groupings.add(entry.getValue());
+            }
+        }
+        return groupings;
+    }
+
     public String getName() {
         return name;
     }
index 5b9638eb63dc715a7b58a6b810fe6095810fa938..6cbcec1054a1b58256fe4cec1e6731cce7ef0d41 100644 (file)
@@ -103,6 +103,10 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder,
         addedTypedefs.add(type);
     }
 
+    public Set<GroupingBuilder> getGroupings() {
+        return addedGroupings;
+    }
+
     public void addGrouping(GroupingBuilder grouping) {
         addedGroupings.add(grouping);
     }
index dba747db1dd9bad3aa31a3d265279119d8434b85..850938161bf4c25cc30fd5d7e7270d0056d9f596 100644 (file)
@@ -15,7 +15,6 @@ import java.util.List;
 import java.util.Map;\r
 import java.util.Set;\r
 \r
-import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.model.api.AugmentationSchema;\r
 import org.opendaylight.controller.yang.model.api.SchemaNode;\r
 import org.opendaylight.controller.yang.model.api.SchemaPath;\r
@@ -27,25 +26,25 @@ import org.opendaylight.controller.yang.parser.util.RefineHolder;
 \r
 public final class UsesNodeBuilderImpl implements UsesNodeBuilder {\r
     private boolean isBuilt;\r
-    private final UsesNodeImpl instance;\r
+    private UsesNodeImpl instance;\r
     private final int line;\r
-    private final String groupingPathStr;\r
-    private final SchemaPath groupingPath;\r
+    private SchemaPath schemaPath;\r
+    private final String groupingName;\r
+    private SchemaPath groupingPath;\r
     private boolean augmenting;\r
     private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<AugmentationSchemaBuilder>();\r
     private List<SchemaNodeBuilder> refineBuilders = new ArrayList<SchemaNodeBuilder>();\r
     private List<RefineHolder> refines = new ArrayList<RefineHolder>();\r
 \r
-    public UsesNodeBuilderImpl(final String groupingPathStr, final int line) {\r
-        this.groupingPathStr = groupingPathStr;\r
-        this.groupingPath = parseUsesPath(groupingPathStr);\r
+    public UsesNodeBuilderImpl(final String groupingName, final int line) {\r
+        this.groupingName = groupingName;\r
         this.line = line;\r
-        instance = new UsesNodeImpl(groupingPath);\r
     }\r
 \r
     @Override\r
     public UsesNode build() {\r
         if (!isBuilt) {\r
+            instance = new UsesNodeImpl(groupingPath);\r
             instance.setAugmenting(augmenting);\r
 \r
             // AUGMENTATIONS\r
@@ -74,13 +73,23 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
     }\r
 \r
     @Override\r
-    public String getGroupingPathString() {\r
-        return groupingPathStr;\r
+    public void setGroupingPath(SchemaPath groupingPath) {\r
+        this.groupingPath = groupingPath;\r
     }\r
 \r
     @Override\r
-    public SchemaPath getGroupingPath() {\r
-        return groupingPath;\r
+    public SchemaPath getPath() {\r
+        return schemaPath;\r
+    }\r
+\r
+    @Override\r
+    public void setPath(SchemaPath path) {\r
+        this.schemaPath = path;\r
+    }\r
+\r
+    @Override\r
+    public String getGroupingName() {\r
+        return groupingName;\r
     }\r
 \r
     @Override\r
@@ -123,23 +132,6 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
         refines.add(refine);\r
     }\r
 \r
-    private SchemaPath parseUsesPath(final String groupingPathStr) {\r
-        final String[] splittedPath = groupingPathStr.split("/");\r
-        final List<QName> path = new ArrayList<QName>();\r
-        QName name;\r
-        for (String pathElement : splittedPath) {\r
-            final String[] splittedElement = pathElement.split(":");\r
-            if (splittedElement.length == 1) {\r
-                name = new QName(null, null, null, splittedElement[0]);\r
-            } else {\r
-                name = new QName(null, null, splittedElement[0],\r
-                        splittedElement[1]);\r
-            }\r
-            path.add(name);\r
-        }\r
-        final boolean absolute = groupingPathStr.startsWith("/");\r
-        return new SchemaPath(path, absolute);\r
-    }\r
 \r
     private final class UsesNodeImpl implements UsesNode {\r
         private final SchemaPath groupingPath;\r
index 4520405bbebc615e71ef6749016d11c31e417a95..94437170f4be3c8ef91ae774debd26cb1d4f8963 100644 (file)
@@ -761,15 +761,15 @@ public final class YangParserImpl implements YangModelParser {
                 .getUsesNodes();
         for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses
                 .entrySet()) {
-            final List<String> key = entry.getKey();
             final UsesNodeBuilder usesNode = entry.getValue();
             final int line = usesNode.getLine();
 
-            final String groupingName = key.get(key.size() - 1);
+            GroupingBuilder targetGrouping = getTargetGrouping(usesNode, modules, module);
+            usesNode.setGroupingPath(targetGrouping.getPath());
 
             for (RefineHolder refine : usesNode.getRefines()) {
                 SchemaNodeBuilder refineTarget = getRefineNodeBuilderCopy(
-                        groupingName, refine, modules, module);
+                        targetGrouping, refine, modules, module);
                 ParserUtils.checkRefine(refineTarget, refine);
                 ParserUtils.refineDefault(refineTarget, refine, line);
                 if (refineTarget instanceof LeafSchemaNodeBuilder) {
@@ -805,6 +805,82 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
+    private GroupingBuilder getTargetGrouping(
+            final UsesNodeBuilder usesBuilder,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module) {
+        final int line = usesBuilder.getLine();
+        String groupingString = usesBuilder.getGroupingName();
+        String groupingPrefix;
+        String groupingName;
+
+        if(groupingString.contains(":")) {
+            String[] splitted = groupingString.split(":");
+            if(splitted.length != 2 || groupingString.contains("/")) {
+                throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
+            }
+            groupingPrefix = splitted[0];
+            groupingName = splitted[1];
+        } else {
+            groupingPrefix = module.getPrefix();
+            groupingName = groupingString;
+        }
+
+        ModuleBuilder dependentModule = null;
+        if(groupingPrefix.equals(module.getPrefix())) {
+            dependentModule = module;
+        } else {
+            dependentModule = findDependentModule(modules, module, groupingPrefix, line);
+        }
+
+
+        List<QName> path = usesBuilder.getPath().getPath();
+        GroupingBuilder result = null;
+        Set<GroupingBuilder> groupings = dependentModule.getModuleGroupings();
+        result = findGrouping(groupings, groupingName);
+
+        if (result == null) {
+            Builder currentNode = null;
+            final List<String> currentPath = new ArrayList<String>();
+            currentPath.add(dependentModule.getName());
+
+            for (int i = 0; i < path.size(); i++) {
+                QName qname = path.get(i);
+                currentPath.add(qname.getLocalName());
+                currentNode = dependentModule.getModuleNode(currentPath);
+
+                if (currentNode instanceof RpcDefinitionBuilder) {
+                    groupings = ((RpcDefinitionBuilder) currentNode).getGroupings();
+                } else if (currentNode instanceof DataNodeContainerBuilder) {
+                    groupings = ((DataNodeContainerBuilder) currentNode).getGroupings();
+                } else {
+                    groupings = Collections.emptySet();
+                }
+
+                result = findGrouping(groupings, groupingName);
+                if (result != null) {
+                    break;
+                }
+            }
+        }
+
+        if (result != null) {
+            return result;
+        }
+        throw new YangParseException(module.getName(), line,
+                "Referenced grouping '" + groupingName + "' not found.");
+    }
+
+    private GroupingBuilder findGrouping(Set<GroupingBuilder> groupings,
+            String name) {
+        for (GroupingBuilder grouping : groupings) {
+            if (grouping.getQName().getLocalName().equals(name)) {
+                return grouping;
+            }
+        }
+        return null;
+    }
+
     /**
      * Find original builder of node to refine and return copy of this builder.
      * <p>
@@ -825,11 +901,11 @@ public final class YangParserImpl implements YangModelParser {
      *         otherwise
      */
     private SchemaNodeBuilder getRefineNodeBuilderCopy(
-            final String groupingPath, final RefineHolder refine,
+            final GroupingBuilder targetGrouping, final RefineHolder refine,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
         Builder result = null;
-        final Builder lookedUpBuilder = findRefineTargetBuilder(groupingPath,
+        final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping,
                 refine, modules, module);
         if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) {
             result = ParserUtils
@@ -876,28 +952,11 @@ public final class YangParserImpl implements YangModelParser {
      * @return Builder object of refine node if it is present in grouping, null
      *         otherwise
      */
-    private Builder findRefineTargetBuilder(final String groupingPath,
+    private Builder findRefineTargetBuilder(final GroupingBuilder builder,
             final RefineHolder refine,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
         final String refineNodeName = refine.getName();
-        final SchemaPath path = ParserUtils.parseUsesPath(groupingPath);
-        final List<String> builderPath = new ArrayList<String>();
-        String prefix = null;
-        for (QName qname : path.getPath()) {
-            builderPath.add(qname.getLocalName());
-            prefix = qname.getPrefix();
-        }
-        if (prefix == null) {
-            prefix = module.getPrefix();
-        }
-
-        final ModuleBuilder dependentModule = findDependentModule(modules,
-                module, prefix, refine.getLine());
-        builderPath.add(0, dependentModule.getName());
-        final GroupingBuilder builder = dependentModule
-                .getGrouping(builderPath);
-
         Builder result = builder.getChildNode(refineNodeName);
         if (result == null) {
             Set<GroupingBuilder> grps = builder.getGroupings();
index 40a3289745f10a4010df3cd1797bb081f034c714..1c01cd4a82b56cdbc016ed0e3f0c23eec5b833d8 100644 (file)
@@ -410,15 +410,15 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         GroupingBuilder builder = moduleBuilder.addGrouping(groupQName,
                 actualPath, ctx.getStart().getLine());
         moduleBuilder.enterNode(builder);
-        updatePath("grouping");
         updatePath(groupName);
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision,
+                yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
     }
 
     @Override
     public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
         String actContainer = actualPath.pop();
-        actContainer += "-" + actualPath.pop();
         logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
     }
@@ -495,8 +495,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String groupingPathStr = stringFromNode(ctx);
         UsesNodeBuilder builder = moduleBuilder.addUsesNode(groupingPathStr,
                 actualPath, ctx.getStart().getLine());
+
         moduleBuilder.enterNode(builder);
         updatePath(groupingPathStr);
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision,
+                yangModelPrefix));
     }
 
     @Override
index 8361d4715631ff4e2afad6d7f588ba17c1b86027..d38bc5e7adf22f74f6678e9614d38e2872a8099d 100644 (file)
@@ -907,7 +907,7 @@ public final class ParserUtils {
 
     public static UsesNodeBuilder copyUsesNodeBuilder(UsesNodeBuilder old) {
         final UsesNodeBuilder copy = new UsesNodeBuilderImpl(
-                old.getGroupingPathString(), old.getLine());
+                old.getGroupingName(), old.getLine());
         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
             copy.addAugment(augment);
         }
diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/BaseIdentity.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/BaseIdentity.java
new file mode 100644 (file)
index 0000000..004287a
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.yang.binding;
+
+public abstract class BaseIdentity {
+    
+    protected BaseIdentity() {
+    }
+
+}
index df111acf0854603d453f1c1bd6cefb40a449d48c..7c26531f37efbddd520b31623539d011511719f7 100644 (file)
@@ -8,29 +8,30 @@ import java.util.Set;
 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.controller.yang.model.api.DataNodeContainer;
 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;
 import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
 
 public class DataNodeIterator implements Iterator<DataSchemaNode> {
-    
+
     private final DataNodeContainer container;
     private List<ListSchemaNode> allLists;
     private List<ContainerSchemaNode> allContainers;
     private List<LeafSchemaNode> allLeafs;
     private List<LeafListSchemaNode> allLeafLists;
     private List<DataSchemaNode> allChilds;
-    
+
     public DataNodeIterator(final DataNodeContainer container) {
         if (container == null) {
             throw new IllegalArgumentException("Data Node Container MUST be specified and cannot be NULL!");
         }
-        
+
         init();
         this.container = container;
         traverse(this.container);
     }
-    
+
     private void init() {
         this.allContainers = new ArrayList<ContainerSchemaNode>();
         this.allLists = new ArrayList<ListSchemaNode>();
@@ -38,28 +39,28 @@ public class DataNodeIterator implements Iterator<DataSchemaNode> {
         this.allLeafLists = new ArrayList<LeafListSchemaNode>();
         this.allChilds = new ArrayList<DataSchemaNode>();
     }
-    
+
     public List<ContainerSchemaNode> allContainers() {
         return allContainers;
     }
-    
+
     public List<ListSchemaNode> allLists() {
         return allLists;
     }
-    
+
     public List<LeafSchemaNode> allLeafs() {
         return allLeafs;
     }
-    
+
     public List<LeafListSchemaNode> allLeafLists() {
         return allLeafLists;
     }
-    
+
     private void traverse(final DataNodeContainer dataNode) {
         if (dataNode == null) {
             return;
         }
-        
+
         final Set<DataSchemaNode> childs = dataNode.getChildNodes();
         if (childs != null) {
             for (DataSchemaNode childNode : childs) {
@@ -83,15 +84,21 @@ public class DataNodeIterator implements Iterator<DataSchemaNode> {
                     allLeafLists.add(leafList);
                 }
             }
-            return;
+        }
+
+        final Set<GroupingDefinition> groupings = dataNode.getGroupings();
+        if(groupings != null) {
+            for(GroupingDefinition grouping : groupings) {
+                traverse(grouping);
+            }
         }
     }
-    
+
     @Override
     public boolean hasNext() {
         if (container.getChildNodes() != null) {
             Set<DataSchemaNode> childs = container.getChildNodes();
-            
+
             if ((childs != null) && !childs.isEmpty()) {
                 return childs.iterator().hasNext();
             }