/**
* <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: EAttributePropertyHandler.java,v 1.11 2009/02/24 12:04:50 mtaal Exp $
*/
package org.eclipse.emf.teneo.hibernate.mapping.property;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.teneo.util.AssertUtil;
import org.eclipse.emf.teneo.util.StoreUtil;
import org.hibernate.HibernateException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.property.Getter;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.Setter;
/**
* Is a getter and setter for EMF eattribute which uses eGet and eSet.Handles
* many==false properties.
*
* This class implements both the getter, setter and propertyaccessor
* interfaces. When the getGetter and getSetter methods are called it returns
* itself.
*
* This accessor also handles arrays of primitive types.
*
* @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
* @version $Revision: 1.11 $
*/
@SuppressWarnings("unchecked")
public class EAttributePropertyHandler implements Getter, Setter,
PropertyAccessor {
/**
* Generated Serial Version ID
*/
private static final long serialVersionUID = 8953817672640618007L;
/** The logger */
private static Log log = LogFactory.getLog(EAttributePropertyHandler.class);
/** The field name for which this elist getter operates */
protected final EAttribute eAttribute;
/** The instanceclass */
protected final Class instanceClass;
/** Constructor */
public EAttributePropertyHandler(EAttribute eAttribute) {
this.eAttribute = eAttribute;
instanceClass = eAttribute.getEType().getInstanceClass();
AssertUtil.assertTrue(eAttribute.getName()
+ " is a many feature which is not handled by this accessor ",
!eAttribute.isMany());
log
.debug("Created getter/setter for "
+ StoreUtil.toString(eAttribute));
}
public EAttribute getEAttribute() {
return eAttribute;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
* java.lang.String)
*/
public Getter getGetter(Class theClass, String propertyName)
throws PropertyNotFoundException {
return this;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
* java.lang.String)
*/
public Setter getSetter(Class theClass, String propertyName)
throws PropertyNotFoundException {
return this;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.property.Getter#get(java.lang.Object)
*/
public Object get(Object owner) throws HibernateException {
return ((EObject) owner).eGet(eAttribute);
}
/*
* (non-Javadoc)
*
* @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
* java.util.Map, org.hibernate.engine.SessionImplementor)
*/
public Object getForInsert(Object arg0, Map arg1, SessionImplementor arg2)
throws HibernateException {
return get(arg0);
}
/*
* (non-Javadoc)
*
* @see org.hibernate.property.Getter#getMethod()
*/
public Method getMethod() {
return null;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.property.Getter#getMethodName()
*/
public String getMethodName() {
return null;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.property.Getter#getReturnType()
*/
public Class getReturnType() {
return eAttribute.getEType().getInstanceClass();
}
/*
* (non-Javadoc)
*
* @see org.hibernate.property.Setter#set(java.lang.Object,
* java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
*/
public void set(Object target, Object value,
SessionFactoryImplementor factory) throws HibernateException {
if (value == null) {
// do not overwrite the defaults in the eobject
// TODO is this really a correct approach?
return;
}
final Object curValue = get(target);
if (curValue != null && curValue.equals(value)) {
return; // do not set if not changed
}
if (curValue == value) {
return; // do not set if not changed
}
EObject eobj = (EObject) target;
final Object setValue;
if (value != null && instanceClass != null
&& value.getClass() != instanceClass) {
final Class valClass = value.getClass();
if (valClass == Integer[].class) {
setValue = convert((Integer[]) value);
} else if (valClass == Byte[].class) {
setValue = convert((Byte[]) value);
} else if (valClass == Boolean[].class) {
setValue = convert((Boolean[]) value);
} else if (valClass == Double[].class) {
setValue = convert((Double[]) value);
} else if (valClass == Float[].class) {
setValue = convert((Float[]) value);
} else if (valClass == Long[].class) {
setValue = convert((Long[]) value);
} else if (valClass == Short[].class) {
setValue = convert((Short[]) value);
} else {
setValue = convert(value);
}
} else {
setValue = value;
}
eobj.eSet(eAttribute, setValue);
}
/** Convert to a primitive type */
private Object convert(Integer[] arr) {
if (instanceClass != int[].class) {
if (log.isDebugEnabled()) {
log.debug("Expecting " + instanceClass.getName()
+ " as instance class but it is: "
+ arr.getClass().getName());
}
return arr;
}
final int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i].intValue();
}
return res;
}
/** Convert to a primitive type */
private Object convert(Boolean[] arr) {
if (instanceClass != boolean[].class) {
if (log.isDebugEnabled()) {
log.debug("Expecting " + instanceClass.getName()
+ " as instance class but it is: "
+ arr.getClass().getName());
}
return arr;
}
final boolean[] res = new boolean[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i].booleanValue();
}
return res;
}
/** Convert to a primitive type */
private Object convert(Byte[] arr) {
if (instanceClass != byte[].class) {
if (log.isDebugEnabled()) {
log.debug("Expecting " + instanceClass.getName()
+ " as instance class but it is: "
+ arr.getClass().getName());
}
return arr;
}
final byte[] res = new byte[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i].byteValue();
}
return res;
}
/** Convert to a primitive type */
private Object convert(Double[] arr) {
if (instanceClass != double[].class) {
if (log.isDebugEnabled()) {
log.debug("Expecting " + instanceClass.getName()
+ " as instance class but it is: "
+ arr.getClass().getName());
}
return arr;
}
final double[] res = new double[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i].doubleValue();
}
return res;
}
/** Convert to a primitive type */
private Object convert(Float[] arr) {
if (instanceClass != float[].class) {
if (log.isDebugEnabled()) {
log.debug("Expecting " + instanceClass.getName()
+ " as instance class but it is: "
+ arr.getClass().getName());
}
return arr;
}
final float[] res = new float[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i].floatValue();
}
return res;
}
/** Convert to a primitive type */
private Object convert(Long[] arr) {
if (instanceClass != long[].class) {
if (log.isDebugEnabled()) {
log.debug("Expecting [] as instance class but it is: "
+ instanceClass.getName());
}
return arr;
}
final long[] res = new long[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i].longValue();
}
return res;
}
/** Convert to a primitive type */
private Object convert(Short[] arr) {
if (instanceClass != short[].class) {
if (log.isDebugEnabled()) {
log.debug("Expecting short[] as instance class but it is: "
+ instanceClass.getName());
}
return arr;
}
final short[] res = new short[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i].shortValue();
}
return res;
}
/** Capature all, do not convert */
private Object convert(Object arr) {
if (arr != null
&& instanceClass != null
&& (!instanceClass.isPrimitive() || !arr.getClass()
.isPrimitive())) {
log.debug("Expecting " + instanceClass.getName()
+ " as instance class but it is: "
+ arr.getClass().getName());
}
return arr;
}
}