/** * <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: OneToOneReferenceAnnotator.java,v 1.9 2008/09/21 19:03:20 mtaal Exp $ */ package org.eclipse.emf.teneo.annotations.mapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEReference; import org.eclipse.emf.teneo.annotations.pannotation.OneToOne; import org.eclipse.emf.teneo.extension.ExtensionPoint; /** * Annotates an ereference. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> * @version $Revision: 1.9 $ */ public class OneToOneReferenceAnnotator extends BaseEFeatureAnnotator implements ExtensionPoint { // The logger protected static final Log log = LogFactory.getLog(OneToOneReferenceAnnotator.class); /** Annotate it */ public void annotate(PAnnotatedEReference aReference) { final String logStr = aReference.getModelEReference().getName() + "/" + aReference.getModelEReference().getEContainingClass().getName(); if (aReference.getOneToMany() != null || aReference.getManyToMany() != null || aReference.getManyToOne() != null) { throw new StoreMappingException("The feature/eclass " + logStr + " should be a OneToOne but " + "it already has a OneToMany, ManyToMany or ManyToOne annotation"); } final EReference eReference = (EReference) aReference.getModelElement(); OneToOne oto = aReference.getOneToOne(); if (oto == null) { log.debug("EReference + " + logStr + " does not have a onetoone annotation, adding one"); oto = getFactory().createOneToOne(); aReference.setOneToOne(oto); // removed unsettable because it is not used to define optional, it is used // to allow distinction between the default value set or a feature which has not been // set, this is used in validation // oto.setOptional(!eReference.isRequired() || eReference.isUnsettable()); oto.setOptional(!eReference.isRequired()); oto.setEModelElement(eReference); } else { log.debug("EReference + " + logStr + " has an onetoone annotation setting defaults if required"); } if (!oto.isSetFetch()) { oto.setFetch(getFetch(aReference.getAReferenceType())); } // determine where to put the mapped-by if (oto.getMappedBy() == null && setMappedBy(eReference)) { oto.setMappedBy(eReference.getEOpposite().getName()); } if (getPersistenceOptions().isSetForeignKeyNames() && aReference.getForeignKey() == null) { // See bugzilla 211798: handle a specific case when this is a bidirectional // association. In that case the foreign key name has to be // the same on both sides and is set on the many-side. So use the // annotated reference from the other side to ensure that the same foreign key name // is used. if (eReference.getEOpposite() != null && !eReference.getEOpposite().isTransient()) { final PAnnotatedEReference aOpposite = aReference.getPaModel().getPAnnotated(eReference.getEOpposite()); if (aOpposite != null && aOpposite.getTransient() == null) { // don't do anything as otherwise hibernate will create two // fk's with the same name // if (aOpposite.getForeignKey() != null) { // final ForeignKey fk = getFactory().createForeignKey(); // fk.setName(aOpposite.getForeignKey().getName()); // aReference.setForeignKey(fk); // } else { // aReference.setForeignKey(createFK(aOpposite)); // } } else { aReference.setForeignKey(createFK(aReference)); } } else { aReference.setForeignKey(createFK(aReference)); } } setCascade(oto.getCascade(), eReference.isContainment()); if (getPersistenceOptions().isMapEmbeddableAsEmbedded() && aReference.getAReferenceType().getEmbeddable() != null) { aReference.setEmbedded(getFactory().createEmbedded()); } // Note: Sometimes EMF generated getters/setters have a // very generic type (EObject), if the type can be derived here then // this should // be added here if (oto.getTargetEntity() == null) { oto.setTargetEntity(getEntityName(eReference.getEReferenceType())); } } }