/**
* GRANITE DATA SERVICES
* Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S.
*
* This file is part of the Granite Data Services Platform.
*
* Granite Data Services is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Granite Data Services is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA, or see <http://www.gnu.org/licenses/>.
*/
package org.granite.eclipselink;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import org.granite.logging.Logger;
import org.granite.messaging.amf.io.util.DefaultClassGetter;
import org.granite.eclipselink.EclipseLinkClassGetter;
import org.granite.eclipselink.EclipseLinkProxy;
import org.granite.util.TypeUtil;
import org.eclipse.persistence.indirection.IndirectContainer;
import org.eclipse.persistence.indirection.ValueHolderInterface;
/**
* @author William DRAI
*/
public class EclipseLinkClassGetter extends DefaultClassGetter {
private final static Logger log = Logger.getLogger(EclipseLinkClassGetter.class);
@Override
public Class<?> getClass(Object o) {
if (o instanceof ValueHolderInterface) {
ValueHolderInterface holder = (ValueHolderInterface)o;
String className = (
holder.isInstantiated() ?
holder.getValue().getClass().getName() :
Object.class.getName()
);
if (className != null && className.length() > 0) {
try {
return TypeUtil.forName(className);
} catch (Exception e) {
log.warn(e, "Could not get class with initializer: %s for: %s", className, className);
}
}
// fallback...
return Object.class;
}
else if (o instanceof EclipseLinkProxy) {
return ((EclipseLinkProxy)o).getProxiedClass();
}
return super.getClass(o);
}
@Override
public boolean isEntity(Object o) {
return o.getClass().isAnnotationPresent(Entity.class);
}
@Override
public boolean isInitialized(Object owner, String propertyName, Object propertyValue) {
Object value = propertyValue;
if (owner != null) {
Field vhf = null;
Class<?> c = owner.getClass();
while (c != null && c != Object.class) {
for (Field f : c.getDeclaredFields()) {
if (f.getName().equals("_persistence_" + propertyName + "_vh")) {
vhf = f;
break;
}
}
if (vhf != null)
break;
c = c.getSuperclass();
}
if (vhf != null) {
try {
vhf.setAccessible(true);
value = vhf.get(owner);
}
catch (Exception e) {
log.error(e, "Could not get persistence ValueHolder " + propertyName + " for class " + owner.getClass());
}
}
}
if (value instanceof ValueHolderInterface)
return ((ValueHolderInterface)value).isInstantiated();
else if (value instanceof IndirectContainer)
return ((IndirectContainer)value).isInstantiated();
return true;
}
@Override
public void initialize(Object owner, String propertyName, Object propertyValue) {
if (propertyValue instanceof ValueHolderInterface)
((ValueHolderInterface)propertyValue).getValue().toString();
else if (propertyValue instanceof IndirectContainer)
((IndirectContainer)propertyValue).getValueHolder().getValue().toString();
}
@Override
public List<Object
[]> getFieldValues(Object obj, Object dest) {
List<Object[]> fieldValues = new ArrayList<Object[]>();
List<String> topLinkVhs = new ArrayList<String>();
// Merges field values
try {
Class<?> clazz = obj.getClass();
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if ((field.getModifiers() & Modifier.STATIC) != 0
|| (field.getModifiers() & Modifier.FINAL) != 0
|| (field.getModifiers() & Modifier.VOLATILE) != 0
|| (field.getModifiers() & Modifier.NATIVE) != 0
|| (field.getModifiers() & Modifier.TRANSIENT) != 0)
continue;
if (ValueHolderInterface.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
ValueHolderInterface vh = (ValueHolderInterface)field.get(obj);
if (!vh.isInstantiated()) {
topLinkVhs.add(field.getName());
field.set(dest, vh);
}
}
else if (!topLinkVhs.contains("_persistence_" + field.getName() + "_vh")) {
field.setAccessible(true);
Object o = field.get(obj);
if (dest != null) {
Object d = field.get(dest);
fieldValues.add(new Object[] { field, o, d });
}
else
fieldValues.add(new Object[] { field, o });
}
}
clazz = clazz.getSuperclass();
}
}
catch (Exception e) {
throw new RuntimeException("Could not merge entity ", e);
}
return fieldValues;
}
}