Changeset 1929 for trunk/autoquest-plugin-uml/src
- Timestamp:
- 03/20/15 16:00:10 (10 years ago)
- Location:
- trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/UMLUtils.java
r1926 r1929 15 15 package de.ugoe.cs.autoquest.plugin.uml; 16 16 17 import java.io.StringWriter;18 import java.util.ArrayList;19 17 import java.util.Collection; 20 18 import java.util.Collections; … … 32 30 import java.util.TreeSet; 33 31 34 import javax.xml.transform.Transformer;35 import javax.xml.transform.TransformerException;36 import javax.xml.transform.TransformerFactory;37 import javax.xml.transform.TransformerFactoryConfigurationError;38 import javax.xml.transform.dom.DOMSource;39 import javax.xml.transform.stream.StreamResult;40 41 32 import org.eclipse.emf.common.util.EList; 42 import org.eclipse.emf.common.util.URI;43 33 import org.eclipse.uml2.uml.Activity; 44 34 import org.eclipse.uml2.uml.ActivityEdge; … … 74 64 import org.eclipse.uml2.uml.Port; 75 65 import org.eclipse.uml2.uml.PrimitiveType; 76 import org.eclipse.uml2.uml.Profile;77 66 import org.eclipse.uml2.uml.Property; 78 67 import org.eclipse.uml2.uml.Region; … … 83 72 import org.eclipse.uml2.uml.Transition; 84 73 import org.eclipse.uml2.uml.Trigger; 85 import org.eclipse.uml2.uml.Type;86 74 import org.eclipse.uml2.uml.UMLPackage; 75 import org.eclipse.uml2.uml.ValueSpecification; 87 76 import org.eclipse.uml2.uml.Vertex; 88 import org.w3c.dom.Attr;89 import org.w3c.dom.Node;90 import org.w3c.dom.NodeList;91 77 92 78 import de.ugoe.cs.autoquest.eventcore.Event; … … 113 99 final static int MAX_MULTIPLICITY = 10; 114 100 115 final public static URI UML_PRIMITIVE_TYPES_URI = URI116 .createURI("pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml", true);117 118 101 /** 119 102 * <p> … … 134 117 String testContextName) 135 118 { 136 final Profile utpProfile = model.getAppliedProfile("utp");137 final Stereotype utpTestComponent = (Stereotype) utpProfile.getOwnedMember("TestComponent");138 final Stereotype utpSUT = (Stereotype) utpProfile.getOwnedMember("SUT");139 final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext");140 141 119 int violationCount = 0; 142 Component testContext = fetchTestContext(model, utpTestContext,testContextName);120 Component testContext = fetchTestContext(model, testContextName); 143 121 if (testContext == null) { 144 122 violationCount++; … … 186 164 // fetch all SUTs and TestComponents 187 165 HashMap<String, Property> properties = new HashMap<>(); 188 for (Property property : testContext.getAllAttributes()) { 189 if (property.getAppliedStereotypes().contains(utpSUT)) { 190 properties.put(property.getName(), property); 191 } 192 else if (property.getType().getAppliedStereotypes().contains(utpTestComponent)) { 193 properties.put(property.getName(), property); 194 } 166 for (Property property : fetchAllSUTProperties(testContext)) { 167 properties.put(property.getName(), property); 168 } 169 for (Property property : fetchAllTestComponentProperties(testContext)) { 170 properties.put(property.getName(), property); 195 171 } 196 172 Console.traceln(Level.INFO, "Found the following services in the TestConfiguration:"); … … 455 431 * test context found is used. 456 432 */ 457 public static voidcreateInteractionFromEventSequence(List<Event> sequence,458 Model model,459 String interactionName,460 String testContextName)433 public static Interaction createInteractionFromEventSequence(List<Event> sequence, 434 Model model, 435 String interactionName, 436 String testContextName) 461 437 { 462 final Profile utpProfile = model.getAppliedProfile("utp"); 463 final Stereotype utpTestCase = (Stereotype) utpProfile.getOwnedMember("TestCase"); 464 final Stereotype utpTestComponent = (Stereotype) utpProfile.getOwnedMember("TestComponent"); 465 final Stereotype utpSUT = (Stereotype) utpProfile.getOwnedMember("SUT"); 466 final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext"); 467 468 // add UML Primitive types 469 // final UMLResource umlRes = (UMLResource) 470 // model.eResource().getResourceSet().getResource(UML_PRIMITIVE_TYPES_URI, true); 471 // model = (Model) umlRes.getContents().get(0); 472 473 Component testContext = fetchTestContext(model, utpTestContext, testContextName); 438 final Component testContext = fetchTestContext(model, testContextName); 474 439 if (testContext == null) { 475 440 throw new RuntimeException("Could not find any test context in the model"); 476 441 } 477 442 478 Operation operation = testContext.createOwnedOperation(interactionName, null, null);479 operation.applyStereotype( utpTestCase);480 481 Interaction interaction =443 final Operation operation = testContext.createOwnedOperation(interactionName, null, null); 444 operation.applyStereotype(UTPUtils.getTestCaseStereotype(model)); 445 446 final Interaction interaction = 482 447 (Interaction) testContext.createPackagedElement(interactionName + "_Impl", 483 448 UMLPackage.Literals.INTERACTION); … … 487 452 Lifeline userLifeline = null; 488 453 489 for (Property property : testContext.getAllAttributes()) {490 if (property.getAppliedStereotypes().contains(utpSUT)) {491 String serviceName = property.getName();492 Lifeline targetLifeline = interaction.createLifeline(serviceName);493 targetLifeline.setRepresents(property);494 }495 else if (property.getType().getAppliedStereotypes().contains(utpTestComponent)) {496 497 498 499 500 501 502 503 } 454 for (Property property : fetchAllSUTProperties(testContext)) { 455 String serviceName = property.getName(); 456 Lifeline targetLifeline = interaction.createLifeline(serviceName); 457 targetLifeline.setRepresents(property); 458 } 459 for (Property property : fetchAllTestComponentProperties(testContext)) { 460 // TODO check if this is still required 461 if (userLifeline != null) { 462 throw new RuntimeException( 463 "TestContext must only have one TestComponent for the application of usage-based testing."); 464 } 465 userLifeline = interaction.createLifeline(property.getName()); 466 userLifeline.setRepresents(property); 467 } 468 504 469 if (userLifeline == null) { 505 470 throw new RuntimeException("No TestComponent found, could not create user lifeline."); … … 580 545 callRecvFragment.setCovered(msgTargetLifeline); 581 546 547 // get connector 548 Connector connector = inferConnector(msgSourceLifeline, msgTargetLifeline); 549 582 550 // create call 583 Message callMessage = interaction.createMessage( methodName);551 Message callMessage = interaction.createMessage(prefix + "call"); 584 552 callMessage.setSignature(calledOperation); 585 set MessageParameters(callMessage, calledOperation, event, prefix);586 callMessage.setConnector( inferConnector(msgSourceLifeline, msgTargetLifeline));553 setCallMessageParameters(callMessage, calledOperation, event, prefix); 554 callMessage.setConnector(connector); 587 555 callMessage.setSendEvent(callSendFragment); 588 556 callMessage.setReceiveEvent(callRecvFragment); … … 632 600 633 601 // create reply 634 Message replyMessage = interaction.createMessage( methodName+ "_reply");602 Message replyMessage = interaction.createMessage(prefix + "_reply"); 635 603 replyMessage.setMessageSort(MessageSort.REPLY_LITERAL); 636 604 replyMessage.setSignature(calledOperation); 605 setReplyMessageParameters(replyMessage, calledOperation); 606 replyMessage.setConnector(connector); 637 607 replyMessage.setSendEvent(replySendFragment); 638 608 replyMessage.setReceiveEvent(replyRecvFragment); … … 644 614 } 645 615 } 616 return interaction; 646 617 } 647 618 … … 662 633 { 663 634 double usageScore = 0.0d; 664 665 635 EList<InteractionFragment> interactionFragments = interaction.getFragments(); 666 636 List<Event> eventSequence = new LinkedList<>(); 667 637 eventSequence.add(Event.STARTEVENT); 668 638 for (InteractionFragment interactionFragment : interactionFragments) { 669 if (interactionFragment.getName() != null && 670 interactionFragment.getName().endsWith("_recvFragment")) // TODO must be more 671 // generic 672 { 673 String serviceName = 674 interactionFragment.getCovereds().get(0).getRepresents().getName().split("_")[0]; 675 String methodName = "UNKNOWN"; 676 if (interactionFragment instanceof MessageOccurrenceSpecification) { 677 methodName = 678 ((MessageOccurrenceSpecification) interactionFragment).getMessage() 679 .getName(); 680 } 681 // eventSequence.add(new Event(new SimpleSOAPEventType(methodName, serviceName, "", 682 // ))); // TODO 683 // add 684 // client 685 // name 639 if (interactionFragment instanceof MessageOccurrenceSpecification) { 640 Message message = 641 ((MessageOccurrenceSpecification) interactionFragment).getMessage(); 642 if (message.getReceiveEvent().equals(interactionFragment) && isCallMessage(message)) 643 { 644 String clientName = 645 ((MessageOccurrenceSpecification) message.getSendEvent()).getCovereds() 646 .get(0).getName(); 647 String serviceName = 648 ((MessageOccurrenceSpecification) message.getReceiveEvent()).getCovereds() 649 .get(0).getName(); 650 String methodName = message.getSignature().getName(); 651 eventSequence.add(new Event(new SimpleSOAPEventType(methodName, serviceName, 652 clientName, null))); 653 } 686 654 } 687 655 } … … 707 675 String testContextName) 708 676 { 709 710 final Profile utpProfile = model.getAppliedProfile("utp"); 711 final Stereotype utpTestCase = (Stereotype) utpProfile.getOwnedMember("TestCase"); 712 final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext"); 713 714 Component testContext = fetchTestContext(model, utpTestContext, testContextName); 677 final Component testContext = fetchTestContext(model, testContextName); 715 678 if (testContext == null) { 716 679 throw new RuntimeException("Could not find any test context in the model"); … … 720 683 721 684 // first, we determine all test cases and calculate their usage scores 685 final Stereotype utpTestCase = UTPUtils.getTestCaseStereotype(model); 722 686 for (Operation operation : testContext.getAllOperations()) { 723 if (operation.getAppliedStereotypes().contains(utpTestCase)) { 687 if (operation.getAppliedStereotypes().contains(utpTestCase) && 688 !operation.getMethods().isEmpty()) 689 { 724 690 Interaction interaction = (Interaction) operation.getMethods().get(0); 725 691 usageScoreMapUnsorted … … 764 730 edge.setSource(currentOperationNode); 765 731 edge.setTarget(finalNode); 766 }767 768 /**769 * From770 * http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java771 * and adapted to do an inverse sorting772 */773 public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {774 List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());775 Collections.sort(list, new Comparator<Map.Entry<K, V>>() {776 @Override777 public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {778 return -1 * (o1.getValue()).compareTo(o2.getValue());779 }780 });781 782 Map<K, V> result = new LinkedHashMap<>();783 for (Map.Entry<K, V> entry : list) {784 result.put(entry.getKey(), entry.getValue());785 }786 return result;787 732 } 788 733 … … 862 807 } 863 808 809 /** 810 * <p> 811 * Fetches all realized interfaces from the type of a UML {@link Property} (i.e., 812 * property.getType()). If no interfaces are realized, an empty set is returned. 813 * </p> 814 * 815 * @param property 816 * property, of the whose realized interfaces of the type are determined 817 * @return realized interfaces 818 */ 864 819 private static Set<Interface> getRealizedInterfacesFromProperty(Property property) { 865 820 return getRealizedInterfaceFromComponent((Component) property.getType()); 866 821 } 867 822 868 private static Set<Interface> getRealizedInterfaceFromComponent(Component comp) { 823 /** 824 * <p> 825 * Fetches all realized interfaces from a UML {@link Component}. If no interfaces are realized, 826 * an empty set is returned. 827 * </p> 828 * 829 * @param comp 830 * component whose realized interfaces are determined 831 * @return realized interfaces 832 */ 833 private static Set<Interface> getRealizedInterfaceFromComponent(Component component) { 869 834 Set<Interface> interfaces = new HashSet<>(); 870 835 // Interface myInterface = null; 871 for (Property property : comp .getAttributes()) {836 for (Property property : component.getAttributes()) { 872 837 if (property instanceof Port) { 873 838 Port port = (Port) property; … … 880 845 } 881 846 882 private static Component fetchTestContext(Package pkg, 883 Stereotype utpTestContext, 884 String testContextName) 885 { 886 List<Component> testContexts = fetchTestContextRecursively(pkg, utpTestContext); 847 /** 848 * <p> 849 * Determines searches within a {@link Package} for a component to which the UTP TestContext 850 * stereotype is applied. 851 * <ul> 852 * <li>If no testContextName is provided, the first test context found is returned.</li> 853 * <li>In case no test context is found, null is returned.</li> 854 * </p> 855 * 856 * @param pkg 857 * package where the test context is being locked for 858 * @param testContextName 859 * name of the test context; in case no test name is specified, use null and not the 860 * empty String. 861 * @return {@link Component} to which the TestContext stereotype is applied 862 */ 863 private static Component fetchTestContext(final Package pkg, final String testContextName) { 864 List<Component> testContexts = fetchAllTestContexts(pkg); 887 865 if (testContexts.isEmpty()) { 888 866 return null; … … 901 879 } 902 880 903 private static List<Component> fetchTestContextRecursively(Package pkg, 904 Stereotype utpTestContext) 905 { 906 List<Component> testContexts = new LinkedList<>(); 881 /** 882 * <p> 883 * Retrieves all UML {@link Component}s to which the UTP TestContext stereotype is applied from 884 * a package. This method calls itself recursively to include all components contained in 885 * sub-packages. 886 * </p> 887 * <p> 888 * In case no test context is found, an empty list is returned. 889 * </p> 890 * 891 * @param pkg 892 * package from which the test contexts are retrieved 893 * @return {@link List} of test contexts 894 */ 895 private static List<Component> fetchAllTestContexts(final Package pkg) { 896 final Stereotype utpTestContext = UTPUtils.getTestContextStereotype(pkg.getModel()); 897 final List<Component> testContexts = new LinkedList<>(); 907 898 for (Element element : pkg.getOwnedElements()) { 908 899 if (element instanceof Package) { 909 testContexts.addAll(fetch TestContextRecursively((Package) element, utpTestContext));900 testContexts.addAll(fetchAllTestContexts((Package) element)); 910 901 } 911 902 if (element instanceof Component && … … 920 911 /** 921 912 * <p> 922 * Infers connector between two lifelines. TODO: currently assumes only one connector between 923 * two lifelines possible. I need to make sure this assumption is valid. 924 * </p> 925 * 926 * @param userAttributes 913 * Retrieves all properties that represent a UTP TestComponent from a test context. 914 * </p> 915 * 916 * @param testContext 917 * test context from which the properties are retrieved 918 * @return properties that represent test components 919 */ 920 private static Set<Property> fetchAllTestComponentProperties(final Component testContext) { 921 // fetch all SUTs and TestComponents 922 final Stereotype utpTestComponent = 923 UTPUtils.getTestComponentStereotype(testContext.getModel()); 924 final Set<Property> properties = new HashSet<>(); 925 for (Property property : testContext.getAllAttributes()) { 926 if (property.getType().getAppliedStereotypes().contains(utpTestComponent)) { 927 properties.add(property); 928 } 929 } 930 return properties; 931 } 932 933 /** 934 * <p> 935 * Retrieves all properties that represent a UTP SUT from a test context. 936 * </p> 937 * 938 * @param testContext 939 * test context from which the properties are retrieved 940 * @return properties that represent the SUTs 941 */ 942 private static Set<Property> fetchAllSUTProperties(final Component testContext) { 943 // fetch all SUTs and TestComponents 944 final Stereotype utpSUT = UTPUtils.getSUTStereotype(testContext.getModel()); 945 final Set<Property> properties = new HashSet<>(); 946 for (Property property : testContext.getAllAttributes()) { 947 if (property.getAppliedStereotypes().contains(utpSUT)) { 948 properties.add(property); 949 } 950 } 951 return properties; 952 } 953 954 /** 955 * <p> 956 * Infers connector between two lifelines. 957 * </p> 958 * <p> 959 * TODO: Currently assumes only one connector between two lifelines possible. This assumption is 960 * invalid as soon as there are two ports that connect the same two properties. 961 * </p> 962 * 963 * @param msgSourceLifeline 964 * source lifeline of the message 927 965 * @param targetAttributes 966 * target lifeline of the message 928 967 */ 929 968 private static Connector inferConnector(Lifeline msgSourceLifeline, Lifeline msgTargetLifeline) … … 955 994 } 956 995 996 /** 997 * <p> 998 * Creates a map that maps the interfaces to the properties, i.e., services that they are 999 * represented by. 1000 * </p> 1001 * <p> 1002 * TODO: currently assumes that each interfaces is only realized by one property 1003 * </p> 1004 * 1005 * @param model 1006 * model for which the interface->service map is created 1007 * @return the map 1008 */ 957 1009 private static Map<Interface, String> createInterfaceServiceMap(Model model) { 958 1010 Map<Interface, String> interfaceServiceMap = new HashMap<>(); 959 final Profile utpProfile = model.getModel().getAppliedProfile("utp"); 960 final Stereotype utpTestComponent = (Stereotype) utpProfile.getOwnedMember("TestComponent"); 961 final Stereotype utpSUT = (Stereotype) utpProfile.getOwnedMember("SUT"); 962 final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext"); 963 List<Component> testContexts = 964 fetchTestContextRecursively(model.getModel(), utpTestContext); 1011 List<Component> testContexts = fetchAllTestContexts(model.getModel()); 965 1012 for (Component testContext : testContexts) { 966 for (Property property : testContext.getAllAttributes()) { 967 if (property.getAppliedStereotypes().contains(utpSUT) || 968 property.getType().getAppliedStereotypes().contains(utpTestComponent)) 969 { 970 for (Interface intface : getRealizedInterfacesFromProperty(property)) { 971 interfaceServiceMap.put(intface, property.getName()); 972 } 1013 for (Property property : fetchAllSUTProperties(testContext)) { 1014 for (Interface intface : getRealizedInterfacesFromProperty(property)) { 1015 interfaceServiceMap.put(intface, property.getName()); 1016 } 1017 } 1018 for (Property property : fetchAllTestComponentProperties(testContext)) { 1019 for (Interface intface : getRealizedInterfacesFromProperty(property)) { 1020 interfaceServiceMap.put(intface, property.getName()); 973 1021 } 974 1022 } … … 977 1025 } 978 1026 979 private static void setMessageParameters(Message callMessage, 980 Operation calledOperation, 981 Event event, 982 String prefix) 1027 /** 1028 * <p> 1029 * Sets values for the parameters of a call message. The values are, if possible, inferred from 1030 * the event that is provided. 1031 * </p> 1032 * 1033 * @param callMessage 1034 * call message for which the parameters are set 1035 * @param calledOperation 1036 * operation that is called by the message 1037 * @param event 1038 * event that provides the parameters; in case of null, default values are assumed 1039 * @param prefix 1040 * prefix of the call message; used to create good warnings and debugging information 1041 */ 1042 private static void setCallMessageParameters(Message callMessage, 1043 Operation calledOperation, 1044 Event event, 1045 String prefix) 983 1046 { 984 1047 org.w3c.dom.Element requestBody = SOAPUtils.getSoapRequestBodyFromEvent(event); 1048 Package instSpecPkg = null; 985 1049 986 1050 // Set parameters of operation 987 1051 for (Parameter param : calledOperation.getOwnedParameters()) { 1052 if (instSpecPkg == null) { 1053 instSpecPkg = getOrCreateInstanceSpecificationPackage(param.getModel(), event); 1054 } 1055 1056 String path = calledOperation.getName() + ":" + param.getName(); 988 1057 Expression argument = 989 1058 (Expression) callMessage.createArgument(param.getName(), param.getType(), 990 1059 UMLPackage.Literals.EXPRESSION); 991 1060 992 if (param.getDirection() == ParameterDirectionKind.IN_LITERAL || 993 param.getDirection() == ParameterDirectionKind.INOUT_LITERAL) 994 { 1061 if (isInParameter(param)) { 995 1062 if (param.getType() instanceof DataType) { 996 1063 List<org.w3c.dom.Element> paramNodes = 997 getMatchingChildNode((DataType) param.getType(), requestBody); 998 for (org.w3c.dom.Element paramNode : paramNodes) { 1064 SOAPUtils.getMatchingChildNode(param.getType().getName(), requestBody); 1065 int multiplicityChosen = paramNodes.size(); 1066 1067 if (multiplicityChosen == 0 && param.getLower() > 0) { 1068 Console.traceln(Level.WARNING, 1069 "required attribute not found in SOAP message: " + path); 1070 Console 1071 .traceln(Level.WARNING, 1072 "setting default values for this attribute and all its children"); 1073 Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 1074 SOAPUtils.getSerialization(requestBody)); 1075 multiplicityChosen = param.getLower(); 1076 } 1077 for (int i = 0; i < multiplicityChosen; i++) { 1078 org.w3c.dom.Element paramNode = null; 1079 if (!paramNodes.isEmpty()) { 1080 paramNode = paramNodes.get(i); 1081 } 999 1082 InstanceSpecification instSpec = 1000 createInstanceSpecification((DataType) param.getType(), event, prefix,1001 p aramNode, "");1083 createInstanceSpecification((DataType) param.getType(), instSpecPkg, 1084 prefix, paramNode, path); 1002 1085 1003 1086 InstanceValue value = … … 1009 1092 } 1010 1093 else if (param.getType() instanceof PrimitiveType) { 1011 createOperandPrimitiveType(param, argument, requestBody );1094 createOperandPrimitiveType(param, argument, requestBody, path); 1012 1095 } 1013 1096 } … … 1019 1102 } 1020 1103 1104 /** 1105 * <p> 1106 * Creates an {@link InstanceSpecification} for a data type in the given package. The values are 1107 * inferred, if possible, from the DOM node. The prefix and the path are used for naming the 1108 * instance specification and to provide good warnings and debug information in case of 1109 * problems. 1110 * </p> 1111 * 1112 * @param type 1113 * DataType for which the {@link InstanceSpecification} is created 1114 * @param pkg 1115 * package in which the {@link InstanceSpecification} is created 1116 * @param prefix 1117 * prefix used for naming the {@link InstanceSpecification} 1118 * @param currentNode 1119 * node of a DOM from which values are inferred 1120 * @param path 1121 * used for warnings and debug information 1122 * @return {@link InstanceSpecification} for the given type 1123 */ 1021 1124 private static InstanceSpecification createInstanceSpecification(DataType type, 1022 Event event,1125 Package pkg, 1023 1126 String prefix, 1024 1127 org.w3c.dom.Element currentNode, … … 1028 1131 path = type.getName(); 1029 1132 } 1030 // System.out.println(path);1031 String pkgUBTInstSpecs = "UBT_InstanceSpecifications";1032 Model model = type.getModel();1033 Package ubtInstSpecPkg = (Package) model.getOwnedMember(pkgUBTInstSpecs);1034 if (ubtInstSpecPkg == null) {1035 ubtInstSpecPkg =1036 (Package) type.getModel().createPackagedElement(pkgUBTInstSpecs,1037 UMLPackage.Literals.PACKAGE);1038 }1039 String serviceName = SOAPUtils.getServiceNameFromEvent(event);1040 Package serviceInstSpecPkg = (Package) ubtInstSpecPkg.getOwnedMember(serviceName);1041 if (serviceInstSpecPkg == null) {1042 serviceInstSpecPkg =1043 (Package) ubtInstSpecPkg.createPackagedElement(serviceName,1044 UMLPackage.Literals.PACKAGE);1045 }1046 1133 1047 1134 InstanceSpecification instSpec = 1048 (InstanceSpecification) serviceInstSpecPkg.createPackagedElement(prefix + "instspec_" + 1049 type.getName(), UMLPackage.Literals.INSTANCE_SPECIFICATION); 1135 (InstanceSpecification) pkg 1136 .createPackagedElement(prefix + "instspec_" + type.getName(), 1137 UMLPackage.Literals.INSTANCE_SPECIFICATION); 1050 1138 instSpec.getClassifiers().add(type); 1051 1139 for (Property prop : type.getAllAttributes()) { … … 1057 1145 int multiplicityChosen = 0; 1058 1146 if (currentNode != null) { 1059 attributeNodes = getMatchingChildNode(prop, currentNode);1147 attributeNodes = SOAPUtils.getMatchingChildNode(prop.getName(), currentNode); 1060 1148 multiplicityChosen = attributeNodes.size(); 1061 1149 } … … 1086 1174 (InstanceValue) slot.createValue(prop.getName() + "_" + i, prop.getType(), 1087 1175 UMLPackage.Literals.INSTANCE_VALUE); 1088 value.setInstance(createInstanceSpecification((DataType) prop.getType(), event,1176 value.setInstance(createInstanceSpecification((DataType) prop.getType(), pkg, 1089 1177 prefix, attributeNode, path + 1090 1178 "." + prop.getName())); … … 1100 1188 } 1101 1189 1190 /** 1191 * <p> 1192 * Gets or creates a {@link Package} for {@link InstanceSpecification} created by the 1193 * usage-based testing. Each service gets its own sub-package within a package called 1194 * UBT_InstanceSpecifications. " 1195 * </p> 1196 * 1197 * @param model 1198 * model in which the package is generated 1199 * @param event 1200 * event from which the service name is inferred 1201 * @return package for the {@link InstanceSpecification}s 1202 */ 1203 private static Package getOrCreateInstanceSpecificationPackage(Model model, Event event) { 1204 String pkgUBTInstSpecs = "UBT_InstanceSpecifications"; 1205 Package ubtInstSpecPkg = (Package) model.getOwnedMember(pkgUBTInstSpecs); 1206 if (ubtInstSpecPkg == null) { 1207 ubtInstSpecPkg = 1208 (Package) model.createPackagedElement(pkgUBTInstSpecs, UMLPackage.Literals.PACKAGE); 1209 } 1210 String serviceName = SOAPUtils.getServiceNameFromEvent(event); 1211 Package serviceInstSpecPkg = (Package) ubtInstSpecPkg.getOwnedMember(serviceName); 1212 if (serviceInstSpecPkg == null) { 1213 serviceInstSpecPkg = 1214 (Package) ubtInstSpecPkg.createPackagedElement(serviceName, 1215 UMLPackage.Literals.PACKAGE); 1216 } 1217 return serviceInstSpecPkg; 1218 } 1219 1220 /** 1221 * <p> 1222 * Creates an operand that defines a {@link PrimitiveType}. 1223 * </p> 1224 * <p> 1225 * TODO: Currently does nothing in case of multiplicity 0. I am not sure if, in that case, one 1226 * has to define LiteralNull instead. 1227 * </p> 1228 * 1229 * @param param 1230 * parameter for which the operand is created 1231 * @param argument 1232 * argument to which the operand is added 1233 * @param currentNode 1234 * DOM node from which is value for the operand is inferred 1235 * @param path 1236 * used for warnings and debug information 1237 */ 1102 1238 private static void createOperandPrimitiveType(Parameter param, 1103 1239 Expression argument, 1104 org.w3c.dom.Element currentNode) 1240 org.w3c.dom.Element currentNode, 1241 String path) 1105 1242 { 1106 if ("String".equals(param.getType().getName())) { 1107 LiteralString spec = 1108 (LiteralString) argument.createOperand(param.getName(), null, 1109 UMLPackage.Literals.LITERAL_STRING); 1110 spec.setValue("foobar"); // TODO needs to be real value 1111 } 1112 else if ("Integer".equals(param.getType().getName())) { 1113 LiteralInteger spec = 1114 (LiteralInteger) argument.createOperand(param.getName(), null, 1115 UMLPackage.Literals.LITERAL_INTEGER); 1116 spec.setValue(42); // TODO needs to be real value 1117 } 1118 else if ("Boolean".equals(param.getType().getName())) { 1119 LiteralBoolean spec = 1120 (LiteralBoolean) argument.createOperand(param.getName(), null, 1121 UMLPackage.Literals.LITERAL_BOOLEAN); 1122 spec.setValue(true); // TODO needs to be real value 1123 } 1124 else if ("Real".equals(param.getType().getName())) { 1125 LiteralReal spec = 1126 (LiteralReal) argument.createOperand(param.getName(), null, 1127 UMLPackage.Literals.LITERAL_REAL); 1128 spec.setValue(3.14); // TODO needs to be real value 1129 } 1130 } 1131 1243 List<String> attributeValues = SOAPUtils.getValuesFromElement(param.getName(), currentNode); 1244 1245 if (attributeValues.isEmpty()) { 1246 if (param.getLower() == 0) { 1247 // ignoring optional attribute 1248 return; 1249 } 1250 else { 1251 if (currentNode != null) { 1252 Console.traceln(Level.WARNING, 1253 "required attribute not found in SOAP message: " + path + "." + 1254 param.getName()); 1255 Console.traceln(Level.WARNING, "setting default values for this attribute"); 1256 Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 1257 SOAPUtils.getSerialization(currentNode)); 1258 } 1259 attributeValues.add(null); 1260 } 1261 } 1262 for (String attributeValue : attributeValues) { 1263 if ("String".equals(param.getType().getName())) { 1264 LiteralString spec = 1265 (LiteralString) argument.createOperand(param.getName(), null, 1266 UMLPackage.Literals.LITERAL_STRING); 1267 if (attributeValue != null) { 1268 spec.setValue(attributeValue); 1269 } 1270 else { 1271 spec.setValue("foobar"); 1272 } 1273 } 1274 else if ("Integer".equals(param.getType().getName())) { 1275 LiteralInteger spec = 1276 (LiteralInteger) argument.createOperand(param.getName(), null, 1277 UMLPackage.Literals.LITERAL_INTEGER); 1278 if (attributeValue != null) { 1279 spec.setValue(Integer.parseInt(attributeValue)); 1280 } 1281 else { 1282 spec.setValue(42); 1283 } 1284 } 1285 else if ("Boolean".equals(param.getType().getName())) { 1286 LiteralBoolean spec = 1287 (LiteralBoolean) argument.createOperand(param.getName(), null, 1288 UMLPackage.Literals.LITERAL_BOOLEAN); 1289 if (attributeValue != null) { 1290 spec.setValue(Boolean.parseBoolean(attributeValue)); 1291 } 1292 else { 1293 spec.setValue(true); 1294 } 1295 } 1296 else if ("Real".equals(param.getType().getName())) { 1297 LiteralReal spec = 1298 (LiteralReal) argument.createOperand(param.getName(), null, 1299 UMLPackage.Literals.LITERAL_REAL); 1300 if (attributeValue != null) { 1301 spec.setValue(Double.parseDouble(attributeValue)); 1302 } 1303 else { 1304 spec.setValue(3.14); 1305 } 1306 } 1307 } 1308 } 1309 1310 /** 1311 * <p> 1312 * Creates a {@link Slot} in an {@link InstanceSpecification} for a primitive type. 1313 * </p> 1314 * 1315 * @param instSpec 1316 * instance specification to which the slot is added 1317 * @param prop 1318 * property that describes the slot 1319 * @param currentNode 1320 * DOM node from which is value for the slot is inferred 1321 * @param path 1322 * used for warnings and debug information 1323 */ 1132 1324 private static void createSlotPrimitiveType(InstanceSpecification instSpec, 1133 1325 Property prop, … … 1135 1327 String path) 1136 1328 { 1137 List<String> attributeValues = getPrimitiveTypeValuesFromElement(prop, currentNode);1329 List<String> attributeValues = SOAPUtils.getValuesFromElement(prop.getName(), currentNode); 1138 1330 1139 1331 if (attributeValues.isEmpty()) { … … 1148 1340 prop.getName()); 1149 1341 Console.traceln(Level.WARNING, "setting default values for this attribute"); 1150 }1151 Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE +1152 SOAPUtils.getSerialization(currentNode));1342 Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 1343 SOAPUtils.getSerialization(currentNode)); 1344 } 1153 1345 attributeValues.add(null); 1154 1346 } … … 1198 1390 } 1199 1391 else { 1200 value.setValue(3.14); // TODO needs to be real value1392 value.setValue(3.14); 1201 1393 } 1202 1394 } … … 1209 1401 } 1210 1402 1211 // TODO comment 1212 private static List<org.w3c.dom.Element> getMatchingChildNode(Type type, 1213 org.w3c.dom.Element parentNode) 1214 { 1215 return getMachingChildNode(type.getName(), parentNode); 1216 } 1217 1218 // TODO comment 1219 private static List<org.w3c.dom.Element> getMatchingChildNode(Property prop, 1220 org.w3c.dom.Element parentNode) 1221 { 1222 return getMachingChildNode(prop.getName(), parentNode); 1223 } 1224 1225 // TODO comment 1226 private static List<org.w3c.dom.Element> getMachingChildNode(String typeNameRaw, 1227 org.w3c.dom.Element parentNode) 1228 { 1229 List<org.w3c.dom.Element> matchingNodes = new ArrayList<>(); 1230 Node parameterNode = null; 1231 if (parentNode != null) { 1232 NodeList parameterNodes = parentNode.getChildNodes(); 1233 String[] typeNameSplit = typeNameRaw.split(":"); 1234 String typeName = typeNameSplit[typeNameSplit.length - 1]; 1235 for (int i = 0; i < parameterNodes.getLength(); i++) { 1236 parameterNode = parameterNodes.item(i); 1237 if (parameterNode.getNodeType() == Node.ELEMENT_NODE) { 1238 String[] parameterNodeSplit = parameterNode.getNodeName().split(":"); 1239 String parameterNodeName = parameterNodeSplit[parameterNodeSplit.length - 1]; 1240 if (typeName.equals(parameterNodeName)) { 1241 matchingNodes.add((org.w3c.dom.Element) parameterNode); 1242 } 1243 } 1244 } 1245 /* 1246 * if( !matchingSOAPFound) { Console.traceln(Level.WARNING, 1247 * "could not look up name of parameter in SOAP request: " + typeName); if( 1248 * elementCount==0 ) { Console.traceln(Level.INFO, "\tno parameters found"); } else { 1249 * Console.traceln(Level.INFO, "\tparameters found:"); for( int i=0 ; 1250 * i<parameterNodes.getLength(); i++ ) { if( 1251 * parameterNodes.item(i).getNodeType()==Node.ELEMENT_NODE ) { 1252 * Console.traceln(Level.INFO, "\t\t" + parameterNodes.item(i).getNodeName()); } } } 1253 * Console.traceln(Level.WARNING, 1254 * "using dummy values for this parameter (and nested values) instead"); } 1255 */ 1256 } 1257 return matchingNodes; 1258 } 1259 1260 // TODO 1261 private static List<String> getPrimitiveTypeValuesFromElement(Property prop, 1262 org.w3c.dom.Element currentNode) 1263 { 1264 List<String> attributeValues = new LinkedList<>(); 1265 1266 if (currentNode != null) { 1267 // first check attributes of the node 1268 Attr attribute = currentNode.getAttributeNode(prop.getName()); 1269 if (attribute != null) { 1270 attributeValues.add(attribute.getValue()); 1403 /** 1404 * <p> 1405 * Sets values for the parameters of a reply message. The values are, all LiterealNull and to 1406 * the INOUT, OUT and REPLY parameters, the UTP stereotype LiteralAny is applied. 1407 * </p> 1408 * 1409 * @param replyMessage 1410 * reply message for which the parameters are set 1411 * @param calledOperation 1412 * operation that is replied for by the message 1413 */ 1414 private static void setReplyMessageParameters(Message replyMessage, Operation calledOperation) { 1415 for (Parameter param : calledOperation.getOwnedParameters()) { 1416 Expression argument = 1417 (Expression) replyMessage.createArgument(param.getName(), param.getType(), 1418 UMLPackage.Literals.EXPRESSION); 1419 if (isOutParameter(param)) { 1420 ValueSpecification operand = 1421 argument.createOperand(null, param.getType(), UMLPackage.Literals.LITERAL_NULL); 1422 operand.applyStereotype(UTPUtils.getLiteralAnyStereotype(param.getModel())); 1271 1423 } 1272 1424 else { 1273 // now check elements 1274 List<org.w3c.dom.Element> elements = getMatchingChildNode(prop, currentNode); 1275 for (org.w3c.dom.Element element : elements) { 1276 attributeValues.add(element.getTextContent()); 1277 } 1278 } 1279 } 1280 1281 return attributeValues; 1282 } 1283 1425 argument.createOperand(null, param.getType(), UMLPackage.Literals.LITERAL_NULL); 1426 } 1427 } 1428 } 1429 1430 /** 1431 * <p> 1432 * Checks if a parameter has the direction IN or INOUT 1433 * </p> 1434 * 1435 * @param parameter 1436 * parameter that is checked 1437 * @return true if the direction is IN or INOUT; false otherwise 1438 */ 1439 private static boolean isInParameter(Parameter parameter) { 1440 return parameter.getDirection() == ParameterDirectionKind.IN_LITERAL || 1441 parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL; 1442 } 1443 1444 /** 1445 * <p> 1446 * Checks if a parameter has the direction RETURN, OUT or INOUT 1447 * </p> 1448 * 1449 * @param parameter 1450 * parameter that is checked 1451 * @return true if the direction is RETURN, OUT, or INOUT; false otherwise 1452 */ 1453 private static boolean isOutParameter(Parameter parameter) { 1454 return parameter.getDirection() == ParameterDirectionKind.RETURN_LITERAL || 1455 parameter.getDirection() == ParameterDirectionKind.OUT_LITERAL || 1456 parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL; 1457 } 1458 1459 /** 1460 * <p> 1461 * Checks if the {@link MessageSort} of a message is a call message, i.e., ASYNCH_CALL or 1462 * SYNCH_CALL. 1463 * </p> 1464 * 1465 * @param message 1466 * message that is checked 1467 * @return true if the message is a call message; false otherwise 1468 */ 1469 private static boolean isCallMessage(Message message) { 1470 if (message == null) { 1471 return false; 1472 } 1473 MessageSort msgSort = message.getMessageSort(); 1474 return msgSort == MessageSort.ASYNCH_CALL_LITERAL || 1475 msgSort == MessageSort.SYNCH_CALL_LITERAL; 1476 } 1477 1478 /** 1479 * <p> 1480 * inverse-sorts the values of a map. Has been adapted from <a href= 1481 * "http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java" 1482 * >this</a> StackOverflow post. 1483 * </p> 1484 * 1485 * @param map 1486 * map whose values are sorted 1487 * @return sorted version of the map 1488 */ 1489 private static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { 1490 // TODO possibly move to another class 1491 List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet()); 1492 Collections.sort(list, new Comparator<Map.Entry<K, V>>() { 1493 @Override 1494 public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) { 1495 return -1 * (o1.getValue()).compareTo(o2.getValue()); 1496 } 1497 }); 1498 1499 Map<K, V> result = new LinkedHashMap<>(); 1500 for (Map.Entry<K, V> entry : list) { 1501 result.put(entry.getKey(), entry.getValue()); 1502 } 1503 return result; 1504 } 1284 1505 }
Note: See TracChangeset
for help on using the changeset viewer.