/** * <copyright> * * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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: * Martin Taal * </copyright> * * $Id: ComplexNode.java,v 1.3 2008/09/01 12:45:19 mtaal Exp $ */ package org.eclipse.emf.teneo.annotations.parser; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EcoreUtil; /** * Models a real type (a complex type in xml schema speak), an EClass. * * @author <a href="mailto:mtaal at elver.org">Martin Taal</a> */ class ComplexNode extends NamedParserNode { /** Log it */ private final static Log log = LogFactory.getLog(ComplexNode.class); /** The child nodes */ private List<NamedParserNode> children = new ArrayList<NamedParserNode>(); /** Is set if this is a list */ private boolean isList = false; /** Returns the list of children */ List<NamedParserNode> getChildren() { return children; } /** Translate into an eclass */ @Override @SuppressWarnings("unchecked") Object convert(EClassResolver ecr) { log.debug("Converting " + getName() + " to EObject "); // special case in which the main type is just a list of other types // for example SecondaryTables which is just a list of SecondaryTable // TODO: repair this hard link to a separate type! final EClass eClass = ecr.getEClass(getName()); if (isList() && eClass == null) { assert (children.size() == 1); assert (children.get(0) instanceof ArrayValueNode); return ((ArrayValueNode) children.get(0)).convert(ecr); } if (eClass == null) { throw new AnnotationParserException("No eclass found with name " + getName()); } final EObject eobj = EcoreUtil.create(eClass); for (NamedParserNode child : children) { final EStructuralFeature efeature = ecr.getEStructuralFeature(eClass, child.getName()); if (child instanceof PrimitiveValueNode) { final PrimitiveValueNode pvn = (PrimitiveValueNode) child; log.debug("Primitive child: " + pvn.getName() + ": " + pvn.getValue()); if (!(efeature instanceof EAttribute)) { throw new AnnotationParserException("The EFeature " + efeature.getName() + "/" + eClass.getName() + " is not an eattribute but a " + efeature.getClass().getName()); } final EClassifier eType = efeature.getEType(); if (!efeature.isMany()) { eobj.eSet(efeature, ParserUtil.convertValue((EDataType) eType, pvn.getValue())); } else { final String[] sources = pvn.getValue().split("\\s+"); log.debug("Child is many, splitting content into " + sources.length + " parts"); final List<Object> referenced = new ArrayList<Object>(sources.length); for (String source : sources) { referenced.add(ParserUtil.convertValue((EDataType) eType, source)); } final List currentList = (List) eobj.eGet(efeature); currentList.addAll(referenced); } } else if (child instanceof ArrayValueNode && efeature instanceof EAttribute) { final EAttribute eattr = (EAttribute) efeature; if (!eattr.isMany()) { throw new AnnotationParserException("The EFeature " + efeature.getName() + "/" + eClass.getName() + " is not ismany"); } log.debug("Array child with primitive values"); List<Object> list = ((ArrayValueNode) child).convert(ecr); List<Object> convertedList = new ArrayList<Object>(); for (Object object : list) { final String val = (String) object; log.debug("Value " + val); convertedList.add(ParserUtil.convertValue((EDataType) eattr.getEType(), val)); } final List currentList = (List) eobj.eGet(efeature); currentList.addAll(convertedList); } else if (child instanceof ArrayValueNode) { if (!(efeature instanceof EReference)) { throw new AnnotationParserException("The EFeature " + efeature.getName() + "/" + eClass.getName() + " is not an ereference but a " + efeature.getClass().getName()); } final EReference eref = (EReference) efeature; if (!eref.isMany()) { throw new AnnotationParserException("The EFeature " + efeature.getName() + "/" + eClass.getName() + " is not ismany"); } log.debug("Array child"); eobj.eSet(eref, ((ArrayValueNode) child).convert(ecr)); } else if (child instanceof ReferenceValueNode) { if (!(efeature instanceof EReference)) { throw new AnnotationParserException("The EFeature " + efeature.getName() + "/" + eClass.getName() + " is not an ereference but a " + efeature.getClass().getName()); } final EReference eref = (EReference) efeature; log.debug("Reference child " + child.getName()); if (eref.isMany()) { ((List) eobj.eGet(eref)).add(((ReferenceValueNode) child).convert(ecr)); } else { eobj.eSet(eref, ((ReferenceValueNode) child).convert(ecr)); } } } return eobj; } /** * @return the isList */ public boolean isList() { return isList; } /** * @param isList * the isList to set */ public void setList(boolean isList) { this.isList = isList; } }