Parsing constraints having elements from differents packages [message #1817955] |
Tue, 03 December 2019 10:04  |
Eclipse User |
|
|
|
Hello,
I'm trying to parse OCL constraints of the UML metamodel using an UML.ecore file containing different UML packages, each of these packages represents a UML diagram (Actions, Activities, ...).
The constraints that use elements from one package are perfectly parsed, However, I am getting errors like "Unknown type" or "Unrecognized variable" when an element that is pointed in the constraint does not belong to THE package containing the "context class". In other words, in a UML MM hierarchy, some superclasses do not belong to the same package as the subclasses, so when trying to access to an attribute defined in this superclass from the subclass, the OCL engine does not find it!
Here is my constraint:
package UML::Activities::CommonBehaviors::Communications
context UML::Actions::CompleteActions::AcceptCallAction
inv result_pins : let parameter: OrderedSet(Parameter) = trigger.event->asSequence()->first().oclAsType(CallEvent).operation.inputParameters() in
result->size() = parameter->size() and
Sequence{1..result->size()}->forAll(i |
parameter->at(i).type.conformsTo(result->at(i).type) and
parameter->at(i).isOrdered = result->at(i).isOrdered and
parameter→at(i).compatibleWith(result→at(i)))
endpackage
How can I proceed to fix this issue? is it by merging the packages to get only one package?
The metamodel is also joined.
Thank you in advance
Attachment: UML.ecore
(Size: 1.39MB, Downloaded 197 times)
Attachment: UML.ecore
(Size: 1.39MB, Downloaded 181 times)
|
|
|
|
Re: Parsing constraints having elements from differents packages [message #1818073 is a reply to message #1818030] |
Thu, 05 December 2019 04:22   |
Eclipse User |
|
|
|
Hi Ed,
Thank you for your answer, I'm trying to transform UML's constraints from ".OCL" to ".Xmi" to get a syntactical tree with the OCL metamodel components.
To parse the constraints first, I'm using a class that I suspect to be outdated. The code is the following :
public class ModelOCL {
/**
* @param args
*/
private ResourceSet resSet;
private Collection<Constraint> Contraintes;
public ModelOCL(){
resSet = new ResourceSetImpl();
resSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(XMIResource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
}
public void loadModel(String pathModel, String pathOCL){
ResourceSet resourceSet = new ResourceSetImpl();
// Register the default resource factory -- only needed for stand-alone!
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(XMIResource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
URI fileURI = URI.createFileURI(pathModel);
// Demand load the resource for this file.
Resource resource = resourceSet.getResource(fileURI, true);
EList<EObject> modelContents=resource.getContents();
// Load OCL file
EPackage.Registry.INSTANCE.put(((EPackage) modelContents.get(0)).getName(), modelContents.get(0));
OCL<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> ocl;
ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE);
InputStream in;
Contraintes = new HashSet<Constraint>();
try
{
in = new FileInputStream(pathOCL);
// parse the contents as an OCL document
try
{
OCLInput document = new OCLInput(in);
Contraintes = ocl.parse(document);
}
catch (ParserException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.getCause());
}
finally
{
try
{
in.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void OCLToXML(String path) {
Resource newResource = resSet.createResource(URI.createURI(path));
for (Constraint Contrainte:Contraintes )
newResource.getContents().add(Contrainte);
try {
newResource.save(Collections.EMPTY_MAP);
} catch (IOException e) {
//e.printStackTrace();
}
}
protected void XmlToOCL(String path) {
File file = new File(path);
String stringOCL = "package \n\n";
for (Constraint Contrainte : Contraintes) {
OCLExpression<EClassifier> body = Contrainte.getSpecification()
.getBodyExpression();
Variable<EClassifier, EParameter> context = Contrainte
.getSpecification().getContextVariable();
stringOCL += "context " + context.getType().getEPackage().getName()+
"::"+context.getType().getName() + "\n"
+ "inv " + Contrainte.getName() + ":\n\t" + body.accept(ToString.getInstance(body)) + "\n\n";
System.out.println(stringOCL);
}
FileWriter fw = null;
try {
fw = new FileWriter(file);
fw.write(stringOCL);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ModelOCL test =new ModelOCL();
test.loadModel("./outputs/UML.ecore", "./inputs/UML.ocl");
}
}
Is there any package that does this transformation from constraint.ocl to constraint.xmi programmatically?
Regards,
Elyes
[Updated on: Thu, 05 December 2019 04:24] by Moderator
|
|
|
Re: Parsing constraints having elements from differents packages [message #1818082 is a reply to message #1818073] |
Thu, 05 December 2019 05:56  |
Eclipse User |
|
|
|
Hi
Conversion of *.ocl to *.xmi is close to meaningless since the OMG specification of XMI serialization is seriously deficient.
The Pivot OCL, which you are not using, prototypes a credible XMI serialization so that if you open a *.ocl file in the Complete OCL editor, the context menu offers OCL->Save Abstract Syntax, or OCL->Save As Pivot. These are just UI for underlying capabilities.
Regards
Ed Willink
|
|
|
Powered by
FUDForum. Page generated in 0.07548 seconds