/** * <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: SingleAttributeAnnotator.java,v 1.9 2008/10/12 11:24:35 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.EAttribute; import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.teneo.PersistenceOptions; import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEAttribute; import org.eclipse.emf.teneo.annotations.pannotation.Basic; import org.eclipse.emf.teneo.annotations.pannotation.EnumType; import org.eclipse.emf.teneo.annotations.pannotation.Enumerated; import org.eclipse.emf.teneo.annotations.pannotation.GeneratedValue; import org.eclipse.emf.teneo.annotations.pannotation.GenerationType; import org.eclipse.emf.teneo.annotations.pannotation.Id; import org.eclipse.emf.teneo.annotations.pannotation.TemporalType; import org.eclipse.emf.teneo.extension.ExtensionPoint; /** * Annotates a single attribute, a primitive type such as a long or int. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> * @version $Revision: 1.9 $ */ public class SingleAttributeAnnotator extends BaseEFeatureAnnotator implements ExtensionPoint { // The logger protected static final Log log = LogFactory.getLog(SingleAttributeAnnotator.class); private TemporalType optionDefaultTemporal = null; /** Process the features of the eclass */ public void annotate(PAnnotatedEAttribute aAttribute) { log.debug(" Adding default annotations for EAttribute " + aAttribute.getModelElement().getName()); final EAttribute eAttribute = (EAttribute) aAttribute.getModelElement(); // this is done before adding the id because an enumerated can also be // an id if (eAttribute.getEType() instanceof EEnum && aAttribute.getEnumerated() == null) { final Enumerated enumerated = getFactory().createEnumerated(); enumerated.setValue(EnumType.STRING); enumerated.setEModelElement(eAttribute); aAttribute.setEnumerated(enumerated); } if (getPersistenceOptions().isIDFeatureAsPrimaryKey() && eAttribute.isID() && aAttribute.getId() == null) { // bugzilla 249246 if (aAttribute.getPaEClass().getPaSuperEntity() != null && aAttribute.getPaEClass().getPaSuperEntity().getMappedSuperclass() == null) { log .warn("The eclass " + aAttribute.getPaEClass().getModelEClass().getName() + " has an efeature (" + aAttribute.getModelEAttribute().getName() + ")" + " which has type ID, Teneo will not annotate this efeature with @Id because it is an efeature of a subtype"); } else { final Id id = getFactory().createId(); id.setEModelElement(eAttribute); aAttribute.setId(id); addColumnConstraints(aAttribute); if (getPersistenceOptions().isSetGeneratedValueOnIDFeature() && aAttribute.getGeneratedValue() == null && (Number.class.isAssignableFrom(eAttribute.getEAttributeType().getInstanceClass()) || eAttribute.getEAttributeType().getInstanceClass() == long.class || eAttribute .getEAttributeType().getInstanceClass() == int.class)) { final GeneratedValue gv = getFactory().createGeneratedValue(); gv.setStrategy(GenerationType.AUTO); aAttribute.setGeneratedValue(gv); } return; // after id do not add basic } } else if (aAttribute.getId() != null) { addColumnConstraints(aAttribute); return; // after id do not do basic } if (aAttribute.getTemporal() == null) { setTemporal(aAttribute, optionDefaultTemporal); } if (aAttribute.getBasic() == null) { // primitive defaults are set in the model itself final Basic basic = getFactory().createBasic(); basic.setEModelElement(eAttribute); // NOTE: the ejb3 spec says that for primitivie optional does not // apply, this is // confusing why having this then? If this applies then for each // basic and nullable // field a column annotation has to be added to force nullability // 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 // basic.setOptional(!eAttribute.isRequired() || eAttribute.isUnsettable()); if (aAttribute.getColumn() != null) { basic.setOptional(aAttribute.getColumn().isNullable()); } else { basic.setOptional(!eAttribute.isRequired()); } aAttribute.setBasic(basic); } if (aAttribute.getId() != null) { aAttribute.getBasic().setOptional(false); if (aAttribute.getColumn() != null && aAttribute.getColumn().isNullable()) { log.warn("The column of a primary key property is null, this will often result in database errors!"); } } addColumnConstraints(aAttribute); } /* * (non-Javadoc) * * @see * org.eclipse.emf.teneo.annotations.mapper.AbstractAnnotator#setPersistenceOptions(org.eclipse * .emf.teneo.PersistenceOptions) */ @Override public void setPersistenceOptions(PersistenceOptions persistenceOptions) { super.setPersistenceOptions(persistenceOptions); optionDefaultTemporal = TemporalType.get(persistenceOptions.getDefaultTemporalValue()); if (optionDefaultTemporal == null) { throw new StoreMappingException("Temporal value not found: " + persistenceOptions.getDefaultTemporalValue()); } } }