Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 412ed227862156421ee47e9ddc55dfe4d4f1cd70 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14













                                                                        
                                                                 



                                               

                           



                                             
                                        
                                       
                                                                      
                                                                     

                                                                         

                                                                 
                                                                        
                                                          

                                                                     


















                                                                                                                   















                                                                




                                                                            





                                                                                                                                              















                                                                                                                              






                                                                                                                   
 












                                                                                                                               
 






















                                                                                                                   


           
                                                                                        
           
                                                                     

                                                                           













                                                                                     


















































                                                                                                                            
 



                                                                                                   


                                                                                               







                                                                                 

         
/**
 * <copyright>
 *
 * Copyright (c) 2005, 2006 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
 *   Davide Marchignoli
 * </copyright>
 *
 * $Id: AbstractMapper.java,v 1.3 2006/11/13 14:53:00 mtaal Exp $
 */

package org.eclipse.emf.teneo.hibernate.mapper;

import java.util.ArrayList;
import java.util.Iterator;
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.EDataType;
import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEAttribute;
import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEDataType;
import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEModelElement;
import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEReference;
import org.eclipse.emf.teneo.annotations.pannotation.Column;
import org.eclipse.emf.teneo.annotations.pannotation.PAnnotation;
import org.eclipse.emf.teneo.annotations.pannotation.PannotationFactory;
import org.eclipse.emf.teneo.hibernate.hbannotation.Cache;
import org.eclipse.emf.teneo.hibernate.hbmodel.HbAnnotatedEAttribute;
import org.eclipse.emf.teneo.hibernate.hbmodel.HbAnnotatedEDataType;
import org.eclipse.emf.teneo.simpledom.Element;
import org.eclipse.emf.teneo.util.EcoreDataTypes;

/**
 * Base class for all mapping classes. Provides access to the hbmcontext.
 * 
 * @author <a href="mailto:marchign at elver.org">Davide Marchignoli</a>
 * @author <a href="mailto:mtaal at elver.org">Martin Taal</a>
 */
abstract class AbstractMapper {

	/** logs it all */
	private static final Log log = LogFactory.getLog(AbstractMapper.class);

	/** return the opposite of an association */
	protected PAnnotatedEReference getOtherSide(PAnnotatedEReference paReference) {
		// TODO assuming that mappedBy coincide with opposite, check in validation
		return paReference.getPaModel().getPAnnotated(paReference.getAnnotatedEReference().getEOpposite());
	}

	/** The mapping context of this mapping action */
	protected final MappingContext hbmContext;

	/** Constructor */
	public AbstractMapper(final MappingContext hbmContext) {
		this.hbmContext = hbmContext;
	}

	/**
	 * @return The mapping context used by this mapper
	 */
	protected MappingContext getHbmContext() {
		return hbmContext;
	}

	/**
	 * @return Returns the hibernate name for the given Ecore data type.
	 * @throws MappingException
	 *             if no corresponding hb type is defined.
	 */
	protected String hbType(PAnnotatedEAttribute paAttribute) {
		final EAttribute eAttribute = paAttribute.getAnnotatedEAttribute();
		final HbAnnotatedEDataType hed = (HbAnnotatedEDataType)paAttribute.getPaModel().getPAnnotated(eAttribute.getEAttributeType());
		final EDataType eDataType = paAttribute.getAnnotatedEAttribute().getEAttributeType();
		if (hed != null && hed.getHbTypeDef() != null) {
			return hed.getHbTypeDef().getName();
		} else if (EcoreDataTypes.INSTANCE.isEWrapper(eDataType) || EcoreDataTypes.INSTANCE.isEPrimitive(eDataType)) {
			return eDataType.getInstanceClassName();
		} else if (EcoreDataTypes.INSTANCE.isEString(eDataType)) {
			return eDataType.getInstanceClassName();
		} else if (EcoreDataTypes.INSTANCE.isEDate(eDataType)) {
			return "java.util.Date";
		} else if (eDataType.getInstanceClass() == Object.class) {
			return "serializable"; // MT: this is sometimes the best/robust approach
		} else if (eDataType.getInstanceClass() != null) {
			return eDataType.getInstanceClassName();
		} else {
			return "serializable"; // MT: this is sometimes the best/robust approach
			// throw new MappingException("Do not know how to handle type " + eDataType);
		}
	}

	/** Sets property attributes on the basis of the column */
	protected void addColumn(Element propertyElement, String defaultName, Column column, boolean forceNullable,
			boolean isId) {
		if (column != null) {
			if (!isId) {
				propertyElement.addAttribute("insert", column.isInsertable() ? "true" : "false");
				propertyElement.addAttribute("update", column.isUpdatable() ? "true" : "false");

				// MT: I think that the column nullability should not be used for setting not-null
				// on the property, this is already specified by the optional attribute on the
				// basic annotation. Maybe a check can be used instead to detect inconsistenties
				// in the column attributes and the basic ann.
				// Note that the ejb3 spec says that optional should be disregarded for primitive types which I
				// do not understand.
				// I disabled it for now to ignore for the test cases.
				// MT05032006: After some more thought the column nullability can be used in case of
				// single table inheritance mapping
				propertyElement.addAttribute("not-null", column.isNullable() ? "false" : "true");
				propertyElement.addAttribute("unique", column.isUnique() ? "true" : "false");
			}
			addColumnElement(propertyElement, defaultName, column, forceNullable);

		} else if (getHbmContext().getEmbeddingFeature() != null) { // embedded
			// TODO: check illegal, embedded component can not really have an id
			final PAnnotatedEReference pae = getHbmContext().getEmbeddingFeature();
			final String name = pae.getAnnotatedEReference().getName() + "_" + defaultName;
			final Column newColumn = PannotationFactory.eINSTANCE.createColumn();
			newColumn.setName(name);
			addColumnElement(propertyElement, defaultName, newColumn, forceNullable);
			//propertyElement.addAttribute("column", getHbmContext().trunc(name));
		} else {
			final Column newColumn = PannotationFactory.eINSTANCE.createColumn();
			newColumn.setName(getHbmContext().trunc(defaultName));
			addColumnElement(propertyElement, defaultName, newColumn, forceNullable);
			//propertyElement.addAttribute("column", getHbmContext().trunc(defaultName));
		}
	}
	
	/** Same as above only handles multiple columns */
	protected void addColumns(Element propertyElement, String defaultName, List columns, boolean forceNullable,
			boolean isId) {
		for (Iterator it = columns.iterator(); it.hasNext();) {
			final Column column = (Column) it.next();
			addColumn(propertyElement, defaultName, column, forceNullable, isId);
		}
	}

	/**
	 * Returns the (possibly overridden) columns annotation for the given attribute.
	 */
	protected List getColumns(PAnnotatedEAttribute paAttribute) {
		final Column defaultColumn = paAttribute.getColumn();
		final Column oc = getHbmContext().getOverride(paAttribute);
		
		if (oc != null) {
			final ArrayList result = new ArrayList();
			result.add(oc);
			return result;
		}
		// try multiple columns 
		final HbAnnotatedEAttribute hae = (HbAnnotatedEAttribute)paAttribute;
		if (hae.getHbColumns().size() > 0) {
			return hae.getHbColumns();
		}
		final ArrayList result = new ArrayList();
		result.add(defaultColumn);
		return result;
	}

	/**
	 * Returns the (possibly overridden) JoinColumns annotations for the given reference or an empty list if no
	 * JoinColumns were defined.
	 */
	protected List getJoinColumns(PAnnotatedEReference paReference) {
		List joinColumns = getHbmContext().getOverride(paReference);
		if (joinColumns == null) {
			return paReference.getJoinColumns();
		}
		return joinColumns;
	}

	/** Generic method to log and throw error situation */
	public void processIllFormed(PAnnotatedEModelElement paElement, String cause, PAnnotation offendingAnnotation) {
		log.error(cause + " on " + paElement);
		throw new MappingException(cause, offendingAnnotation);
	}

	/**
	 * Add a columnelement to the property, takes into account length, precision etc. forceNullable is set when the
	 * feature belongs to a featuremap
	 */
	protected void addColumnElement(Element propertyElement, String defaultName, Column column, boolean forceNullable) {
		if (column != null) {
			Element columnElement = propertyElement.addElement("column").addAttribute("not-null",
					column.isNullable() || forceNullable ? "false" : "true").addAttribute("unique",
					column.isUnique() ? "true" : "false");
			final String name;
			if (column.getName() != null) {
				name = column.getName();
			} else {
				name = defaultName;
			}
			columnElement.addAttribute("name", getHbmContext().trunc(name));
			if (column.isSetLength())
				columnElement.addAttribute("length", Integer.toString(column.getLength()));
			if (column.isSetPrecision())
				columnElement.addAttribute("precision", Integer.toString(column.getPrecision()));
			if (column.isSetScale())
				columnElement.addAttribute("scale", Integer.toString(column.getScale()));
			if (column.getColumnDefinition() != null) {
				columnElement.addAttribute("sql-type", column.getColumnDefinition());
			}
			final String uc = getHbmContext().getUniqueConstraintKey(name);
			if (uc != null) {
				columnElement.addAttribute("unique-key", uc);
			}
		}
	}

	/** Adds a cache element */
	protected void addCacheElement(Element parent, Cache cache) {
		// translate to hibernate specific notation
		final String usage = cache.getUsage().getName().toLowerCase().replaceAll("_", "-");

		// note a trick because the name of the
		Element cacheElement = parent.addElement("cache").addAttribute("usage", usage);
		if (cache.getRegion() != null) {
			cacheElement.addAttribute("region", cache.getRegion());
		}
		if (cache.getInclude() != null) {
			cacheElement.addAttribute("include", cache.getInclude());
		}
		parent.remove(cacheElement);
		parent.add(0, cacheElement);
	}
}

Back to the top