/** * Copyright (C) 2009 STMicroelectronics * * This file is part of "Mind Compiler" is free software: you can redistribute * it and/or modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contact: mind@ow2.org * * Authors: Ali Erdem Ozcan * Contributors: */ package org.ow2.mind.st.templates.parser; import static org.objectweb.fractal.adl.NodeUtil.castNodeError; import org.objectweb.fractal.adl.CompilerError; import org.objectweb.fractal.adl.Node; import org.objectweb.fractal.adl.error.GenericErrors; import org.objectweb.fractal.adl.xml.XMLNodeFactory; import org.ow2.mind.st.templates.ast.BoundInterface; import org.ow2.mind.st.templates.ast.PluginInterface; import org.ow2.mind.st.templates.ast.ServerInterface; import org.ow2.mind.st.templates.ast.SuperTemplate; import org.ow2.mind.st.templates.ast.TemplateComponent; import org.ow2.mind.st.templates.jtb.syntaxtree.FullyQualifiedName; import org.ow2.mind.st.templates.jtb.syntaxtree.ImplementsDefinitions; import org.ow2.mind.st.templates.jtb.syntaxtree.NodeChoice; import org.ow2.mind.st.templates.jtb.syntaxtree.NodeSequence; import org.ow2.mind.st.templates.jtb.syntaxtree.NodeToken; import org.ow2.mind.st.templates.jtb.syntaxtree.RequiresDefinitions; import org.ow2.mind.st.templates.jtb.syntaxtree.SuperTemplateDefinition; import org.ow2.mind.st.templates.jtb.syntaxtree.TemplateComponentDefinition; import org.ow2.mind.st.templates.jtb.visitor.GJDepthFirst; import org.xml.sax.SAXException; /** * Translates the JTB AST of a template component file into a semantic-based * AST. */ public class JTBProcessor extends GJDepthFirst<Node, Node> { private final String filename; private final XMLNodeFactory nodeFactory; private final String adlDtd; /** * @param nodeFactory The node factory to be used for instantiating AST nodes. * @param adlDtd The grammar definition for ADL nodes. * @param filename The name of the parsed file. */ public JTBProcessor(final XMLNodeFactory nodeFactory, final String adlDtd, final String filename) { this.nodeFactory = nodeFactory; this.adlDtd = adlDtd; this.filename = filename; try { nodeFactory.checkDTD(adlDtd); } catch (final SAXException e) { throw new CompilerError(GenericErrors.INTERNAL_ERROR, e, "Error in dtd file '" + adlDtd + "'"); } } public TemplateComponent toTemplateComponent( final TemplateComponentDefinition tcd) { return (TemplateComponent) visit(tcd, null); } private Node newNode(final String name, final NodeToken source) { Node node; try { node = nodeFactory.newXMLNode(adlDtd, name); } catch (final SAXException e) { throw new CompilerError(GenericErrors.INTERNAL_ERROR, e, "Unable to create node"); } setSource(node, source); return node; } private void setSource(final Node node, final NodeToken source) { if (source == null) node.astSetSource(filename); else node.astSetSource(filename + ":" + source.beginLine + "-" + source.beginColumn); } // --------------------------------------------------------------------------- // File level grammar // --------------------------------------------------------------------------- @Override public Node visit(final TemplateComponentDefinition n, final Node argu) { final TemplateComponent template = (TemplateComponent) newNode("template", n.f0); template.setName(fullyQualifiedName(n.f1)); n.f2.accept(this, template); n.f3.accept(this, template); n.f5.accept(this, template); template.setContent(n.f6.tokenImage); return template; } @Override public Node visit(final SuperTemplateDefinition n, final Node argu) { assert argu != null; final TemplateComponent template = castNodeError(argu, TemplateComponent.class); final SuperTemplate superTemplate = (SuperTemplate) newNode( "superTemplate", n.f0); superTemplate.setName(fullyQualifiedName(n.f1)); template.setSuperTemplate(superTemplate); return template; } @Override public Node visit(final ImplementsDefinitions n, final Node argu) { assert argu != null; final TemplateComponent template = castNodeError(argu, TemplateComponent.class); final ServerInterface si = (ServerInterface) newNode("serverInterface", n.f0); si.setSignature(fullyQualifiedName(n.f1)); template.addServerInterface(si); for (final org.ow2.mind.st.templates.jtb.syntaxtree.Node node : n.f2.nodes) { final ServerInterface sitf = (ServerInterface) newNode("serverInterface", n.f0); sitf.setSignature(fullyQualifiedName((FullyQualifiedName) ((NodeSequence) node) .elementAt(1))); template.addServerInterface(sitf); } return template; } @Override public Node visit(final RequiresDefinitions n, final Node argu) { assert argu != null; final TemplateComponent template = castNodeError(argu, TemplateComponent.class); for (final org.ow2.mind.st.templates.jtb.syntaxtree.Node node : n.f0.nodes) { final NodeSequence sequence = (NodeSequence) node; final String signature = fullyQualifiedName((FullyQualifiedName) sequence .elementAt(0)); final String name = ((NodeToken) sequence.elementAt(1)).tokenImage; final NodeChoice itfChoice = (NodeChoice) sequence.elementAt(3); if (itfChoice.which == 0) { // PluginInterface final PluginInterface itf = (PluginInterface) newNode( "pluginInterface", (NodeToken) sequence.elementAt(1)); itf.setSignature(signature); itf.setName(name); final NodeSequence s = (NodeSequence) itfChoice.choice; itf.setRepository(fullyQualifiedName((FullyQualifiedName) s .elementAt(2))); template.addPluginInterface(itf); } else { // BoundInterface final BoundInterface itf = (BoundInterface) newNode("boundInterface", (NodeToken) sequence.elementAt(1)); itf.setSignature(signature); itf.setName(name); itf.setBoundTo(fullyQualifiedName((FullyQualifiedName) itfChoice.choice)); template.addBoundInterface(itf); } } return template; } private String fullyQualifiedName(final FullyQualifiedName n) { String name = n.f0.tokenImage; for (final org.ow2.mind.st.templates.jtb.syntaxtree.Node node : n.f1.nodes) { name += "." + ((NodeToken) ((NodeSequence) node).elementAt(1)).tokenImage; } return name; } }