/**
* Copyright (c) 2015 committers of YAKINDU and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* committers of YAKINDU - initial API and implementation
*/
package org.yakindu.sct.model.stext.expressions;
import java.io.StringReader;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.XtextFactory;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.linking.ILinker;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.parser.IParseResult;
import org.eclipse.xtext.parser.IParser;
import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer;
import org.eclipse.xtext.util.CancelIndicator;
import org.yakindu.sct.domain.extension.DomainRegistry;
import org.yakindu.sct.model.sgraph.SGraphFactory;
import org.yakindu.sct.model.sgraph.SGraphPackage;
import org.yakindu.sct.model.sgraph.Scope;
import org.yakindu.sct.model.sgraph.SpecificationElement;
import org.yakindu.sct.model.sgraph.Statechart;
import org.yakindu.sct.model.sgraph.util.ContextElementAdapter;
import org.yakindu.sct.model.stext.resource.StextResource;
import org.yakindu.sct.model.stext.stext.InterfaceScope;
import org.yakindu.sct.model.stext.stext.InternalScope;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
public class STextExpressionParser implements IExpressionParser {
public static class LinkingException extends RuntimeException{
private static final long serialVersionUID = 1L;
public LinkingException(String msg) {
super(msg);
}
}
public static class SyntaxException extends RuntimeException{
private static final long serialVersionUID = 1L;
public SyntaxException(String msg) {
super(msg);
}
}
@Inject
private IParser parser;
@Inject
private ILinker linker;
@Inject
private Injector injector;
@Inject
@Named(DomainRegistry.DOMAIN_ID)
private String domainId;
public StextResource getResource() {
final StextResource resource = new StextResource();
injector.injectMembers(resource);
resource.eAdapters().add(new ContextElementAdapter(new ContextElementAdapter.IContextElementProvider() {
public EObject getContextObject() {
return (EObject) EcoreUtil.getObjectByType(resource.getContents(), SGraphPackage.Literals.STATECHART);
}
}));
ResourceSet set = new ResourceSetImpl();
set.getResources().add(resource);
return resource;
}
public EObject parseExpression(String expression, String ruleName) {
return parseExpression(expression, ruleName, (String) null);
}
public EObject parseExpression(String expression, String ruleName, String specification) {
StextResource resource = getResource();
resource.setURI(URI.createURI("path", true));
ParserRule parserRule = XtextFactory.eINSTANCE.createParserRule();
parserRule.setName(ruleName);
IParseResult result = parser.parse(parserRule, new StringReader(expression));
EObject rootASTElement = result.getRootASTElement();
resource.getContents().add(rootASTElement);
ListBasedDiagnosticConsumer diagnosticsConsumer = new ListBasedDiagnosticConsumer();
Statechart sc = SGraphFactory.eINSTANCE.createStatechart();
sc.setDomainID(domainId);
sc.setName("sc");
if (specification != null) {
sc.setSpecification(specification);
}
resource.getContents().add(sc);
linker.linkModel(sc, diagnosticsConsumer);
linker.linkModel(rootASTElement, diagnosticsConsumer);
resource.resolveLazyCrossReferences(CancelIndicator.NullImpl);
resource.resolveLazyCrossReferences(CancelIndicator.NullImpl);
Multimap<SpecificationElement, Diagnostic> diagnostics = resource.getLinkingDiagnostics();
if (diagnostics.size() > 0) {
throw new LinkingException(diagnostics.toString());
}
if (result.hasSyntaxErrors()) {
StringBuilder errorMessages = new StringBuilder();
Iterable<INode> syntaxErrors = result.getSyntaxErrors();
for (INode iNode : syntaxErrors) {
errorMessages.append(iNode.getSyntaxErrorMessage());
errorMessages.append("\n");
}
throw new SyntaxException("Could not parse expression, syntax errors: " + errorMessages);
}
if (diagnosticsConsumer.hasConsumedDiagnostics(Severity.ERROR)) {
throw new LinkingException("Error during linking: " + diagnosticsConsumer.getResult(Severity.ERROR));
}
return rootASTElement;
}
public Scope createInternalScope(String contextScope) {
ParserRule parserRule = XtextFactory.eINSTANCE.createParserRule();
parserRule.setName(InternalScope.class.getSimpleName());
IParseResult result = parser.parse(parserRule, new StringReader(contextScope));
return (Scope) result.getRootASTElement();
}
public Scope createInterfaceScope(String contextScope) {
ParserRule parserRule = XtextFactory.eINSTANCE.createParserRule();
parserRule.setName(InterfaceScope.class.getSimpleName());
IParseResult result = parser.parse(parserRule, new StringReader(contextScope));
return (Scope) result.getRootASTElement();
}
}