/* * Copyright 2012 PRODYNA AG * * Licensed under the Eclipse Public License (EPL), Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php or * http://www.nabucco.org/License.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.nabucco.framework.generator.compiler.transformation.xml.service; import java.util.ArrayList; import java.util.List; import org.nabucco.framework.generator.compiler.transformation.common.annotation.service.NabuccoTransactionType; import org.nabucco.framework.generator.compiler.transformation.xml.constants.EjbJarConstants; import org.nabucco.framework.generator.compiler.visitor.NabuccoVisitorException; import org.nabucco.framework.generator.parser.syntaxtree.MethodDeclaration; import org.nabucco.framework.generator.parser.visitor.GJVoidDepthFirst; import org.nabucco.framework.mda.template.xml.XmlTemplate; import org.nabucco.framework.mda.template.xml.XmlTemplateException; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * NabuccoToXmlServiceOperationEjbJarVisitor * <p/> * Visitor for service operation transaction attributes. * * @author Nicolas Moser, PRODYNA AG */ class NabuccoToXmlServiceOperationEjbJarVisitor extends GJVoidDepthFirst<List<Element>> implements EjbJarConstants { private static final String TAG_METHOD = "method"; private static final String TAG_METHOD_NAME = "method-name"; private static final String TAG_EJB_NAME = "ejb-name"; private static final String TAG_TRANS_ATTRIBUTE = "trans-attribute"; private String ejbName; private XmlTemplate template; /** * Creates a new {@link NabuccoToXmlServiceOperationEjbJarVisitor} instance. * * @param ejbName * the ejb name * @param template * the xml template */ public NabuccoToXmlServiceOperationEjbJarVisitor(String ejbName, XmlTemplate template) { this.ejbName = ejbName; this.template = template; } @Override public void visit(MethodDeclaration nabuccoMethod, List<Element> containerTransactions) { try { Element containerTransaction = this.createOperationTransactionAttribute(nabuccoMethod); if (containerTransaction != null) { containerTransactions.add(containerTransaction); } } catch (XmlTemplateException te) { throw new NabuccoVisitorException("Error creating transaction attribute for service operation.", te); } } /** * Create the transaction attribute of the service operation. * * @param nabuccoService * the nbc service * * @return the container-transaction xml element * * @throws XmlTemplateException * when the XML template is not correct */ private Element createOperationTransactionAttribute(MethodDeclaration nabuccoMethod) throws XmlTemplateException { NabuccoTransactionType transactionType = NabuccoTransactionType.valueOf(nabuccoMethod); String methodName = nabuccoMethod.nodeToken1.tokenImage; // REQUIRED is defined on service level by default! if (transactionType == NabuccoTransactionType.REQUIRED) { return null; } // Template Element containerTransaction = (Element) this.template.copyNodesByXPath(XPATH_CONTAINER_TRANSACTION).get(0); Element methodElement = this.getElementByTagName(containerTransaction, TAG_METHOD); Element ejbNameElement = this.getElementByTagName(methodElement, TAG_EJB_NAME); ejbNameElement.setTextContent(this.ejbName); Element methodNameElement = this.getElementByTagName(methodElement, TAG_METHOD_NAME); methodNameElement.setTextContent(methodName); Element transAttribute = this.getElementByTagName(containerTransaction, TAG_TRANS_ATTRIBUTE); transAttribute.setTextContent(transactionType.getValue()); return containerTransaction; } /** * Get the first child elements of the given parent node by its name. * * @param parent * the parent node * @param name * name of the child element, or null for all children * * @return the first found child element, or null if none is found */ protected Element getElementByTagName(Node parent, String name) { List<Element> elements = this.getElementsByTagName(parent, name); if (elements.isEmpty()) { return null; } return elements.get(0); } /** * Get all child elements of the given node by their name. * * @param parent * the parent node * @param name * name of the child elements, or null for all children * * @return the child elements */ protected List<Element> getElementsByTagName(Node parent, String name) { List<Element> elements = new ArrayList<Element>(); NodeList childNodes = parent.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node child = childNodes.item(i); if (child instanceof Element) { Element element = (Element) child; if (name == null || element.getNodeName().equals(name)) { elements.add(element); } } } return elements; } }