/* * 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.datatype; import java.util.ArrayList; import java.util.List; import org.nabucco.framework.generator.compiler.constants.NabuccoXmlTemplateConstants; import org.nabucco.framework.generator.compiler.transformation.util.NabuccoTransformationUtility; import org.nabucco.framework.generator.compiler.transformation.xml.constants.PersistenceConstants; import org.nabucco.framework.generator.compiler.transformation.xml.visitor.NabuccoToXmlVisitorContext; import org.nabucco.framework.generator.compiler.transformation.xml.visitor.NabuccoToXmlVisitorSupport; import org.nabucco.framework.generator.compiler.visitor.NabuccoVisitorException; import org.nabucco.framework.generator.parser.model.NabuccoModel; import org.nabucco.framework.generator.parser.model.multiplicity.NabuccoMultiplicityType; import org.nabucco.framework.generator.parser.model.multiplicity.NabuccoMultiplicityTypeMapper; import org.nabucco.framework.generator.parser.syntaxtree.DatatypeDeclaration; import org.nabucco.framework.generator.parser.syntaxtree.DatatypeStatement; import org.nabucco.framework.mda.model.MdaModel; import org.nabucco.framework.mda.model.xml.XmlModel; 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; /** * NabuccoToXmlDatatypeRefIdVisitor * * @author Nicolas Moser, PRODYNA AG */ class NabuccoToXmlDatatypeRefIdVisitor extends NabuccoToXmlVisitorSupport implements PersistenceConstants { private List<Element> elementList = new ArrayList<Element>(); /** * Creates a new {@link NabuccoToXmlDatatypeRefIdVisitor} instance. * * @param context * the visitor context */ public NabuccoToXmlDatatypeRefIdVisitor(NabuccoToXmlVisitorContext context) { super(createContext(context)); } /** * Prepare the visitor context for the current traversion. * * @param context * the existing context * * @return the new context */ private static NabuccoToXmlVisitorContext createContext(NabuccoToXmlVisitorContext context) { context = new NabuccoToXmlVisitorContext(context); context.setNabuccoExtension(null); return context; } /** * Getter for the elementList. * * @return Returns the elementList. */ public List<Element> getElementList() { return this.elementList; } @Override public void visit(DatatypeStatement nabuccoDatatype, MdaModel<XmlModel> target) { super.visit(nabuccoDatatype, target); this.createParentRefIds(target); } /** * Create the reference IDs for the datatypes parent datatypes. * * @param target * the java target */ private void createParentRefIds(MdaModel<XmlModel> target) { NabuccoModel parent = super.getParent(); if (parent != null) { super.getVisitorContext().setNabuccoExtension(null); parent.getUnit().accept(this, target); } } @Override public void visit(DatatypeDeclaration nabuccoDatatype, MdaModel<XmlModel> target) { // Transient fields must not have a ref ID. if (nabuccoDatatype.nodeOptional.present()) { return; } NabuccoMultiplicityType multiplicity = NabuccoMultiplicityTypeMapper.getInstance().mapToMultiplicity( nabuccoDatatype.nodeToken1.tokenImage); if (multiplicity.isMultiple()) { throw new NabuccoVisitorException( "Cannot extend a datatype of another component which has references on another datatype with multiplicity larger 1."); } String name = nabuccoDatatype.nodeToken2.tokenImage; this.createRefId(name, multiplicity); } /** * Checks whether a type is of another componentName and creates a reference ID. * * @param name * the element name * @param multiplicity * the multiplicity */ private void createRefId(String name, NabuccoMultiplicityType multiplicity) { try { XmlTemplate ormTemplate = this.getVisitorContext().getTemplate(NabuccoXmlTemplateConstants.ORM_TEMPLATE); List<Node> nodes = ormTemplate.copyNodesByXPath(XPATH_BASIC); if (nodes.size() == 1 && nodes.get(0) instanceof Element) { Element basic = (Element) nodes.get(0); basic.setAttribute(NAME, name + REF_ID); NodeList childNodes = basic.getChildNodes(); if (childNodes.getLength() > 1 && childNodes.item(1) instanceof Element) { Element column = (Element) childNodes.item(1); column.setAttribute(NAME, NabuccoTransformationUtility.toTableName(name) + TABLE_SEPARATOR + REF_ID_COLUMN); if (!multiplicity.isOptional()) { column.setAttribute(NULLABLE, Boolean.FALSE.toString()); } } this.elementList.add(basic); } } catch (XmlTemplateException te) { throw new NabuccoVisitorException("Error creating Reference ID for " + name + ".", te); } } }