Coverage Report - uk.co.badgersinfoil.asxsd.components.ArrayElementDeclarationComponent
 
Classes in this File Line Coverage Branch Coverage Complexity
ArrayElementDeclarationComponent
95% 
100% 
2.429
 
 1  
 /*
 2  
  * Copyright (c) 2007 David Holroyd
 3  
  */
 4  
 
 5  
 package uk.co.badgersinfoil.asxsd.components;
 6  
 
 7  
 import org.eclipse.xsd.XSDConcreteComponent;
 8  
 import org.eclipse.xsd.XSDElementDeclaration;
 9  
 import uk.co.badgersinfoil.asxsd.BasicMappingFunction;
 10  
 import uk.co.badgersinfoil.asxsd.CodegenContext;
 11  
 import uk.co.badgersinfoil.asxsd.CodegenRole;
 12  
 import uk.co.badgersinfoil.asxsd.MappingFunction;
 13  
 import uk.co.badgersinfoil.asxsd.MarshalBuilder;
 14  
 import uk.co.badgersinfoil.asxsd.StringUtils;
 15  
 import uk.co.badgersinfoil.asxsd.TypeBuilder;
 16  
 import uk.co.badgersinfoil.asxsd.TypeDescriptor;
 17  
 import uk.co.badgersinfoil.asxsd.UnmarshalBuilder;
 18  
 import uk.co.badgersinfoil.asxsd.XSDUtils;
 19  
 import uk.co.badgersinfoil.metaas.dom.ASArg;
 20  
 import uk.co.badgersinfoil.metaas.dom.ASClassType;
 21  
 import uk.co.badgersinfoil.metaas.dom.ASCompilationUnit;
 22  
 import uk.co.badgersinfoil.metaas.dom.ASConstants;
 23  
 import uk.co.badgersinfoil.metaas.dom.ASField;
 24  
 import uk.co.badgersinfoil.metaas.dom.ASMethod;
 25  
 import uk.co.badgersinfoil.metaas.dom.StatementContainer;
 26  
 import uk.co.badgersinfoil.metaas.dom.Visibility;
 27  
 
 28  16
 public class ArrayElementDeclarationComponent extends AbstractMappingComponent {
 29  
 
 30  
         public TypeDescriptor createTypeDescriptor(CodegenContext context,
 31  
                                                 XSDConcreteComponent component)
 32  
         {
 33  1
                 XSDElementDeclaration elementDecl = (XSDElementDeclaration)component;
 34  1
                 XSDElementDeclaration listElement = XSDUtils.getElementIfContainerForList(elementDecl);
 35  1
                 TypeDescriptor elementType = context.typeDescriptorFor(listElement);
 36  1
                 String doc = "Elements of type {@link " + elementType.getTypeName()+"}";
 37  1
                 return new TypeDescriptor(ASConstants.TYPE_ARRAY, true, doc, elementDecl);
 38  
         }
 39  
 
 40  
         public ASCompilationUnit createType(CodegenContext context,
 41  
                                             XSDConcreteComponent component)
 42  
         {
 43  
                 // no implementation (built in type)
 44  1
                 return null;
 45  
         }
 46  
 
 47  
         public boolean willAccept(XSDConcreteComponent component) {
 48  2395
                 return component instanceof XSDElementDeclaration
 49  
                     && XSDUtils.getElementIfContainerForList((XSDElementDeclaration)component)!=null
 50  
                     && XSDUtils.isAnonymous(((XSDElementDeclaration)component).getType());
 51  
         }
 52  
 
 53  
         public void generateCode(CodegenContext context, final XSDConcreteComponent component) {
 54  3
                 XSDElementDeclaration elementDecl = (XSDElementDeclaration)component;
 55  3
                 CodegenRole role = context.getCurrentRole();
 56  3
                 if (role == CodegenRole.MARSHAL) {
 57  1
                         StatementContainer containingBlock = context.getCurrentMethodCode();
 58  1
                         XSDElementDeclaration listElement = XSDUtils.getElementIfContainerForList(elementDecl);
 59  1
                         String listName = "_"+context.variableNameFor(elementDecl);
 60  1
                         containingBlock.addStmt("var "+listName+":XML = <"+elementDecl.getName()+"/>");
 61  1
                         TypeDescriptor typeDesc = context.typeDescriptorFor(listElement);
 62  1
                         String elementType = typeDesc.getTypeName();
 63  1
                         String childVarName = listName+"_child";
 64  1
                         String accessExpr = MarshalBuilder.getCurrentSourceExpr(context);
 65  1
                         StatementContainer forEachLoop = containingBlock.newForEachIn("var "+childVarName+":"+elementType, accessExpr);
 66  1
                         context.pushAttrScope();
 67  1
                         context.setCurrentMethodCode(forEachLoop);
 68  1
                         MarshalBuilder.setCurrentSourceExpr(context, childVarName);
 69  1
                         MarshalBuilder.setCurrentTargetParentElementExpr(context, listName);
 70  
 
 71  1
                         context.generateCode(listElement);
 72  
 
 73  
                         // switch back to the original block,
 74  1
                         context.popAttrScope();
 75  1
                         String targetParentExpr = MarshalBuilder.getCurrentTargetParentElementExpr(context);
 76  1
                         containingBlock.addStmt(targetParentExpr+".appendChild("+listName+")");
 77  1
                 } else if (role == CodegenRole.UNMARSHAL) {
 78  1
                         context.generateCode(elementDecl.getType());
 79  1
                 } else if (role == CodegenRole.TYPE) {
 80  1
                         ASCompilationUnit unit = TypeBuilder.getCurrentTypeCompilationUnit(context);
 81  1
                         ASClassType clazz = (ASClassType)unit.getType();
 82  1
                         TypeDescriptor typeDesc = context.typeDescriptorFor(elementDecl.getContainer());
 83  1
                         ASField field = clazz.newField(context.variableNameFor(elementDecl.getResolvedElementDeclaration()), Visibility.PUBLIC, typeDesc.getTypeName());
 84  1
                         field.setDescription(typeDesc.getDocumentation());                        
 85  1
                 } else {
 86  0
                         throw new RuntimeException(getClass().getName()+" does not suppport operation generateCodeFor(role="+role+")");
 87  
                 }
 88  3
         }
 89  
 
 90  
         public MappingFunction createFunctionRef(CodegenContext context,
 91  
                                               XSDConcreteComponent component)
 92  
         {
 93  1
                 XSDElementDeclaration elementDecl = (XSDElementDeclaration)component;
 94  1
                 CodegenRole role = context.getCurrentRole();
 95  1
                 if (role == CodegenRole.UNMARSHAL) {
 96  1
                         UnmarshalBuilder builder = context.getUnmarshalBuilder();
 97  1
                         ASCompilationUnit unit = builder.getClassForNamespace(elementDecl.getTargetNamespace());
 98  1
                         ASClassType clazz = (ASClassType)unit.getType();
 99  1
                         String name = StringUtils.sanitize(elementDecl.getName());
 100  1
                         String methodName = "unmarshal" + name;
 101  
                         String qname;
 102  1
                         if (unit.getPackageName() != null) {
 103  1
                                 qname = unit.getPackageName()+"."+clazz.getName()+"."+methodName;
 104  
                         } else {
 105  0
                                 qname = clazz.getName()+"."+methodName;
 106  
                         }
 107  1
                         return new BasicMappingFunction(qname);
 108  
                 }
 109  0
                 return super.createFunctionRef(context, component);
 110  
         }
 111  
 
 112  
         public ASMethod createFunction(CodegenContext context,
 113  
                                        XSDConcreteComponent component)
 114  
         {
 115  1
                 XSDElementDeclaration elementDecl = (XSDElementDeclaration)component;
 116  1
                 CodegenRole role = context.getCurrentRole();
 117  1
                 if (role == CodegenRole.UNMARSHAL) {
 118  1
                         UnmarshalBuilder builder = context.getUnmarshalBuilder();
 119  1
                         ASCompilationUnit unit = builder.getClassForNamespace(elementDecl.getTargetNamespace());
 120  1
                         ASClassType clazz = (ASClassType)unit.getType();
 121  1
                         String name = StringUtils.sanitize(elementDecl.getName());
 122  1
                         String methodName = "unmarshal" + name;
 123  1
                         TypeDescriptor typeDesc = context.typeDescriptorFor(elementDecl);
 124  1
                         ASMethod meth = clazz.newMethod(methodName, Visibility.PUBLIC, typeDesc.getTypeName());
 125  1
                         ASArg arg = meth.addParam("thisElement", "XML");
 126  1
                         String doc = "a &lt;" + elementDecl.getName()+"/&gt; element";
 127  1
                         arg.setDescription(doc);
 128  1
                         if (!elementDecl.isGlobal()) {
 129  1
                                 meth.setVisibility(Visibility.PRIVATE);
 130  
                         }
 131  1
                         meth.setStatic(true);
 132  1
                         context.pushAttrScope();
 133  1
                         context.setCurrentMethodCode(meth);
 134  1
                         UnmarshalBuilder.setCurrentSourceExpr(context, arg.getName());
 135  1
                         context.generateCode(elementDecl);
 136  1
                         context.popAttrScope();
 137  1
                         return meth;
 138  
                 }
 139  0
                 return super.createFunction(context, component);
 140  
         }
 141  
 
 142  
         public String variableNameFor(CodegenContext context,
 143  
                                       XSDConcreteComponent component)
 144  
         {
 145  4
                 XSDElementDeclaration elementDecl = (XSDElementDeclaration)component;
 146  4
                 return context.toVariableName(elementDecl.getName());
 147  
         }
 148  
 }