Newer
Older
package org.etsi.mts.tdl.constraints.evl;
import java.io.BufferedInputStream;
import java.io.File;
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.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;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
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.Platform;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EObjectValidator;
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;
import org.eclipse.epsilon.emc.emf.EmfUtil;
import org.eclipse.epsilon.emc.emf.InMemoryEmfModel;
import org.eclipse.epsilon.eol.EolModule;
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;
import org.eclipse.epsilon.evl.IEvlModule;
import org.eclipse.epsilon.evl.emf.validation.CompositeEValidator;
import org.eclipse.epsilon.evl.emf.validation.EvlValidator;
import org.eclipse.epsilon.evl.emf.validation.EvlValidator.ValidationProblemListener;
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.structuredobjectives.StructuredObjectivesPackage;
import org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage;
import org.osgi.framework.Bundle;
@SuppressWarnings("unused")
public class Validator {
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 {
//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;
//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();
}
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
EvlModule module = new EvlModule();
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) {
System.err.println("Parse errors occured...");
for (ParseProblem problem : module.getParseProblems()) {
System.err.println(problem.toString());
}
}
// 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());
//filter only within resource
violations = violations.stream()
.filter(v -> ((EObject)v.getInstance()).eResource() == r)
.collect(Collectors.toList());
//TODO: Needed? New API does not provide it
// module.reset();
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;
}
public void dumpViolations(List<UnsatisfiedConstraint> violations, boolean includeLocation) {
for (UnsatisfiedConstraint constraint : violations) {
System.out.println(" Validator: " + constraint.getMessage());
//TODO: this can only work with XtextResources
if (includeLocation && ((EObject) constraint.getInstance()).eResource() instanceof XtextResource) {
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
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("//"))
.collect(Collectors.toList());
snippet = String.join(" ", lines)
.replaceAll("\\s+", " ")
;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return snippet;
//TODO: extract to shared library
public IModel getTDLModel(Resource resource, boolean read, boolean write) throws Exception {
EmfModel model;
//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));