Ignore:
Timestamp:
07/17/15 09:52:27 (9 years ago)
Author:
sherbold
Message:
  • updated interaction generation to be able to handle anonymous sequence and choice elements in the model that represent XSD sequences and choices to some degree. This is just a workaround at the current stage
  • interaction generation now supports enumeration data types
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/UMLInteractionCreator.java

    r2009 r2010  
    2323 
    2424import org.apache.commons.lang.mutable.MutableInt; 
     25import org.eclipse.emf.common.util.EList; 
    2526import org.eclipse.uml2.uml.CallConcurrencyKind; 
    2627import org.eclipse.uml2.uml.Component; 
    2728import org.eclipse.uml2.uml.Connector; 
    2829import org.eclipse.uml2.uml.DataType; 
     30import org.eclipse.uml2.uml.Element; 
     31import org.eclipse.uml2.uml.Enumeration; 
     32import org.eclipse.uml2.uml.Generalization; 
    2933import org.eclipse.uml2.uml.InstanceSpecification; 
    3034import org.eclipse.uml2.uml.InstanceValue; 
     
    4549import org.eclipse.uml2.uml.PrimitiveType; 
    4650import org.eclipse.uml2.uml.Property; 
     51import org.eclipse.uml2.uml.Relationship; 
    4752import org.eclipse.uml2.uml.Slot; 
     53import org.eclipse.uml2.uml.Type; 
    4854import org.eclipse.uml2.uml.UMLPackage; 
    49 import org.w3c.dom.Element; 
    5055 
    5156import de.ugoe.cs.autoquest.eventcore.Event; 
     
    7883     */ 
    7984    private final boolean useRandomMsgBodies; 
    80      
    81     /** 
    82      * TODO 
     85 
     86    /** 
     87     * a cache of the already created instance specification; used to create the overall number of generated specifications 
    8388     */ 
    8489    private final Map<String, InstanceSpecification> instanceSpecificationCache; 
    85      
     90 
    8691    /** 
    8792     * <p> 
     
    116121     */ 
    117122    public Interaction createInteraction(List<Event> sequence, String interactionName) { 
     123        Console.traceln(Level.FINEST, "creating interaction: " + interactionName); 
    118124        final Component testContext = UMLUtils.fetchTestContext(model, testContextName); 
    119125        if (testContext == null) { 
     
    151157        int i = 0; 
    152158        for (Event event : sequence) { 
     159            Console.traceln(Level.FINEST, "creating message for event: " + event.toString()); 
    153160            if (!(event.equals(Event.STARTEVENT) || event.equals(Event.ENDEVENT))) { 
    154161                String serviceName = SOAPUtils.getServiceNameFromEvent(event); 
     
    325332                                      String prefix) 
    326333    { 
    327         Element requestBody; 
     334        // printParameters(calledOperation); // FOR DEBUGGING 
     335        org.w3c.dom.Element requestBody; 
    328336        if (SOAPUtils.isSOAPRequest(event)) { 
    329337            requestBody = 
     
    343351            } 
    344352 
    345             String path = calledOperation.getName() + ":" + param.getType().getName(); 
     353            String path = calledOperation.getName() + ":" + getNormalizedTypeName(param.getType()); 
    346354            if ((UMLUtils.isInParameter(param) && SOAPUtils.isSOAPRequest(event)) || 
    347355                (UMLUtils.isOutParameter(param) && SOAPUtils.isSOAPResponse(event))) 
     
    356364                    (InstanceSpecification) instSpecPkg 
    357365                        .createPackagedElement(prefix + "instspec" + instSpecNumber.intValue() + 
    358                                                    "_" + param.getType().getName(), 
     366                                                   "_" + getNormalizedTypeName(param.getType()), 
    359367                                               UMLPackage.Literals.INSTANCE_SPECIFICATION); 
    360368                instSpecParameters.getClassifiers().add((DataType) param.getType()); 
     
    368376                    if (internalParameter.getType() instanceof DataType) { 
    369377                        List<org.w3c.dom.Element> paramNodes = 
    370                             SOAPUtils.getMatchingChildNode(internalParameter.getType().getName(), 
    371                                                           requestBody); 
     378                            SOAPUtils.getMatchingChildNode(getNormalizedTypeName(internalParameter 
     379                                .getType()), requestBody); 
    372380                        int multiplicityChosen = paramNodes.size(); 
    373381 
     
    397405                                                 internalParameter.getType(), 
    398406                                                 UMLPackage.Literals.INSTANCE_VALUE); 
    399                             InstanceSpecification instSpec = createInstanceSpecification((DataType) internalParameter 
    400                                                                                         .getType(), 
    401                                                                                         instSpecPkg, prefix, 
    402                                                                                         instSpecNumber, paramNode, 
    403                                                                                         path); 
     407                            InstanceSpecification instSpec = 
     408                                createInstanceSpecification((DataType) internalParameter.getType(), 
     409                                                            instSpecPkg, prefix, instSpecNumber, 
     410                                                            paramNode, path); 
    404411                            value.setInstance(instSpec); 
    405412                            /* 
     
    452459                                                              String path) 
    453460    { 
    454         if( instanceSpecificationCache.containsKey(SOAPUtils.getSerialization(currentNode)) ) { 
     461        if (instanceSpecificationCache.containsKey(SOAPUtils.getSerialization(currentNode))) { 
    455462            return instanceSpecificationCache.get(SOAPUtils.getSerialization(currentNode)); 
    456463        } 
     
    470477                createSlotPrimitiveType(instSpec, prop, currentNode, path); 
    471478            } 
     479            else if (prop.getType() instanceof Enumeration ) { 
     480                createSlotEnumeration(instSpec, prop, currentNode, path); 
     481            } 
    472482            else if (prop.getType() instanceof DataType) { 
    473                 List<org.w3c.dom.Element> attributeNodes = null; 
    474                 int multiplicityChosen = 0; 
    475                 if (currentNode != null) { 
    476                     attributeNodes = SOAPUtils.getMatchingChildNode(prop.getName(), currentNode); 
    477                     multiplicityChosen = attributeNodes.size(); 
    478                 } 
    479  
    480                 if (multiplicityChosen == 0 && prop.getLower() > 0) { 
     483                if( isXSDSequence(prop.getType()) ) { // XSD sequence, no real type 
     484                    System.out.println(SOAPUtils.getChildNodeNames(currentNode)); 
     485                    List<String> childNames = SOAPUtils.getChildNodeNames(currentNode); 
     486                    List<org.w3c.dom.Element> childNodes = SOAPUtils.getChildElements(currentNode); 
     487                    EList<Property> sequenceProperties = ((DataType) prop.getType()).getAllAttributes(); 
     488                    boolean sequenceIsMatch = true; 
     489                    if( sequenceProperties.size()==childNames.size()) { 
     490                        for(int i=0; sequenceIsMatch && i<sequenceProperties.size() ; i++) { 
     491                            Property propSeq = sequenceProperties.get(i); 
     492                            String currentChildName = childNames.get(i); 
     493                            if( isXSDChoice(propSeq.getType() ) ) { 
     494                                boolean choiceMatchFound = false; 
     495                                for( Property propChoice : ((DataType) propSeq.getType()).getAllAttributes() ) { 
     496                                    if( currentChildName.equals(propChoice.getName()) ) { 
     497                                        choiceMatchFound = true; 
     498                                    } 
     499                                } 
     500                                sequenceIsMatch &= choiceMatchFound; 
     501                            } else { 
     502                                sequenceIsMatch &= currentChildName.equals(propSeq.getName()); 
     503                            } 
     504                        } 
     505                        if( sequenceIsMatch ) { 
     506                            // this is the correct sequence, it matches; now appropriate data must be created 
     507                             
     508                            // first we create the slot and instance specification for the sequence 
     509                            Slot slot = instSpec.createSlot(); 
     510                            slot.setDefiningFeature(prop); 
     511                            InstanceValue value = 
     512                                (InstanceValue) slot.createValue(prop.getName(), prop.getType(), UMLPackage.Literals.INSTANCE_VALUE); 
     513                            InstanceSpecification instSpecSequence = 
     514                                    (InstanceSpecification) pkg 
     515                                        .createPackagedElement(prefix + prop.getName() + "_instspec" + instSpecNumber.intValue() + "_" + 
     516                                                                   type.getName(), 
     517                                                               UMLPackage.Literals.INSTANCE_SPECIFICATION); 
     518                            instSpecSequence.getClassifiers().add((DataType) prop.getType()); 
     519                            instSpecNumber.setValue(instSpecNumber.intValue() + 1); 
     520                            value.setInstance(instSpecSequence); 
     521                             
     522                            // now we create the slots and instance specifications for the elements of the sequence 
     523                            for(int i=0; i<sequenceProperties.size() ; i++) { 
     524                                Property propSeq = sequenceProperties.get(i); 
     525                                String currentChildName = childNames.get(i); 
     526                                slot = instSpecSequence.createSlot(); 
     527                                slot.setDefiningFeature(propSeq); 
     528                                value = (InstanceValue) slot.createValue(propSeq.getName(), propSeq.getType(), UMLPackage.Literals.INSTANCE_VALUE); 
     529                                if( isXSDChoice(propSeq.getType() ) ) { 
     530                                    // create the inner choice instance spec 
     531                                    InstanceSpecification instSpecSequenceChoice = (InstanceSpecification) pkg 
     532                                            .createPackagedElement(prefix + propSeq.getName() + "_instspec" + instSpecNumber.intValue() + "_" + 
     533                                                    propSeq.getType().getName(), 
     534                                                UMLPackage.Literals.INSTANCE_SPECIFICATION); 
     535                                    instSpecSequenceChoice.getClassifiers().add((DataType) propSeq.getType()); 
     536                                    instSpecNumber.setValue(instSpecNumber.intValue()+1); 
     537                                    value.setInstance(instSpecSequenceChoice); 
     538                                    for( Property propChoice : ((DataType) propSeq.getType()).getAllAttributes() ) { 
     539                                        if( currentChildName.equals(propChoice.getName()) ) { 
     540                                            slot = instSpecSequenceChoice.createSlot(); 
     541                                            slot.setDefiningFeature(propChoice); 
     542                                            value = (InstanceValue) slot.createValue(propChoice.getName(), propChoice.getType(), UMLPackage.Literals.INSTANCE_VALUE); 
     543                                            value.setInstance(createInstanceSpecification((DataType) propChoice.getType(), pkg, prefix, instSpecNumber, childNodes.get(i), path+"."+propChoice.getName())); 
     544                                            break; 
     545                                        } 
     546                                    } 
     547                                } else { 
     548                                    value.setInstance(createInstanceSpecification((DataType) propSeq.getType(), pkg, prefix, instSpecNumber, childNodes.get(i), path+"."+propSeq.getName())); 
     549                                } 
     550                            }  
     551                        } 
     552                        System.out.println(prop.getName() + " " + sequenceIsMatch); 
     553                    } 
     554                } 
     555                else if( isXSDChoice(prop.getType()) ) {  
     556                    // TODO implement handling of choices, if required for the MIDAS pilots 
     557                    Console.traceln(Level.SEVERE, "cannot handle choices that are the child elements of normal data types yet!"); 
     558                    Console.traceln(Level.SEVERE, "choice is ignored and no data is created."); 
     559                } else { 
     560                    List<org.w3c.dom.Element> attributeNodes = null; 
     561                    int multiplicityChosen = 0; 
    481562                    if (currentNode != null) { 
    482                         Console.traceln(Level.WARNING, 
    483                                         "required attribute not found in SOAP message: " + path + 
    484                                             "." + prop.getName()); 
    485                         Console 
    486                             .traceln(Level.WARNING, 
    487                                      "setting default values for this attribute and all its children"); 
    488                         Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 
    489                             SOAPUtils.getSerialization(currentNode)); 
     563                        attributeNodes = SOAPUtils.getMatchingChildNode(prop.getName(), currentNode); 
     564                        multiplicityChosen = attributeNodes.size(); 
    490565                    } 
    491                     multiplicityChosen = prop.getLower(); 
    492                 } 
    493                 for (int i = 0; i < multiplicityChosen; i++) { 
    494                     org.w3c.dom.Element attributeNode = null; 
    495                     if (attributeNodes != null && !attributeNodes.isEmpty()) { 
    496                         attributeNode = attributeNodes.get(i); 
     566     
     567                    if (multiplicityChosen == 0 && prop.getLower() > 0) { 
     568                        if (currentNode != null) { 
     569                            Console.traceln(Level.WARNING, 
     570                                            "required attribute not found in SOAP message: " + path + 
     571                                                "." + prop.getName()); 
     572                            Console 
     573                                .traceln(Level.WARNING, 
     574                                         "setting default values for this attribute and all its children"); 
     575                            Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 
     576                                SOAPUtils.getSerialization(currentNode)); 
     577                        } 
     578                        multiplicityChosen = prop.getLower(); 
    497579                    } 
    498  
    499                     Slot slot = instSpec.createSlot(); 
    500                     slot.setDefiningFeature(prop); 
    501  
    502                     InstanceValue value = 
    503                         (InstanceValue) slot.createValue(prop.getName() + "_" + i, prop.getType(), 
    504                                                          UMLPackage.Literals.INSTANCE_VALUE); 
    505                     value.setInstance(createInstanceSpecification((DataType) prop.getType(), pkg, 
    506                                                                   prefix, instSpecNumber, 
    507                                                                   attributeNode, 
    508                                                                   path + "." + prop.getName())); 
     580                    for (int i = 0; i < multiplicityChosen; i++) { 
     581                        org.w3c.dom.Element attributeNode = null; 
     582                        if (attributeNodes != null && !attributeNodes.isEmpty()) { 
     583                            attributeNode = attributeNodes.get(i); 
     584                        } 
     585     
     586                        Slot slot = instSpec.createSlot(); 
     587                        slot.setDefiningFeature(prop); 
     588     
     589                        InstanceValue value = 
     590                            (InstanceValue) slot.createValue(prop.getName() + "_" + i, prop.getType(), 
     591                                                             UMLPackage.Literals.INSTANCE_VALUE); 
     592                        value.setInstance(createInstanceSpecification((DataType) prop.getType(), pkg, 
     593                                                                      prefix, instSpecNumber, 
     594                                                                      attributeNode, 
     595                                                                      path + "." + prop.getName())); 
     596                    } 
    509597                } 
    510598            } 
     
    535623     *            used for warnings and debug information 
    536624     */ 
    537     private static void createSlotPrimitiveType(InstanceSpecification instSpec, 
    538                                                 Property prop, 
    539                                                 org.w3c.dom.Element currentNode, 
    540                                                 String path) 
     625    private void createSlotPrimitiveType(InstanceSpecification instSpec, 
     626                                         Property prop, 
     627                                         org.w3c.dom.Element currentNode, 
     628                                         String path) 
    541629    { 
    542630        List<String> attributeValues = SOAPUtils.getValuesFromElement(prop.getName(), currentNode); 
     
    562650            Slot slot = instSpec.createSlot(); 
    563651            slot.setDefiningFeature(prop); 
    564             if ("String".equals(prop.getType().getName())) { 
     652            if (isPrimitiveTypeOf(prop.getType(), "String")) { 
    565653                LiteralString value = 
    566654                    (LiteralString) slot.createValue(prop.getName(), null, 
     
    573661                } 
    574662            } 
    575             else if ("Integer".equals(prop.getType().getName())) { 
     663            else if (isPrimitiveTypeOf(prop.getType(), "Integer")) { 
    576664                LiteralInteger value = 
    577665                    (LiteralInteger) slot.createValue(prop.getName(), null, 
     
    584672                } 
    585673            } 
    586             else if ("Boolean".equals(prop.getType().getName())) { 
     674            else if (isPrimitiveTypeOf(prop.getType(), "Boolean")) { 
    587675                LiteralBoolean value = 
    588676                    (LiteralBoolean) slot.createValue(prop.getName(), null, 
     
    595683                } 
    596684            } 
    597             else if ("Real".equals(prop.getType().getName())) { 
     685            else if (isPrimitiveTypeOf(prop.getType(), "Real")) { 
    598686                LiteralReal value = 
    599687                    (LiteralReal) slot.createValue(prop.getName(), null, 
     
    610698                    prop.getType().getName()); 
    611699                throw new RuntimeException("unknown primitive type: " + prop.getType().getName()); 
     700            } 
     701        } 
     702    } 
     703     
     704    /** 
     705     * <p> 
     706     * Creates a {@link Slot} in an {@link InstanceSpecification} for an enumeration. 
     707     * </p> 
     708     *  
     709     * @param instSpec 
     710     *            instance specification to which the slot is added 
     711     * @param prop 
     712     *            property that describes the slot 
     713     * @param currentNode 
     714     *            DOM node from which is value for the slot is inferred 
     715     * @param path 
     716     *            used for warnings and debug information 
     717     */ 
     718    private void createSlotEnumeration(InstanceSpecification instSpec, 
     719                                         Property prop, 
     720                                         org.w3c.dom.Element currentNode, 
     721                                         String path) 
     722    { 
     723        List<String> attributeValues = SOAPUtils.getValuesFromElement(prop.getName(), currentNode); 
     724 
     725        if (attributeValues.isEmpty()) { 
     726            if (prop.getLower() == 0) { 
     727                // ignoring optional attribute 
     728                return; 
     729            } 
     730            else { 
     731                if (currentNode != null) { 
     732                    Console.traceln(Level.WARNING, 
     733                                    "required attribute not found in SOAP message: " + path + "." + 
     734                                        prop.getName()); 
     735                    Console.traceln(Level.WARNING, "setting default values for this attribute"); 
     736                    Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 
     737                        SOAPUtils.getSerialization(currentNode)); 
     738                } 
     739                attributeValues.add(null); 
     740            } 
     741        } 
     742        for (String attributeValue : attributeValues) { 
     743            Slot slot = instSpec.createSlot(); 
     744            slot.setDefiningFeature(prop); 
     745             
     746            InstanceValue value = (InstanceValue) slot.createValue(prop.getName(), null, UMLPackage.Literals.INSTANCE_VALUE); 
     747            if( attributeValue!=null ) { 
     748                value.setInstance(((Enumeration) prop.getType()).getOwnedLiteral(attributeValue)); 
     749                System.out.println("foo"); 
     750            } else { 
     751                throw new RuntimeException("cannot create enumeration literal with dummy value"); 
    612752            } 
    613753        } 
     
    642782    } 
    643783 
     784    /** 
     785     * <p> 
     786     * Checks if a type is a instance of a primitive type defined by its name, e.g., String, 
     787     * Integer, or Boolean. The functions also checks whether the type is a generalization. 
     788     * </p> 
     789     *  
     790     * @param type 
     791     *            type that is checked 
     792     * @param typeNam 
     793     *            name of the primitive type 
     794     * @return true if the type is of the specified primitive type; false otherwise 
     795     */ 
     796    private boolean isPrimitiveTypeOf(Type type, String typeName) { 
     797        if (typeName == null) { 
     798            throw new RuntimeException("typename must not be null"); 
     799        } 
     800        if (!(type instanceof PrimitiveType)) { 
     801            return false; 
     802        } 
     803        if (typeName.equals(type.getName())) { 
     804            return true; 
     805        } 
     806        for (Relationship relationship : type.getRelationships()) { 
     807            if (relationship instanceof Generalization) { 
     808                Element target = ((Generalization) relationship).getTargets().get(0); 
     809                if (target instanceof PrimitiveType) { 
     810                    return typeName.equals(((PrimitiveType) target).getName()); 
     811                } 
     812            } 
     813        } 
     814        return false; 
     815    } 
     816     
     817    /** 
     818     * <p> 
     819     * Checks if a type is an anonymous inner type that represents an XSD sequence 
     820     * </p> 
     821     * 
     822     * @param type type that is checked 
     823     * @return true if XSD sequence; false otherwise 
     824     */ 
     825    private boolean isXSDSequence(Type type) { 
     826        if( type==null || type.getName()==null ) { 
     827            return false; 
     828        } 
     829        return type.getName().matches("sequence\\d*"); 
     830    } 
     831     
     832    /** 
     833     * <p> 
     834     * Checks if a type is an anonymous inner type that represents an XSD choice 
     835     * </p> 
     836     * 
     837     * @param type type that is checked 
     838     * @return true if XSD choice; false otherwise 
     839     */ 
     840    private boolean isXSDChoice(Type type) { 
     841        if( type==null || type.getName()==null ) { 
     842            return false; 
     843        } 
     844        return type.getName().matches("choice\\d*"); 
     845    } 
     846 
     847    /** 
     848     * <p> 
     849     * Returns the name of a type and removes the suffix _._type. 
     850     * </p> 
     851     *  
     852     * @param the 
     853     *            type 
     854     * @return type name of the type without the possible suffix 
     855     */ 
     856    private String getNormalizedTypeName(Type type) { 
     857        if (type == null) { 
     858            throw new RuntimeException("type must not be null"); 
     859        } 
     860        String typeName = type.getName(); 
     861        if (typeName != null && typeName.endsWith("_._type")) { 
     862            typeName = typeName.substring(0, typeName.length() - 7); 
     863        } 
     864        return typeName; 
     865    } 
     866 
     867    // ///////////////////// 
     868    // DEBUGGING METHODS // 
     869    // ///////////////////// 
     870 
     871    @SuppressWarnings("unused") 
     872    private void printParameters(Operation operation) { 
     873        System.out.println("operation name: " + operation.getName()); 
     874        for (Parameter param : operation.getOwnedParameters()) { 
     875            printParameters(param, 0); 
     876        } 
     877    } 
     878 
     879    private void printParameters(Parameter param, int depth) { 
     880        for (int i = 0; i < depth; i++) { 
     881            System.out.print(" "); 
     882        } 
     883        System.out.println(param.getName() + " - " + getNormalizedTypeName(param.getType())); 
     884        if (param.getType() instanceof DataType) { 
     885            for (Property prop : ((DataType) param.getType()).getAllAttributes()) { 
     886                printParameters(prop, depth + 2); 
     887            } 
     888        } 
     889    } 
     890 
     891    private void printParameters(Property prop, int depth) { 
     892        if (depth > 10) 
     893            return; 
     894        for (int i = 0; i < depth; i++) { 
     895            System.out.print(" "); 
     896        } 
     897        System.out.println(prop.getName() + " - " + getNormalizedTypeName(prop.getType())); 
     898        if (prop.getType() instanceof DataType) { 
     899            for (Property prop2 : ((DataType) prop.getType()).getAllAttributes()) { 
     900                printParameters(prop2, depth + 2); 
     901            } 
     902        } 
     903    } 
     904 
    644905} 
Note: See TracChangeset for help on using the changeset viewer.