From c5ff61c728492be70539dafa7fa7905268c8e2bb Mon Sep 17 00:00:00 2001 From: Steve Hickman Date: Mon, 22 Jan 2024 13:47:47 -0800 Subject: [PATCH] getRealizingTypes / name, completeComposition_Type, (comp/part)Insertion --- .../com/epistimis/uddl/ui/UddlUiModule.java | 6 + .../CLRealizationProposalProcessor.java | 78 ++++-- .../LPRealizationProposalProcessor.java | 35 ++- .../uddl/ui/contentassist/PropUtils.java | 73 ++++++ .../RealizationProposalProcessor.java | 243 ++++++++++++------ .../contentassist/UddlProposalProvider.java | 110 ++++---- 6 files changed, 380 insertions(+), 165 deletions(-) create mode 100644 com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/PropUtils.java diff --git a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/UddlUiModule.java b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/UddlUiModule.java index 3ba8af9..b9ca743 100644 --- a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/UddlUiModule.java +++ b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/UddlUiModule.java @@ -13,6 +13,7 @@ import com.epistimis.uddl.ui.contentassist.CLRealizationProposalProcessor; import com.epistimis.uddl.ui.contentassist.LPRealizationProposalProcessor; +import com.epistimis.uddl.ui.contentassist.PropUtils; import com.epistimis.uddl.ui.hover.UddlDispatchingEObjectTextHover; import com.epistimis.uddl.ui.hover.UddlEObjectDocumentationProvider; import com.epistimis.uddl.ui.hover.UddlEObjectHoverProvider; @@ -45,4 +46,9 @@ public Class bindCLRealizationProposal public Class bindLPRealizationProposalProcessor() { return LPRealizationProposalProcessor.class; } + + public Class bindPropUtils() { + return PropUtils.class; + } + } diff --git a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/CLRealizationProposalProcessor.java b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/CLRealizationProposalProcessor.java index 1618771..30052a9 100644 --- a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/CLRealizationProposalProcessor.java +++ b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/CLRealizationProposalProcessor.java @@ -14,37 +14,44 @@ import com.epistimis.uddl.LogicalEntityProcessor; import com.epistimis.uddl.uddl.ConceptualAssociation; import com.epistimis.uddl.uddl.ConceptualCharacteristic; +import com.epistimis.uddl.uddl.ConceptualComposableElement; import com.epistimis.uddl.uddl.ConceptualComposition; import com.epistimis.uddl.uddl.ConceptualEntity; import com.epistimis.uddl.uddl.ConceptualParticipant; import com.epistimis.uddl.uddl.LogicalAssociation; import com.epistimis.uddl.uddl.LogicalCharacteristic; +import com.epistimis.uddl.uddl.LogicalComposableElement; import com.epistimis.uddl.uddl.LogicalComposition; import com.epistimis.uddl.uddl.LogicalEntity; +import com.epistimis.uddl.uddl.LogicalMeasurement; +import com.epistimis.uddl.uddl.LogicalMeasurementAxis; import com.epistimis.uddl.uddl.LogicalParticipant; /** * */ public class CLRealizationProposalProcessor extends - RealizationProposalProcessor { + RealizationProposalProcessor { + + final public static String OBSERVABLE_REALIZATION_ERR = "Observable {0} is not realized by any AbstractMeasurment"; + final public static String OBSERVABLE_REALIZATION_MANY = "Observable {0} is realized by multiple AbstractMeasurments - picking one"; + final public static String ENTITY_REALIZATION_ERR = "ConceptualEntity {0} is not realized by any LogicalEntity"; + final public static String ENTITY_REALIZATION_MANY = "ConceptualEntity {0} is realized by multiple LogicalEntity - picking one"; @Override - protected void completeSuperRealizingComposition(UddlProposalProvider pp, EObject obj, RuleCall ruleCall, ContentAssistContext context, - ICompletionProposalAcceptor acceptor) { - - pp.superComplete_LogicalComposition(obj, ruleCall, context, acceptor); + protected void completeSuperRealizingComposition(UddlProposalProvider pp, EObject obj, RuleCall ruleCall, + ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + + pp.superComplete_LogicalComposition(obj, ruleCall, context, acceptor); } @Override protected void completeSuperRealizingComposition_Rolename(UddlProposalProvider pp, EObject obj, - Assignment assignment,ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { pp.superCompleteLogicalComposition_Rolename(obj, assignment, context, acceptor); - + } - + @Override protected String proposalDisplayString(ConceptualCharacteristic bc) { @@ -52,21 +59,50 @@ protected String proposalDisplayString(ConceptualCharacteristic bc) { } @Override - protected String compositionInsertionString(ConceptualComposition bc) { - return String.format(dummyType + compositionFormatString, bc.getRolename(), - bc.getLowerBound(), bc.getUpperBound(), bc.getDescription(), - qnp.getFullyQualifiedName(bc).toString()); + protected String compositionInsertionString(ConceptualComposition bc, String indent) { + String typeName = dummyType; + + /** + * Per the Spec/RIG, Observables can be realized by either Measurements (which + * are LogicalComposableElements) or MeasurementAxis (which aren't + * LogicalComposableElements). That means we can't cast the return value to + * LogicalComposableElement. + */ + // com.epistimis.uddl.ModelFilters.getValueTypeUnit(PlatformDataType pdt) + // handles the opposite case + EObject ce = rezProc.getRealizingType(bc.getType(), OBSERVABLE_REALIZATION_ERR, + OBSERVABLE_REALIZATION_MANY); + if (ce != null) { + typeName = pu.minimalReferenceString(ce, bc); //qnp.relativeQualifiedName(ce, bc).toString(); + } + + return String.format(indent + typeName + compositionFormatString, bc.getRolename(), bc.getLowerBound(), + bc.getUpperBound(), bc.getDescription(), qnp.getFullyQualifiedName(bc).toString()); } @Override - protected String participantInsertionString(ConceptualParticipant bc) { - return String.format(dummyType + participantFormatString, bc.getRolename(), - bc.getLowerBound(), bc.getUpperBound(), bc.getDescription(), - qnp.getFullyQualifiedName(bc).toString(), bc.getSourceLowerBound(), bc.getSourceUpperBound()); + protected String participantInsertionString(ConceptualParticipant bc, String indent) { + String typeName = dummyType; + EObject ce = rezProc.getRealizingType(bc.getType(), ENTITY_REALIZATION_ERR, ENTITY_REALIZATION_MANY); + if (ce != null) { + typeName = pu.minimalReferenceString(ce, bc); //qnp.relativeQualifiedName(ce, bc).toString(); + } + return String.format(indent + typeName + participantFormatString, bc.getRolename(), bc.getLowerBound(), + bc.getUpperBound(), bc.getDescription(), qnp.getFullyQualifiedName(bc).toString(), + bc.getSourceLowerBound(), bc.getSourceUpperBound()); } - - - + @Override + protected String getRealizingTypeName(EObject realizingType) { + // TODO Auto-generated method stub + if (realizingType instanceof LogicalMeasurement) { + return ((LogicalMeasurement)realizingType).getName(); + } + if (realizingType instanceof LogicalMeasurementAxis) { + return ((LogicalMeasurementAxis)realizingType).getName(); + } + // If we get here, need more + return "Implement 'getRealizingTypeName' for " + realizingType.eClass().getName(); + } } diff --git a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/LPRealizationProposalProcessor.java b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/LPRealizationProposalProcessor.java index a558feb..5b0afc5 100644 --- a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/LPRealizationProposalProcessor.java +++ b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/LPRealizationProposalProcessor.java @@ -14,12 +14,15 @@ import com.epistimis.uddl.PlatformEntityProcessor; import com.epistimis.uddl.uddl.LogicalAssociation; import com.epistimis.uddl.uddl.LogicalCharacteristic; +import com.epistimis.uddl.uddl.LogicalComposableElement; import com.epistimis.uddl.uddl.LogicalComposition; import com.epistimis.uddl.uddl.LogicalEntity; import com.epistimis.uddl.uddl.LogicalParticipant; import com.epistimis.uddl.uddl.PlatformAssociation; import com.epistimis.uddl.uddl.PlatformCharacteristic; +import com.epistimis.uddl.uddl.PlatformComposableElement; import com.epistimis.uddl.uddl.PlatformComposition; +import com.epistimis.uddl.uddl.PlatformDataType; import com.epistimis.uddl.uddl.PlatformEntity; import com.epistimis.uddl.uddl.PlatformParticipant; @@ -27,10 +30,16 @@ * */ public class LPRealizationProposalProcessor extends - RealizationProposalProcessor { + final public static String ABS_MEAS_REALIZATION_ERR = "AbstractMeasurement {0} is not realized by any PlatformDataType"; + final public static String ABS_MEAS_REALIZATION_MANY = "AbstractMeasurement {0} is realized by multiple PlatformDataTypes - picking one"; + final public static String ENTITY_REALIZATION_ERR = "LogicalEntity {0} is not realized by any PlatformEntity"; + final public static String ENTITY_REALIZATION_MANY = "LogicalEntity {0} is realized by multiple PlatformEntity - picking one"; + + @Override protected void completeSuperRealizingComposition(UddlProposalProvider pp, EObject obj, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { @@ -51,19 +60,35 @@ protected String proposalDisplayString(LogicalCharacteristic bc) { } @Override - protected String compositionInsertionString(LogicalComposition bc) { - return String.format(dummyType + compositionFormatString, bc.getRolename(), + protected String compositionInsertionString(LogicalComposition bc, String indent) { + String typeName = dummyType; + PlatformComposableElement ce = (PlatformComposableElement) rezProc.getRealizingType(bc.getType(),ABS_MEAS_REALIZATION_ERR,ABS_MEAS_REALIZATION_MANY); + if (ce != null) { + typeName = qnp.relativeQualifiedName(ce, bc).toString(); + } + return String.format(indent + typeName + compositionFormatString, bc.getRolename(), bc.getLowerBound(), bc.getUpperBound(), bc.getDescription(), qnp.getFullyQualifiedName(bc).toString()); } @Override - protected String participantInsertionString(LogicalParticipant bc) { - return String.format(dummyType + participantFormatString, bc.getRolename(), + protected String participantInsertionString(LogicalParticipant bc, String indent) { + String typeName = dummyType; + PlatformEntity ce = (PlatformEntity) rezProc.getRealizingType(bc.getType(),ENTITY_REALIZATION_ERR,ENTITY_REALIZATION_MANY); + if (ce != null) { + typeName = qnp.relativeQualifiedName(ce, bc).toString(); + } + return String.format(indent + typeName + participantFormatString, bc.getRolename(), bc.getLowerBound(), bc.getUpperBound(), bc.getDescription(), qnp.getFullyQualifiedName(bc).toString(), bc.getSourceLowerBound(), bc.getSourceUpperBound()); } + @Override + protected String getRealizingTypeName(EObject realizingType) { + // TODO Auto-generated method stub + return ((PlatformDataType)realizingType).getName(); + } + } diff --git a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/PropUtils.java b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/PropUtils.java new file mode 100644 index 0000000..2cd6c9b --- /dev/null +++ b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/PropUtils.java @@ -0,0 +1,73 @@ +/** + * + */ +package com.epistimis.uddl.ui.contentassist; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.emf.common.util.EList; +//import org.eclipse.emf.core.Resource; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.xtext.naming.QualifiedName; + +import com.epistimis.uddl.UddlQNP; +import com.epistimis.uddl.scoping.IndexUtilities; +import com.google.inject.Inject; + +/** + * + */ +public class PropUtils { + + @Inject IndexUtilities ndxUtils; + @Inject UddlQNP qnp; + + final static String INDENT = "\t"; + + public static String indent(int cnt) { + StringBuilder ndentBldr = new StringBuilder(); + for (int i = 0; i < cnt; i++) { + ndentBldr.append(INDENT); + } + return ndentBldr.toString(); + } + + /** + * Return the shortest QN as string that will work as a valid reference, taking into account + * all the imported namespaces in the resource where the reference will go. + * @param ref The object to which we want the reference + * @param ctx The context object - where the reference will go + * @return The reference string + */ + public String minimalReferenceString( EObject ref, EObject ctx) { + // A minimal reference can be created based on the RQN - and then we can look at the imports + // in the Resource containing the context object and shorten it further from there. + QualifiedName result = qnp.relativeQualifiedName(ref, ctx); + + Resource res = ctx.eResource(); + EListcontent = res.getContents(); + // Get the root instance, then all the includes. The challenge here is that the type + // of the root object can differ depending on the file type. So we need to query for the includes using + // AQL + Map variables = new HashMap(); + variables.put("self", content.get(0)); + + // This works because all grammars use the same 'includes' feature name including. + Collection importedNamespaces = ndxUtils.processAQL(res.getResourceSet(), variables, "self.eGet('includes').eGet('importedNamespace')"); + + // Now get the 'importedNamespace' from each, remove the wildcard (if it's there) and convert the remainder + // to a QualifiedName. Then compare to the rqn to see if we can shorten the RQN. + for (Object o: importedNamespaces) { + String str = o.toString(); + QualifiedName testQN = qnp.minimalQualifiedName(ref, str); + if (testQN.getSegmentCount() < result.getSegmentCount()) { + result = testQN; + } + } + return result.toString(); + } + +} diff --git a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/RealizationProposalProcessor.java b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/RealizationProposalProcessor.java index 56894a2..7e5ded3 100644 --- a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/RealizationProposalProcessor.java +++ b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/RealizationProposalProcessor.java @@ -3,54 +3,82 @@ */ package com.epistimis.uddl.ui.contentassist; +import java.lang.invoke.MethodHandles; import java.lang.reflect.ParameterizedType; +import java.text.MessageFormat; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import org.apache.log4j.Logger; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.Assignment; import org.eclipse.xtext.RuleCall; -import org.eclipse.xtext.naming.IQualifiedNameProvider; import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext; import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor; import com.epistimis.uddl.EntityProcessor; import com.epistimis.uddl.RealizationProcessor; +import com.epistimis.uddl.UddlQNP; +import com.epistimis.uddl.scoping.IndexUtilities; import com.epistimis.uddl.uddl.UddlElement; import com.google.inject.Inject; /** * */ -abstract class RealizationProposalProcessor< - BaseEntity extends EObject, RealizingEntity extends UddlElement, - BaseCharacteristic extends EObject, RealizingCharacteristic extends EObject, - BaseComposition extends BaseCharacteristic, RealizingComposition extends RealizingCharacteristic, - BaseParticipant extends BaseCharacteristic, RealizingParticipant extends RealizingCharacteristic, - BaseAssociation extends BaseEntity, RealizingAssociation extends RealizingEntity, - RezProcessor extends RealizationProcessor, - BaseProcessor extends EntityProcessor, - RealizingProcessor extends EntityProcessor> -{ +abstract class RealizationProposalProcessor, + BaseProcessor extends EntityProcessor, + RealizingProcessor extends EntityProcessor> { + + private static Logger logger = Logger.getLogger(MethodHandles.lookup().lookupClass()); protected static String compositionFormatString = " %s[%d:%d] \"%s\" -> %s;\n"; protected static String participantFormatString = " %s[%d:%d] \"%s\" -> %s { source: [ %s : %d ] };\n"; - protected static String dummyType = "__ReplaceMe__"; - protected static String defaultComment = "// Replace " + dummyType + " with the ComposableElement type for each composition\n"; - protected static String proposalPrefix = "(Default) "; - protected static String proposalSuffix = ""; - protected static String realizeAll = "<>"; - protected static String realizeRemaining = "<>"; + protected static String dummyType = "__ReplaceMe__"; + protected static String defaultComment = "// Replace " + dummyType + + " with the ComposableElement type for each composition\n"; + protected static String proposalPrefix = "(Default) "; + protected static String proposalSuffix = ""; + protected static String realizeAll = "<>"; + protected static String realizeRemaining = "<>"; + + @Inject UddlQNP qnp; + @Inject PropUtils pu; + + @Inject IndexUtilities ndxUtil; - @Inject IQualifiedNameProvider qnp; - - abstract protected void completeSuperRealizingComposition(UddlProposalProvider pp, EObject obj, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) ; - abstract protected void completeSuperRealizingComposition_Rolename(UddlProposalProvider pp, EObject obj, Assignment assignment,ContentAssistContext context, ICompletionProposalAcceptor acceptor) ; + @Inject RezProcessor rezProc; + @Inject BaseProcessor bProc; + @Inject RealizingProcessor rProc; + + abstract protected void completeSuperRealizingComposition(UddlProposalProvider pp, EObject obj, RuleCall ruleCall, + ContentAssistContext context, ICompletionProposalAcceptor acceptor); + + abstract protected void completeSuperRealizingComposition_Rolename(UddlProposalProvider pp, EObject obj, + Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor); abstract protected String proposalDisplayString(BaseCharacteristic bc); - abstract protected String compositionInsertionString(BaseComposition bc); - abstract protected String participantInsertionString(BaseParticipant bc); + + abstract protected String compositionInsertionString(BaseComposition bc, String indent); + + abstract protected String participantInsertionString(BaseParticipant bc, String indent); + /** + * Realizing types don't have a common ancestor other than EObject. Cast them appropriately + * in the implementation. + * @param realizingType + * @return + */ + abstract protected String getRealizingTypeName(EObject realizingType); + /** * Get the type parameters for this generic class See also * https://stackoverflow.com/questions/4213972/java-generics-get-class-of-generic-methods-return-type @@ -70,74 +98,96 @@ public Class returnedTypeParameter(int ndx) { * @return */ @SuppressWarnings("rawtypes") - public Class getBaseEntityType() { + public Class getBaseComposableElementType() { return returnedTypeParameter(0); } @SuppressWarnings("rawtypes") - public Class getRealizingEntityType() { + public Class getRealizingComposableElementType() { return returnedTypeParameter(1); } @SuppressWarnings("rawtypes") - public Class getBaseCharacteristicType() { + public Class getBaseEntityType() { return returnedTypeParameter(2); } @SuppressWarnings("rawtypes") - public Class getRealizingCharacteristicType() { + public Class getRealizingEntityType() { return returnedTypeParameter(3); } @SuppressWarnings("rawtypes") - public Class getBaseCompositionType() { + public Class getBaseCharacteristicType() { return returnedTypeParameter(4); } @SuppressWarnings("rawtypes") - public Class getRealizingCompositionType() { + public Class getRealizingCharacteristicType() { return returnedTypeParameter(5); } @SuppressWarnings("rawtypes") - public Class getBaseParticipantType() { + public Class getBaseCompositionType() { return returnedTypeParameter(6); } @SuppressWarnings("rawtypes") - public Class getRealizingParticipantType() { + public Class getRealizingCompositionType() { return returnedTypeParameter(7); } - + @SuppressWarnings("rawtypes") - public Class getBaseAssociationType() { + public Class getBaseParticipantType() { return returnedTypeParameter(8); } @SuppressWarnings("rawtypes") - public Class getRealizingAssociationType() { + public Class getRealizingParticipantType() { return returnedTypeParameter(9); } + @SuppressWarnings("rawtypes") - public Class getRezProcessorType() { + public Class getBaseAssociationType() { return returnedTypeParameter(10); } + @SuppressWarnings("rawtypes") - public Class getBaseProcessorType() { + public Class getRealizingAssociationType() { return returnedTypeParameter(11); } + @SuppressWarnings("rawtypes") - public Class getRealizingProcessorType() { + public Class getRezProcessorType() { return returnedTypeParameter(12); } - - - public void complete_Composition(UddlProposalProvider pp,RezProcessor rproc, - RealizingEntity rentity, RuleCall ruleCall, ContentAssistContext context, - ICompletionProposalAcceptor acceptor) { + + @SuppressWarnings("rawtypes") + public Class getBaseProcessorType() { + return returnedTypeParameter(13); + } + + @SuppressWarnings("rawtypes") + public Class getRealizingProcessorType() { + return returnedTypeParameter(14); + } + + /** + * In general, we want to indent the content of any container based on the number of levels so far, + * which we can determine by looking at the number segments in the FQN + * @param object + * @return + */ + protected String contentIndent(EObject object) { + return PropUtils.indent(qnp.getFullyQualifiedName(object).getSegmentCount()); + + } + public void complete_Composition(UddlProposalProvider pp, RezProcessor rproc, RealizingEntity rentity, + RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { // Get all the standard stuff first completeSuperRealizingComposition(pp, rentity, ruleCall, context, acceptor); + String indent = contentIndent(rentity); // Now add customization here // When doing this, propose that all ConceptualCompositions be realized - but // only those that @@ -145,61 +195,110 @@ public void complete_Composition(UddlProposalProvider pp,RezProcessor rproc, Collection unrealized = rproc.getUnrealizedCompositions(rentity); List realizedParticipants = rproc.getRealizedParticipants(rentity); Collection unrealizedParticipants = rproc.getUnrealizedParticipants(rentity); - + String result = defaultComment; for (BaseComposition cc : unrealized) { + // If this one isn't already realized, then add it to the proposal + String oneRealizedCC = compositionInsertionString(cc,indent); + String displayString = proposalDisplayString(cc); + acceptor.accept(pp.createCompletionProposal(oneRealizedCC, displayString, null, context)); + result += oneRealizedCC; + } + if (!unrealizedParticipants.isEmpty()) { + result += "\n participants: ["; + + for (BaseParticipant cp : unrealizedParticipants) { // If this one isn't already realized, then add it to the proposal - String oneRealizedCC = compositionInsertionString(cc) ; - String displayString = proposalDisplayString(cc); - acceptor.accept(pp.createCompletionProposal(oneRealizedCC, displayString,null, context)); - result += oneRealizedCC; + String oneRealizedCP = participantInsertionString(cp,indent); + String proposalString = proposalDisplayString(cp); + acceptor.accept(pp.createCompletionProposal(oneRealizedCP, proposalString, null, context)); + result += oneRealizedCP; + } + result += "]"; } - if (!unrealizedParticipants.isEmpty()) { - result += "\n participants: ["; - - for (BaseParticipant cp: unrealizedParticipants) { - // If this one isn't already realized, then add it to the proposal - String oneRealizedCP = participantInsertionString(cp); - String proposalString = proposalDisplayString(cp); - acceptor.accept(pp.createCompletionProposal(oneRealizedCP,proposalString, null, context)); - result += oneRealizedCP; - } - result += "]"; - } /** * Only do the "all" if nothing has been done yet */ if (realized.isEmpty() && realizedParticipants.isEmpty()) { acceptor.accept(pp.createCompletionProposal(result, realizeAll, null, context)); - } - else if (!unrealized.isEmpty() || !unrealizedParticipants.isEmpty()) { + } else if (!unrealized.isEmpty() || !unrealizedParticipants.isEmpty()) { acceptor.accept(pp.createCompletionProposal(result, realizeRemaining, null, context)); } } - public void completeComposition_Rolename(UddlProposalProvider pp,RezProcessor rproc,RealizingEntity rentity, Assignment assignment, ContentAssistContext context, - ICompletionProposalAcceptor acceptor) { + private Collection getRealizingTypes(BaseComposition bcomp) { + BaseComposableElement baseType = bProc.getCompositionType(bcomp); + if (baseType != null) { + return rezProc.getRealizingTypes(baseType); + } + return new HashSet<>(); + } + /** + * The type must be a type that realizes the BaseComposition, if it has been + * specified. If not, then it must be a type that realizes one of the + * BaseCompositions from the BaseEntity realized by the containing + * RealizingEntity. + * + * @param pp + * @param rentity + * @param assignment + * @param context + * @param acceptor + */ + public void completeComposition_Type(UddlProposalProvider pp, RealizingEntity rentity, //RealizingComposition rcomp, + Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { +// BaseComposition bcomp = rezProc.getRealizedComposition(rcomp); +// BaseComposableElement baseType = bProc.getCompositionType(bcomp); + Set realizingTypes = new HashSet(); +// if (baseType != null) { +// realizingTypes = rezProc.getRealizingTypes(baseType); +// } +// else { + // Get the types for all the composition elements in the realized Entity + BaseEntity bentity = rezProc.getRealizedEntity(rentity); + Collection bcomps = bProc.allCompositions(bentity).values(); + for (BaseComposition bc : bcomps) { + realizingTypes.addAll(getRealizingTypes(bc)); + } +// } + /* + * If there are **no** realizing types, then we've got a lot of work to do + */ + if (realizingTypes.isEmpty()) { + String msg = MessageFormat.format("No realizing types found for any composition elements of {0}",qnp.getFullyQualifiedName(rentity)); + logger.info(msg); + System.out.println(msg); + } + for (EObject rce: realizingTypes) { + String insertionString = pu.minimalReferenceString( rce, rentity); + String displayString = getRealizingTypeName(rce); + acceptor.accept(pp.createCompletionProposal(insertionString, displayString, null, context)); + } + } + + public void completeComposition_Rolename(UddlProposalProvider pp, RezProcessor rproc, RealizingEntity rentity, + Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { completeSuperRealizingComposition_Rolename(pp, rentity, assignment, context, acceptor); // Pick out the roles from the list of unrealized Compositions for (BaseComposition cc : rproc.getUnrealizedCompositions(rentity)) { - // If this one isn't already realized, then add it to the proposal - String oneRealizedCC = compositionInsertionString(cc) ; + // If this one isn't already realized, then add it to the proposal + String oneRealizedCC = compositionInsertionString(cc,""); String displayString = proposalDisplayString(cc); - acceptor.accept(pp.createCompletionProposal(oneRealizedCC, displayString, null, context)); + acceptor.accept(pp.createCompletionProposal(oneRealizedCC, displayString, null, context)); } } - public void completeComposition_Realizes(UddlProposalProvider pp,RezProcessor rproc,RealizingEntity rentity, Assignment assignment, ContentAssistContext context, - ICompletionProposalAcceptor acceptor) { + public void completeComposition_Realizes(UddlProposalProvider pp, RezProcessor rproc, RealizingEntity rentity, + Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { for (BaseComposition cc : rproc.getUnrealizedCompositions(rentity)) { - String displayString = proposalDisplayString(cc); - acceptor.accept(pp.createCompletionProposal(qnp.getFullyQualifiedName(cc).toString(), - displayString, null, context)); + String displayString = proposalDisplayString(cc); + acceptor.accept(pp.createCompletionProposal(qnp.getFullyQualifiedName(cc).toString(), displayString, null, + context)); } - + } } diff --git a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/UddlProposalProvider.java b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/UddlProposalProvider.java index 63ae580..19e5491 100644 --- a/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/UddlProposalProvider.java +++ b/com.epistimis.uddl.ui/src/com/epistimis/uddl/ui/contentassist/UddlProposalProvider.java @@ -8,17 +8,11 @@ import java.lang.invoke.MethodHandles; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; import org.apache.log4j.Logger; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.xtext.Assignment; +import org.eclipse.xtext.CrossReference; import org.eclipse.xtext.RuleCall; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.scoping.IScopeProvider; @@ -32,14 +26,15 @@ import com.epistimis.uddl.PlatformEntityProcessor; import com.epistimis.uddl.UddlQNP; import com.epistimis.uddl.scoping.IndexUtilities; +import com.epistimis.uddl.uddl.LogicalComposition; import com.epistimis.uddl.uddl.LogicalEntity; import com.epistimis.uddl.uddl.LogicalMeasurement; import com.epistimis.uddl.uddl.LogicalMeasurementAttribute; import com.epistimis.uddl.uddl.LogicalMeasurementAxis; -import com.epistimis.uddl.uddl.PlatformDataType; +import com.epistimis.uddl.uddl.PlatformComposableElement; +import com.epistimis.uddl.uddl.PlatformComposition; import com.epistimis.uddl.uddl.PlatformEntity; import com.epistimis.uddl.uddl.PlatformStruct; -import com.epistimis.uddl.uddl.UddlPackage; import com.google.inject.Inject; /** @@ -50,6 +45,17 @@ public class UddlProposalProvider extends AbstractUddlProposalProvider { private static Logger logger = Logger.getLogger(MethodHandles.lookup().lookupClass()); + + final static String ABS_MEAS_REALIZATION_ERR = "AbstractMeasurement {0} is not realized by any PlatformDataType"; + final static String ABS_MEAS_REALIZATION_MANY = "AbstractMeasurement {0} is realized by multiple PlatformDataTypes - picking one"; + final static String DEFAULT_PRECISION = "0.01"; + final static String INDENT = "\t"; + final static String MEMBER_DISPLAY_FMT = "{0}" ; + final static String REALIZE_ALL = "<>"; + final static String STRUCT_REALIZATION_ERR = "PlatformStruct {0} must realize a LogicalMeasurement with 2+ axes / attributes. {1} only has {2}"; + final static String STRUCT_AXIS_FMT = "{0} {1} ( {2} ) ;" ; + final static String STRUCT_ATTRIBUTE_FMT = "{0} {1} ( {2} ) -> {3} ;" ; + @Inject UddlQNP qnp; @Inject IndexUtilities ndxUtil; @Inject IScopeProvider sp; @@ -91,6 +97,12 @@ public void complete_LogicalComposition(EObject obj, RuleCall ruleCall, ContentA clrpproc.complete_Composition(this,clrproc, (LogicalEntity)obj, ruleCall, context, acceptor); } +// @Override +// public void completeLogicalComposition_Type(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { +//// lookupCrossReference(((CrossReference)assignment.getTerminal()), context, acceptor); +// clrpproc.completeComposition_Type(this, (LogicalEntity)model, assignment, context, acceptor); +// +// } /** * The only way to force calling a super class method is by calling from the derived class. So we create this callback to * be used by clrpproc to force the call to the super class method @@ -116,6 +128,7 @@ public void completeLogicalComposition_Realizes(EObject obj, Assignment assignme } /** Platform -> Logical */ + /** * The only way to force calling a super class method is by calling from the derived class. So we create this callback to * be used by clrpproc to force the call to the super class method @@ -135,6 +148,12 @@ public void complete_PlatformComposition(EObject obj, RuleCall ruleCall, Content } +// @Override +// public void completePlatformComposition_Type(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { +//// lookupCrossReference(((CrossReference)assignment.getTerminal()), context, acceptor); +// lprpproc.completeComposition_Type(this, (PlatformEntity)model, assignment, context, acceptor); +// +// } /** * The only way to force calling a super class method is by calling from the derived class. So we create this callback to * be used by clrpproc to force the call to the super class method @@ -162,49 +181,6 @@ public void completePlatformComposition_Realizes(EObject obj, Assignment assignm } - final private static String INDENT = "\t"; - private String indent(int cnt) { - StringBuilder ndentBldr = new StringBuilder(); - for (int i = 0; i < cnt; i++) { - ndentBldr.append(INDENT); - } - return ndentBldr.toString(); - } - final static String STRUCT_REALIZATION_ERR = "PlatformStruct {0} must realize a LogicalMeasurement with 2+ axes / attributes. {1} only has {2}"; - final static String DEFAULT_PRECISION = "0.01"; - final static String STRUCT_AXIS_FMT = "{0} {1} ( {2} ) ;" ; - final static String STRUCT_ATTRIBUTE_FMT = "{0} {1} ( {2} ) -> {3} ;" ; - final static String MEMBER_DISPLAY_FMT = "{0}" ; - final static String ABS_MEAS_REALIZATION_ERR = "AbstractMeasurement {0} is not realized by any PlatformDataType"; - final static String ABS_MEAS_REALIZATION_MANY = "AbstractMeasurement {0} is realized by multiple PlatformDataTypes - picking one"; - final static String REALIZE_ALL = "<>"; - - /** - * Find a realiz - * @param pkgs - * @param type2Realize - * @param ndent - * @return - */ - protected PlatformDataType getRealizingDataType( List pkgs, EObject type2Realize) { - Map variables = new HashMap(); - variables.put("self", type2Realize); - ResourceSet resourceSet = type2Realize.eResource().getResourceSet(); - Set found = ndxUtil.processAQL(resourceSet, pkgs,variables,"self.eInverse('realizes')"); - if ((found == null) || (found.size() == 0 )) { - String msg = MessageFormat.format(ABS_MEAS_REALIZATION_ERR, qnp.getFullyQualifiedName(type2Realize)); - logger.error(msg); - System.out.println(msg); - return null; - } - if (found.size() > 1) { - String msg = MessageFormat.format(ABS_MEAS_REALIZATION_MANY, qnp.getFullyQualifiedName(type2Realize)); - logger.info(msg); - System.out.println(msg); - } - // Return the first one found - return (PlatformDataType)found.iterator().next(); - } @Override public void completePlatformStruct_Member(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { @@ -218,8 +194,8 @@ public void completePlatformStruct_Member(EObject model, Assignment assignment, // This can realize a LogicalMeasurement or a LogicalMeasurementAxis. // See idlTypeConsistentlyRealizesMeasurementAxis in constraints/platform.ocl // - List pkgs = new ArrayList<>(); - pkgs.add(UddlPackage.eINSTANCE); +// List pkgs = new ArrayList<>(); +// pkgs.add(UddlPackage.eINSTANCE); EObject obj = ps.getRealizes(); if (obj instanceof LogicalMeasurement) { @@ -231,7 +207,7 @@ public void completePlatformStruct_Member(EObject model, Assignment assignment, logger.error(msg); System.out.println(msg); } - String ndent = indent(qnp.getFullyQualifiedName(model).getSegmentCount()); + String ndent = PropUtils.indent(qnp.getFullyQualifiedName(model).getSegmentCount()); StringBuilder insertionText = new StringBuilder(); @@ -239,12 +215,12 @@ public void completePlatformStruct_Member(EObject model, Assignment assignment, // In order to propose the entire structure, we could find every possible combination. That could get messy. For now, // just pick a combination since users can edit this later. for (LogicalMeasurementAxis axis: meas.getMeasurementAxis()) { - PlatformDataType realizingPDT = getRealizingDataType(pkgs,axis); - if (realizingPDT != null) { + PlatformComposableElement realizingPCE = (PlatformComposableElement) lprproc.getRealizingType(/*pkgs,*/axis, ABS_MEAS_REALIZATION_ERR,ABS_MEAS_REALIZATION_MANY ); + if (realizingPCE != null) { StringBuilder oneProp = new StringBuilder(); oneProp.append("\n" + ndent); // Set the type name - QualifiedName n = qnp.relativeQualifiedName(realizingPDT, model); + QualifiedName n = qnp.relativeQualifiedName(realizingPCE, model); String displayString = MessageFormat.format(MEMBER_DISPLAY_FMT,n.getLastSegment()); oneProp.append(MessageFormat.format(STRUCT_AXIS_FMT,n.toString(), n.getLastSegment().toLowerCase(), DEFAULT_PRECISION)); String insertionString = oneProp.toString(); @@ -255,12 +231,12 @@ public void completePlatformStruct_Member(EObject model, Assignment assignment, for (LogicalMeasurementAttribute attr: meas.getAttribute()) { // Get the type of the MeasurementAttribute - this should be realized by the StructMember's type EObject realizedAttrType = attr.getType(); - PlatformDataType realizingPDT = getRealizingDataType(pkgs,realizedAttrType); - if (realizingPDT != null) { + PlatformComposableElement realizingPCE = (PlatformComposableElement) lprproc.getRealizingType(/*pkgs,*/realizedAttrType, ABS_MEAS_REALIZATION_ERR,ABS_MEAS_REALIZATION_MANY ); + if (realizingPCE != null) { StringBuilder oneProp = new StringBuilder(); oneProp.append("\n" + ndent); // Set the type name - QualifiedName typeName = qnp.relativeQualifiedName(realizingPDT, model); + QualifiedName typeName = qnp.relativeQualifiedName(realizingPCE, model); QualifiedName n = qnp.relativeQualifiedName(attr, model); String displayString = MessageFormat.format(MEMBER_DISPLAY_FMT,n.toString()); oneProp.append(MessageFormat.format(STRUCT_ATTRIBUTE_FMT,typeName.toString(), n.getLastSegment().toLowerCase(), DEFAULT_PRECISION, n.toString())); @@ -290,11 +266,11 @@ public void completePlatformStruct_Member(EObject model, Assignment assignment, } - @Override - public void complete_PlatformStructMember(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - // Each member - // Look at what this object realizes and create a proposal for each - This isn't part - - } +// @Override +// public void complete_PlatformStructMember(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { +// // Each member +// // Look at what this object realizes and create a proposal for each - This isn't part +// +// } }