/** Return the map of name to property for a type. */ protected Map<String, P> getName2Property(C type) { Map<String, P> name2property = type2name2property.get(type); if (name2property == null) { name2property = new HashMap<String, P>(); type2name2property.put(type, name2property); List<P> allProperties = getAttributes(type); for (P candidateProperty : allProperties) { String name = uml.getName(candidateProperty); P oldProperty = name2property.get(name); if (oldProperty == null) { name2property.put(name, candidateProperty); } else { C candidateOwner = uml.getOwningClassifier(candidateProperty); Collection<? extends C> candidateSupertypes = uml.getAllSupertypes(candidateOwner); C oldOwner = uml.getOwningClassifier(oldProperty); if (candidateSupertypes.contains(oldOwner)) { name2property.put(name, candidateProperty); } else { Collection<? extends C> oldSupertypes = uml.getAllSupertypes(oldOwner); if (!oldSupertypes.contains(candidateOwner)) {; // This should not happen } } } } } return name2property; }
/** Return the map of name to operator or list of operations for a type. */ protected Map<String, Object> getName2OperationOrOperations(C type) { Map<String, Object> name2operationOrOperations = type2name2operationOrOperations.get(type); if (name2operationOrOperations == null) { name2operationOrOperations = new HashMap<String, Object>(); type2name2operationOrOperations.put(type, name2operationOrOperations); List<O> allOperations = getOperations(type); for (O candidateOperation : allOperations) { String name = uml.getName(candidateOperation); Object overloadOrOverloads = name2operationOrOperations.get(name); if (overloadOrOverloads == null) { name2operationOrOperations.put(name, candidateOperation); } else { List<O> overloads; if (overloadOrOverloads instanceof List<?>) { @SuppressWarnings("unchecked") List<O> castOperations = (List<O>) overloadOrOverloads; overloads = castOperations; } else { overloads = new ArrayList<O>(); name2operationOrOperations.put(name, overloads); @SuppressWarnings("unchecked") O castOperation = (O) overloadOrOverloads; overloads.add(castOperation); } C candidateOwner = uml.getOwningClassifier(candidateOperation); Collection<? extends C> candidateSupertypes = uml.getAllSupertypes(candidateOwner); List<PM> candidateParameters = uml.getParameters(candidateOperation); int iMax = candidateParameters.size(); int j = overloads.size(); while (--j >= 0) { // Reverse count to allow remove() O oldOperation = overloads.get(j); List<PM> oldParameters = uml.getParameters(oldOperation); if (iMax == oldParameters.size()) { int i = 0; for (; i < iMax; i++) { PM candidateParameter = candidateParameters.get(i); PM oldParameter = oldParameters.get(i); C oldType = uml.getOCLType(oldParameter); C candidateType = uml.getOCLType(candidateParameter); if (oldType != candidateType) { break; } } if (i >= iMax) { C oldOwner = uml.getOwningClassifier(oldOperation); if (candidateSupertypes.contains(oldOwner)) { overloads.remove(j); } else { Collection<? extends C> oldSupertypes = uml.getAllSupertypes(oldOwner); if (oldSupertypes.contains(candidateOwner)) { break; } } } } } if (j < 0) { overloads.add(candidateOperation); } } } } return name2operationOrOperations; }