Coverage Report - uk.co.badgersinfoil.asxsd.components.OptionallyOccuringParticleComponent
 
Classes in this File Line Coverage Branch Coverage Complexity
OptionallyOccuringParticleComponent
93% 
100% 
1.833
 
 1  
 /*
 2  
  * Copyright (c) 2007 David Holroyd
 3  
  */
 4  
 
 5  
 package uk.co.badgersinfoil.asxsd.components;
 6  
 
 7  
 import org.eclipse.xsd.XSDElementDeclaration;
 8  
 import org.eclipse.xsd.XSDParticle;
 9  
 import org.eclipse.xsd.XSDParticleContent;
 10  
 import uk.co.badgersinfoil.asxsd.CodegenContext;
 11  
 import uk.co.badgersinfoil.asxsd.CodegenRole;
 12  
 import uk.co.badgersinfoil.asxsd.MarshalBuilder;
 13  
 import uk.co.badgersinfoil.asxsd.TypeDescriptor;
 14  
 import uk.co.badgersinfoil.metaas.ActionScriptFactory;
 15  
 import uk.co.badgersinfoil.metaas.dom.ASExpression;
 16  
 import uk.co.badgersinfoil.metaas.dom.StatementContainer;
 17  
 
 18  
 
 19  15
 public class OptionallyOccuringParticleComponent extends AbstractParticleComponent {
 20  
 
 21  
         protected void generateCodeFor(CodegenContext context,
 22  
                                        XSDParticle particle)
 23  
         {
 24  21
                 CodegenRole role = context.getCurrentRole();
 25  21
                 XSDParticleContent content = particle.getContent();
 26  21
                 if (role == CodegenRole.UNMARSHAL) {
 27  7
                         StatementContainer block = context.getCurrentMethodCode();
 28  7
                         block = unmarshalDetectStmt(context, content, block);
 29  7
                         context.pushAttrScope();
 30  7
                         context.setCurrentMethodCode(block);
 31  7
                         context.generateCode(content);
 32  7
                         context.popAttrScope();
 33  7
                 } else if (role == CodegenRole.MARSHAL) {
 34  7
                         StatementContainer containingBlock = context.getCurrentMethodCode();
 35  7
                         ASExpression detectExpr= marshalDetectExpr(context, content);
 36  7
                         StatementContainer ifBlock = containingBlock.newIf(detectExpr);
 37  7
                         context.pushAttrScope();
 38  7
                         String src = MarshalBuilder.getCurrentSourceExpr(context);
 39  
                         String access;
 40  7
                         if (content instanceof XSDElementDeclaration) {
 41  5
                                 access = src + "." + context.variableNameFor(content);
 42  
                         } else {
 43  2
                                 access = src;
 44  
                         }
 45  7
                         MarshalBuilder.setCurrentSourceExpr(context, access);
 46  7
                         context.setCurrentMethodCode(ifBlock);
 47  
 
 48  7
                         context.generateCode(content);
 49  
 
 50  
                         // switch back to the original block,
 51  7
                         context.popAttrScope();
 52  7
                 } else if (role == CodegenRole.TYPE) {
 53  7
                         context.generateCode(content);
 54  
                 } else {
 55  0
                         throw new RuntimeException(getClass().getName()+" does not suppport operation generateCodeFor(role="+role+")");
 56  
                 }
 57  21
         }
 58  
 
 59  
         private StatementContainer unmarshalDetectStmt(CodegenContext context,
 60  
                                                        XSDParticleContent content,
 61  
                                                        StatementContainer block)
 62  
         {
 63  7
                 ActionScriptFactory fact = context.getFactory();
 64  7
                 ASExpression childLimit = fact.newExpression("_seq<_children.length()");
 65  7
                 ASExpression detect = unmarshalDetectExpr(context, content);
 66  7
                 ASExpression conditional = fact.newAndExpression(childLimit, detect);
 67  
                 // TODO: don't strictly need to test that there are remaining elements if we know there should be mandatory elements following this optional one,
 68  7
                 return block.newIf(conditional);
 69  
         }
 70  
 
 71  
         private ASExpression unmarshalDetectExpr(CodegenContext context,
 72  
                                     XSDParticleContent content)
 73  
         {
 74  7
                 context.pushAttrScope();
 75  7
                 context.setCurrentRole(CodegenRole.UNMARSHAL_DETECT);
 76  7
                 ASExpression detect = context.createExpression(content);
 77  7
                 context.popAttrScope();
 78  7
                 return detect;
 79  
         }
 80  
 
 81  
         private ASExpression marshalDetectExpr(CodegenContext context,
 82  
                                     XSDParticleContent content)
 83  
         {
 84  7
                 context.pushAttrScope();
 85  7
                 context.setCurrentRole(CodegenRole.MARSHAL_DETECT);
 86  7
                 ASExpression detect = context.createExpression(content);
 87  7
                 context.popAttrScope();
 88  7
                 return detect;
 89  
         }
 90  
 
 91  
         protected TypeDescriptor typeDescriptorFor(CodegenContext context,
 92  
                         XSDParticle particle) {
 93  
                 // just return the type-desc for the particle's content
 94  0
                 XSDParticleContent partContent = particle.getContent();
 95  0
                 return context.typeDescriptorFor(partContent);
 96  
         }
 97  
 
 98  
         protected boolean willAcceptParticle(XSDParticle particle) {
 99  282
                 return particle.getMaxOccurs()==1
 100  
                     && particle.getMinOccurs()==0;
 101  
         }
 102  
 }