/******************************************************************************* * Copyright (c) 2011 SAP AG 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: * SAP AG - initial API and implementation ******************************************************************************/ package com.sap.furcas.prettyprinter; import java.util.List; import org.antlr.runtime.ANTLRStringStream; import org.antlr.runtime.Lexer; import org.antlr.runtime.Token; import org.eclipse.emf.ecore.EObject; import com.sap.furcas.metamodel.FURCAS.TCS.SequenceElement; import com.sap.furcas.metamodel.FURCAS.TCS.Template; import com.sap.furcas.metamodel.FURCAS.textblocks.AbstractToken; import com.sap.furcas.metamodel.FURCAS.textblocks.Bostoken; import com.sap.furcas.metamodel.FURCAS.textblocks.DocumentNode; import com.sap.furcas.metamodel.FURCAS.textblocks.Eostoken; import com.sap.furcas.metamodel.FURCAS.textblocks.LexedToken; import com.sap.furcas.metamodel.FURCAS.textblocks.OmittedToken; import com.sap.furcas.metamodel.FURCAS.textblocks.TextBlock; import com.sap.furcas.metamodel.FURCAS.textblocks.TextblocksFactory; import com.sap.furcas.metamodel.FURCAS.textblocks.Version; import com.sap.furcas.runtime.parser.ParserFactory; import com.sap.furcas.runtime.parser.impl.ObservableInjectingParser; import com.sap.ide.cts.parser.incremental.antlr.ANTLRIncrementalLexerAdapter; /** * A factory for instances of {@link DocumentNode}s configured to be used by the {@linkTemplateHandler} * and {@link SequenceHandler}. Basically, it is a simple wrapper around the EMF {@link TextblocksFactory}. * * @author Stephan Erb * */ public class TextBlocksFactory { private static final Version version = Version.REFERENCE; private final TextblocksFactory factory = TextblocksFactory.eINSTANCE; private final Lexer lexer; public TextBlocksFactory(ParserFactory<? extends ObservableInjectingParser, ? extends Lexer> parserFactory) { lexer = parserFactory.createLexer(null); } public TextBlock createTextBlock(EObject modelElement, List<DocumentNode> subnodes, Template template, SequenceElement seqElem, int offset) { TextBlock textBlock = factory.createTextBlock(); textBlock.setVersion(version); textBlock.getCorrespondingModelElements().add(modelElement); textBlock.setType(template); textBlock.setSequenceElement(seqElem); textBlock.getSubNodes().addAll(subnodes); textBlock.setOffsetRelative(true); textBlock.setComplete(true); textBlock.setOffset(offset); textBlock.setLength(getLengthOf(subnodes, /*default length*/ 0)); return textBlock; } public AbstractToken createLexedToken(String value, SequenceElement seqElem, int offset) { LexedToken token = factory.createLexedToken(); configure(token, value, offset); token.setSequenceElement(seqElem); return token; } public OmittedToken createOmittedToken(String value, int offset) { OmittedToken token = factory.createOmittedToken(); configure(token, value, offset); token.setState(Token.HIDDEN_CHANNEL); return token; } public Bostoken createBOSToken() { return ANTLRIncrementalLexerAdapter.createBOSToken(factory, version); } public Eostoken createEOSToken(int offset) { Eostoken token = ANTLRIncrementalLexerAdapter.createEOSToken(factory, version); token.setOffset(offset); return token; } private void configure(AbstractToken token, String value, int offset) { token.setType(getTokenType(value)); token.setValue(value); token.setLength(value.length()); token.setOffset(offset); token.setVersion(version); token.setOffsetRelative(true); } private int getTokenType(String value) { lexer.setCharStream(new ANTLRStringStream(value)); Token lexerToken = lexer.nextToken(); return lexerToken.getType(); } public static int getLengthOf(List<? extends DocumentNode> nodes, int defaultValue) { if (nodes == null || nodes.isEmpty()) { return defaultValue; } else { DocumentNode lastToken = nodes.get(nodes.size()-1); return lastToken.getOffset()+lastToken.getLength(); } } }