Loading plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/Validator.java +159 −32 Original line number Diff line number Diff line Loading @@ -6,12 +6,17 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.URISyntaxException; import java.net.URL; import java.net.URLEncoder; import java.net.UnknownHostException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; Loading @@ -23,15 +28,16 @@ import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.epsilon.common.parse.Region; import org.eclipse.epsilon.common.parse.problem.ParseProblem; import org.eclipse.epsilon.common.util.StringProperties; import org.eclipse.epsilon.emc.emf.EmfModel; Loading @@ -42,6 +48,8 @@ import org.eclipse.epsilon.eol.exceptions.EolRuntimeException; import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException; import org.eclipse.epsilon.eol.models.IModel; import org.eclipse.epsilon.eol.tools.MathTool; import org.eclipse.epsilon.eol.types.AbstractToolNativeTypeDelegate; import org.eclipse.epsilon.eol.types.EolClasspathNativeTypeDelegate; import org.eclipse.epsilon.etl.EtlModule; import org.eclipse.epsilon.evl.EvlModule; import org.eclipse.epsilon.evl.IEvlFixer; Loading @@ -49,24 +57,75 @@ import org.eclipse.epsilon.evl.execute.UnsatisfiedConstraint; import org.eclipse.epsilon.profiling.Profiler; import org.eclipse.epsilon.profiling.ProfilerTargetSummary; import org.eclipse.epsilon.profiling.ProfilingExecutionListener; import org.eclipse.xtext.nodemodel.ICompositeNode; import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.eclipse.xtext.resource.XtextResource; import org.etsi.mts.tdl.tdlPackage; import org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage; import org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage; import org.osgi.framework.Bundle; @SuppressWarnings("unused") public class Validator { public List<UnsatisfiedConstraint> validate(Resource r) { private static final List<EPackage> packages = List.of(tdlPackage.eINSTANCE, StructuredObjectivesPackage.eINSTANCE, ExtendedConfigurationsPackage.eINSTANCE); public List<UnsatisfiedConstraint> validate(Resource r) throws Exception { List<UnsatisfiedConstraint> violations = new ArrayList<>(); String prefix = "tdl-generated-ETSI-ES-203-119-"; String suffix = "-fixed.evl"; //TODO: Change versions to published? List<String> constraints = List.of( prefix+"1-V1.5.1"+suffix, prefix+"4-V1.4.1"+suffix, prefix+"7-V1.2.1"+suffix ); try { String source = "epsilon/constraints/tdl.evl"; //TODO: also for TO? //TODO: This is very important otherwise all kinds of weird problems might occur (in case it may be put in the handler as well) EcoreUtil.resolveAll(r); //TODO: Run all, maintain generated and fixed for differencing between versions and manual interventions //FIXED: Meta-models not resolved in plugin mode? -> fixed IModel tdlModel = getTDLModel(r, true, false); tdlModel.load(); List<IModel> dependencies = new ArrayList<>(); //TODO: this can cause duplicate definitions, resolveAll above makes this unnecessary // System.out.println("Loading validation dependencies for: "+r.getURI().path()); // for (Resource d : r.getResourceSet().getResources()) { // if (d!=r) { // System.out.println(" Loading "+d.getURI().path()); // IModel dModel = getTDLModel(d, true, false); // dModel.load(); // dependencies.add(dModel); // } // } // String source = "epsilon/constraints/tdl.evl"; for (String part : constraints) { String source = "epsilon/constraints/"+part; java.net.URI uri = new File(source).toURI(); //FIXED: also for TO? -> should work with all now if (Platform.isRunning()) { //System.out.println("Running as plugin..."); Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.constraints"); URL url = bundle.getEntry(source); uri = url.toURI(); } else { //WS String binPath=this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); String projectPath = new File(binPath).getParent(); uri = new File(projectPath+"/"+source).toURI(); } EvlModule module = new EvlModule(); module.parse(url.toURI()); module.parse(uri); //DONE: For some reason default classpath delegate does not work -> add custom delegate // module.getContext().getNativeTypeDelegates().add(new EolClasspathNativeTypeDelegate()); module.getContext().getNativeTypeDelegates().add(new XtextBridgeNativeTypeDelegate()); //FIXED: Defer warnings in case necessary -> not at present // module.getContext().setWarningStream(new PrintStream("Epsilon.log")); //TODO: integrate error reporting if (module.getParseProblems().size() > 0) { Loading @@ -76,40 +135,108 @@ public class Validator { } } IModel tdlModel = getTDLModel(r, true, false); tdlModel.load(); // dumpConstraints(module); module.getContext().getModelRepository().addModel(tdlModel); //add dependencies module.getContext().getModelRepository().addModels(dependencies); //execute module.execute(); EvlModule m = (EvlModule) module; violations.addAll(m.getContext().getUnsatisfiedConstraints()); for (UnsatisfiedConstraint constraint : m.getContext().getUnsatisfiedConstraints()) { System.out.println(" " + constraint.getMessage()); } tdlModel.dispose(); //filter only within resource violations = violations.stream() .filter(v -> ((EObject)v.getInstance()).eResource() == r) .collect(Collectors.toList()); dumpViolations(violations); //TODO: Needed? New API does not provide it // module.reset(); } tdlModel.dispose(); for (IModel d : dependencies) { d.dispose(); } } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { //TODO: Error message refinements System.err.println(e.getMessage() .replaceAll("\n.+epsilon/", "\n at (epsilon/") // .replaceAll("\\.", "") // .replaceAll("evl@", "evl:") // .replaceAll(":(\\d+).+", ":$1)") // .replaceAll("-", "") // .replaceAll("\n.+/", "\n at (") ); throw(e); // e.printStackTrace(); } return violations; } private void dumpViolations(List<UnsatisfiedConstraint> violations) { for (UnsatisfiedConstraint constraint : violations) { System.out.println(" " + constraint.getMessage()); //TODO: this can only work with XtextResources if (((EObject) constraint.getInstance()).eResource() instanceof XtextResource) { ICompositeNode node = NodeModelUtils.findActualNodeFor((EObject) constraint.getInstance()); String text = "Line "+node.getStartLine()+"-"+node.getEndLine()+ ": "+node.getText().trim(); System.out.println(" " + text); } else { //TODO: handle other resources } } } private void dumpConstraints(EvlModule module) { //Dump -> extract to separate functionality for (var cx : module.getDeclaredConstraintContexts()) { System.out.println(cx); for (var cs : cx.getConstraints()) { System.out.println(" "+cs); System.out.println(" check:"+getSnippet(module.getFile(), cs.getCheckBlock().getBody().getRegion())); System.out.println(" message:"+getSnippet(module.getFile(), cs.getMessageBlock().getBody().getRegion())); } } } private String getSnippet(File file, Region region) { String snippet = ""; try { List<String> lines = Files.readAllLines(Path.of(file.getPath())); lines.add(0, ""); lines = lines.subList(region.getStart().getLine(), region.getEnd().getLine()+1); // System.out.println(lines); lines.set(lines.size()-1, lines.get(lines.size()-1).substring(0, region.getEnd().getColumn())); lines.set(0, lines.get(0).substring(region.getStart().getColumn()-1)); lines = lines.stream().filter(l -> !l.trim().startsWith("//")).toList(); snippet = String.join(" ", lines) .replaceAll("\\s+", " ") ; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return violations; return snippet; } //TODO: extract to shared library public IModel getTDLModel(Resource resource, boolean read, boolean write) throws Exception { EmfModel model; model = new InMemoryEmfModel("TDL", resource, tdlPackage.eINSTANCE); //FIXED: meta-models not resolved in plugin mode? -> seems to work now // model = new InMemoryEmfModel(resource); model = new InMemoryEmfModel("TDL", resource, packages); model.setStoredOnDisposal(write); model.setReadOnLoad(read); model.setCachingEnabled(true); model.setMetamodelUris(List.of(tdlPackage.eNS_URI, StructuredObjectivesPackage.eNS_URI, ExtendedConfigurationsPackage.eNS_URI)); return model; } Loading Loading
plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/Validator.java +159 −32 Original line number Diff line number Diff line Loading @@ -6,12 +6,17 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.URISyntaxException; import java.net.URL; import java.net.URLEncoder; import java.net.UnknownHostException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; Loading @@ -23,15 +28,16 @@ import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.epsilon.common.parse.Region; import org.eclipse.epsilon.common.parse.problem.ParseProblem; import org.eclipse.epsilon.common.util.StringProperties; import org.eclipse.epsilon.emc.emf.EmfModel; Loading @@ -42,6 +48,8 @@ import org.eclipse.epsilon.eol.exceptions.EolRuntimeException; import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException; import org.eclipse.epsilon.eol.models.IModel; import org.eclipse.epsilon.eol.tools.MathTool; import org.eclipse.epsilon.eol.types.AbstractToolNativeTypeDelegate; import org.eclipse.epsilon.eol.types.EolClasspathNativeTypeDelegate; import org.eclipse.epsilon.etl.EtlModule; import org.eclipse.epsilon.evl.EvlModule; import org.eclipse.epsilon.evl.IEvlFixer; Loading @@ -49,24 +57,75 @@ import org.eclipse.epsilon.evl.execute.UnsatisfiedConstraint; import org.eclipse.epsilon.profiling.Profiler; import org.eclipse.epsilon.profiling.ProfilerTargetSummary; import org.eclipse.epsilon.profiling.ProfilingExecutionListener; import org.eclipse.xtext.nodemodel.ICompositeNode; import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.eclipse.xtext.resource.XtextResource; import org.etsi.mts.tdl.tdlPackage; import org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage; import org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage; import org.osgi.framework.Bundle; @SuppressWarnings("unused") public class Validator { public List<UnsatisfiedConstraint> validate(Resource r) { private static final List<EPackage> packages = List.of(tdlPackage.eINSTANCE, StructuredObjectivesPackage.eINSTANCE, ExtendedConfigurationsPackage.eINSTANCE); public List<UnsatisfiedConstraint> validate(Resource r) throws Exception { List<UnsatisfiedConstraint> violations = new ArrayList<>(); String prefix = "tdl-generated-ETSI-ES-203-119-"; String suffix = "-fixed.evl"; //TODO: Change versions to published? List<String> constraints = List.of( prefix+"1-V1.5.1"+suffix, prefix+"4-V1.4.1"+suffix, prefix+"7-V1.2.1"+suffix ); try { String source = "epsilon/constraints/tdl.evl"; //TODO: also for TO? //TODO: This is very important otherwise all kinds of weird problems might occur (in case it may be put in the handler as well) EcoreUtil.resolveAll(r); //TODO: Run all, maintain generated and fixed for differencing between versions and manual interventions //FIXED: Meta-models not resolved in plugin mode? -> fixed IModel tdlModel = getTDLModel(r, true, false); tdlModel.load(); List<IModel> dependencies = new ArrayList<>(); //TODO: this can cause duplicate definitions, resolveAll above makes this unnecessary // System.out.println("Loading validation dependencies for: "+r.getURI().path()); // for (Resource d : r.getResourceSet().getResources()) { // if (d!=r) { // System.out.println(" Loading "+d.getURI().path()); // IModel dModel = getTDLModel(d, true, false); // dModel.load(); // dependencies.add(dModel); // } // } // String source = "epsilon/constraints/tdl.evl"; for (String part : constraints) { String source = "epsilon/constraints/"+part; java.net.URI uri = new File(source).toURI(); //FIXED: also for TO? -> should work with all now if (Platform.isRunning()) { //System.out.println("Running as plugin..."); Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.constraints"); URL url = bundle.getEntry(source); uri = url.toURI(); } else { //WS String binPath=this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); String projectPath = new File(binPath).getParent(); uri = new File(projectPath+"/"+source).toURI(); } EvlModule module = new EvlModule(); module.parse(url.toURI()); module.parse(uri); //DONE: For some reason default classpath delegate does not work -> add custom delegate // module.getContext().getNativeTypeDelegates().add(new EolClasspathNativeTypeDelegate()); module.getContext().getNativeTypeDelegates().add(new XtextBridgeNativeTypeDelegate()); //FIXED: Defer warnings in case necessary -> not at present // module.getContext().setWarningStream(new PrintStream("Epsilon.log")); //TODO: integrate error reporting if (module.getParseProblems().size() > 0) { Loading @@ -76,40 +135,108 @@ public class Validator { } } IModel tdlModel = getTDLModel(r, true, false); tdlModel.load(); // dumpConstraints(module); module.getContext().getModelRepository().addModel(tdlModel); //add dependencies module.getContext().getModelRepository().addModels(dependencies); //execute module.execute(); EvlModule m = (EvlModule) module; violations.addAll(m.getContext().getUnsatisfiedConstraints()); for (UnsatisfiedConstraint constraint : m.getContext().getUnsatisfiedConstraints()) { System.out.println(" " + constraint.getMessage()); } tdlModel.dispose(); //filter only within resource violations = violations.stream() .filter(v -> ((EObject)v.getInstance()).eResource() == r) .collect(Collectors.toList()); dumpViolations(violations); //TODO: Needed? New API does not provide it // module.reset(); } tdlModel.dispose(); for (IModel d : dependencies) { d.dispose(); } } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { //TODO: Error message refinements System.err.println(e.getMessage() .replaceAll("\n.+epsilon/", "\n at (epsilon/") // .replaceAll("\\.", "") // .replaceAll("evl@", "evl:") // .replaceAll(":(\\d+).+", ":$1)") // .replaceAll("-", "") // .replaceAll("\n.+/", "\n at (") ); throw(e); // e.printStackTrace(); } return violations; } private void dumpViolations(List<UnsatisfiedConstraint> violations) { for (UnsatisfiedConstraint constraint : violations) { System.out.println(" " + constraint.getMessage()); //TODO: this can only work with XtextResources if (((EObject) constraint.getInstance()).eResource() instanceof XtextResource) { ICompositeNode node = NodeModelUtils.findActualNodeFor((EObject) constraint.getInstance()); String text = "Line "+node.getStartLine()+"-"+node.getEndLine()+ ": "+node.getText().trim(); System.out.println(" " + text); } else { //TODO: handle other resources } } } private void dumpConstraints(EvlModule module) { //Dump -> extract to separate functionality for (var cx : module.getDeclaredConstraintContexts()) { System.out.println(cx); for (var cs : cx.getConstraints()) { System.out.println(" "+cs); System.out.println(" check:"+getSnippet(module.getFile(), cs.getCheckBlock().getBody().getRegion())); System.out.println(" message:"+getSnippet(module.getFile(), cs.getMessageBlock().getBody().getRegion())); } } } private String getSnippet(File file, Region region) { String snippet = ""; try { List<String> lines = Files.readAllLines(Path.of(file.getPath())); lines.add(0, ""); lines = lines.subList(region.getStart().getLine(), region.getEnd().getLine()+1); // System.out.println(lines); lines.set(lines.size()-1, lines.get(lines.size()-1).substring(0, region.getEnd().getColumn())); lines.set(0, lines.get(0).substring(region.getStart().getColumn()-1)); lines = lines.stream().filter(l -> !l.trim().startsWith("//")).toList(); snippet = String.join(" ", lines) .replaceAll("\\s+", " ") ; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return violations; return snippet; } //TODO: extract to shared library public IModel getTDLModel(Resource resource, boolean read, boolean write) throws Exception { EmfModel model; model = new InMemoryEmfModel("TDL", resource, tdlPackage.eINSTANCE); //FIXED: meta-models not resolved in plugin mode? -> seems to work now // model = new InMemoryEmfModel(resource); model = new InMemoryEmfModel("TDL", resource, packages); model.setStoredOnDisposal(write); model.setReadOnLoad(read); model.setCachingEnabled(true); model.setMetamodelUris(List.of(tdlPackage.eNS_URI, StructuredObjectivesPackage.eNS_URI, ExtendedConfigurationsPackage.eNS_URI)); return model; } Loading