diff options
Diffstat (limited to 'core/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/annotations/mapper/BidirectionalManyToManyAnnotator.java')
-rwxr-xr-x | core/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/annotations/mapper/BidirectionalManyToManyAnnotator.java | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/core/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/annotations/mapper/BidirectionalManyToManyAnnotator.java b/core/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/annotations/mapper/BidirectionalManyToManyAnnotator.java new file mode 100755 index 000000000..a5e321c3c --- /dev/null +++ b/core/org.eclipse.emf.teneo/src/org/eclipse/emf/teneo/annotations/mapper/BidirectionalManyToManyAnnotator.java @@ -0,0 +1,133 @@ +/** + * <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: BidirectionalManyToManyAnnotator.java,v 1.10 2009/03/30 07:53:04 mtaal Exp $ + */ + +package org.eclipse.emf.teneo.annotations.mapper; + +import java.util.List; + +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.JoinTable; +import org.eclipse.emf.teneo.annotations.pannotation.ManyToMany; +import org.eclipse.emf.teneo.extension.ExtensionPoint; + +/** + * Annotates a bidirectional many-to-many ereference. + * + * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> + * @version $Revision: 1.10 $ + */ + +public class BidirectionalManyToManyAnnotator extends BaseEFeatureAnnotator implements ExtensionPoint { + + // The logger + protected static final Log log = LogFactory.getLog(BidirectionalManyToManyAnnotator.class); + + /** Process the features of the eclass */ + public void annotate(PAnnotatedEReference aReference) { + final String featureLogStr = + aReference.getModelEReference().getName() + "/" + + aReference.getModelEReference().getEContainingClass().getName(); + + if (aReference.getOneToMany() != null || aReference.getOneToOne() != null || aReference.getManyToOne() != null) { + throw new StoreMappingException("The feature/eclass " + featureLogStr + " should be a ManyToMany but " + + "it already has a OneToMany, OneToOne or ManyToOne annotation"); + } + + final EReference eReference = (EReference) aReference.getModelElement(); + final EReference eOpposite = eReference.getEOpposite(); + assert (eOpposite != null && eOpposite.isMany()); + + ManyToMany mtm = aReference.getManyToMany(); + final boolean mtmWasSet = mtm != null; // mtm was set manually + if (mtm == null) { + log.debug("Adding manytomany annotations to ereference: " + featureLogStr); + mtm = getFactory().createManyToMany(); + aReference.setManyToMany(mtm); + mtm.setEModelElement(eReference); + } else { + log.debug("ManyToMany present check if default information should be added"); + } + + if (eReference.isContainment() || getPersistenceOptions().isSetDefaultCascadeOnNonContainment()) { + setCascade(mtm.getCascade(), eReference.isContainment()); + } + + if (mtm.getTargetEntity() == null) { + mtm.setTargetEntity(getEntityName(eReference.getEReferenceType())); + } + + if (getPersistenceOptions().isSetForeignKeyNames() && aReference.getForeignKey() == null) { + aReference.setForeignKey(createFK(aReference)); + } + + // determine where to place the jointable annotation and where to place + // the mappedby + // use a certain logic to determine as each is only set on one side + // note that the join is always set on the other side of mapped by! + // note that we can not do setJoinHere = !setMappedByHere because there + // are situations + // that even for mtm no mappedby is set on either side, nl. in case of + // containment + + // also check if the other side has a (manual) manytomany with mappedby + // set + // bugzilla: 164808 + final PAnnotatedEReference otherPA = aReference.getPaModel().getPAnnotated(eOpposite); + if (mtm.getMappedBy() == null && setMappedBy(eReference) && + (otherPA.getManyToMany() == null || otherPA.getManyToMany().getMappedBy() == null)) { + mtm.setMappedBy(eOpposite.getName()); + } + + JoinTable joinTable = aReference.getJoinTable(); + if (joinTable == null) { + joinTable = getFactory().createJoinTable(); + aReference.setJoinTable(joinTable); + } + joinTable.setEModelElement(eReference); + + // set unique and indexed + // disabled because indexed = false now for mtm, + // to overcome this the user has to explicitly set a mtm annotation. + if (!mtmWasSet) { + log.debug("Setting indexed and unique from ereference.isOrdered/isUnique " + + "because mtm was not set manually!"); + mtm.setIndexed(!getPersistenceOptions().alwaysMapListAsBag() && eReference.isOrdered()); + } + + // NOTE that the ejb3 spec states that the jointable should be the + // concatenation of the + // tablenames of the owning entities with an underscore, this will + // quickly lead to nameclashes + // in the case there is more than one relation between two classes. This + // can be pretty likely + // if the inheritance strategy is single_table. + // now possibility to use a different naming strategy + if (joinTable.getName() == null) { + joinTable.setName(getSqlNameStrategy().getJoinTableName(aReference)); + } + if (joinTable.getJoinColumns().size() == 0) { + final List<String> names = getSqlNameStrategy().getJoinTableJoinColumns(aReference, false); + joinTable.getJoinColumns().addAll(getJoinColumns(names, false, true, mtm)); + } + if (joinTable.getInverseJoinColumns().size() == 0) { + final List<String> names = getSqlNameStrategy().getJoinTableJoinColumns(aReference, true); + joinTable.getInverseJoinColumns().addAll(getJoinColumns(names, false, true, mtm)); + } + } +} |