Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2010-2012 Luca Garulli (l.garulli--at--orientechnologies.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.orientechnologies.orient.object.serialization;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.common.profiler.OProfiler;
import com.orientechnologies.common.reflection.OReflectionHelper;
import com.orientechnologies.orient.core.annotation.OAccess;
import com.orientechnologies.orient.core.annotation.OAfterDeserialization;
import com.orientechnologies.orient.core.annotation.OAfterSerialization;
import com.orientechnologies.orient.core.annotation.OBeforeDeserialization;
import com.orientechnologies.orient.core.annotation.OBeforeSerialization;
import com.orientechnologies.orient.core.annotation.ODocumentInstance;
import com.orientechnologies.orient.core.annotation.OId;
import com.orientechnologies.orient.core.annotation.OVersion;
import com.orientechnologies.orient.core.db.OUserObject2RecordHandler;
import com.orientechnologies.orient.core.db.object.ODatabaseObject;
import com.orientechnologies.orient.core.db.record.ORecordElement;
import com.orientechnologies.orient.core.db.record.OTrackedList;
import com.orientechnologies.orient.core.db.record.OTrackedMap;
import com.orientechnologies.orient.core.db.record.OTrackedMultiValue;
import com.orientechnologies.orient.core.db.record.OTrackedSet;
import com.orientechnologies.orient.core.entity.OEntityManager;
import com.orientechnologies.orient.core.exception.OConfigurationException;
import com.orientechnologies.orient.core.exception.OSchemaException;
import com.orientechnologies.orient.core.exception.OSerializationException;
import com.orientechnologies.orient.core.exception.OTransactionException;
import com.orientechnologies.orient.core.fetch.OFetchContext;
import com.orientechnologies.orient.core.fetch.OFetchHelper;
import com.orientechnologies.orient.core.fetch.OFetchListener;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OProperty;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.serialization.serializer.object.OObjectSerializerHelperManager;
import com.orientechnologies.orient.core.serialization.serializer.record.OSerializationThreadLocal;
import com.orientechnologies.orient.core.tx.OTransactionOptimistic;
import com.orientechnologies.orient.object.db.ODatabasePojoAbstract;
import com.orientechnologies.orient.object.db.OLazyObjectList;
import com.orientechnologies.orient.object.db.OLazyObjectMap;
import com.orientechnologies.orient.object.db.OObjectNotDetachedException;
import com.orientechnologies.orient.object.fetch.OObjectFetchContext;
import com.orientechnologies.orient.object.fetch.OObjectFetchListener;
@SuppressWarnings("unchecked")
/**
* Helper class to manage POJO by using the reflection.
*
* @author Luca Garulli
* @author Luca Molino
* @author Jacques Desodt
*/
public class OObjectSerializerHelper {
public static final Class>[] callbackAnnotationClasses = new Class[] { OBeforeDeserialization.class,
OAfterDeserialization.class, OBeforeSerialization.class, OAfterSerialization.class };
private static final Class>[] NO_ARGS = new Class>[] {};
public static HashMap, OObjectSerializerContext> serializerContexts = new LinkedHashMap, OObjectSerializerContext>();
private static HashMap> classes = new HashMap>();
private static HashMap callbacks = new HashMap();
private static HashMap getters = new HashMap();
private static HashMap setters = new HashMap();
private static HashMap, Field> boundDocumentFields = new HashMap, Field>();
private static HashMap, Field> fieldIds = new HashMap, Field>();
private static HashMap, Field> fieldVersions = new HashMap, Field>();
private static HashMap, List> embeddedFields = new HashMap, List>();
@SuppressWarnings("rawtypes")
public static Class jpaIdClass;
@SuppressWarnings("rawtypes")
public static Class jpaVersionClass;
@SuppressWarnings("rawtypes")
public static Class jpaAccessClass;
@SuppressWarnings("rawtypes")
public static Class jpaEmbeddedClass;
@SuppressWarnings("rawtypes")
public static Class jpaTransientClass;
@SuppressWarnings("rawtypes")
public static Class jpaOneToOneClass;
@SuppressWarnings("rawtypes")
public static Class jpaOneToManyClass;
@SuppressWarnings("rawtypes")
public static Class jpaManyToManyClass;
static {
try {
// DETERMINE IF THERE IS AVAILABLE JPA 1
jpaIdClass = Class.forName("javax.persistence.Id");
jpaVersionClass = Class.forName("javax.persistence.Version");
jpaEmbeddedClass = Class.forName("javax.persistence.Embedded");
jpaTransientClass = Class.forName("javax.persistence.Transient");
jpaOneToOneClass = Class.forName("javax.persistence.OneToOne");
jpaOneToManyClass = Class.forName("javax.persistence.OneToMany");
jpaManyToManyClass = Class.forName("javax.persistence.ManyToMany");
// DETERMINE IF THERE IS AVAILABLE JPA 2
jpaAccessClass = Class.forName("javax.persistence.Access");
} catch (Exception e) {
// IGNORE THE EXCEPTION: JPA NOT FOUND
}
}
public static void register() {
OObjectSerializerHelperManager.getInstance().registerHelper(OObjectSerializerManager.getInstance());
}
public static boolean hasField(final Object iPojo, final String iProperty) {
final Class> c = iPojo.getClass();
final String className = c.getName();
getClassFields(c);
return getters.get(className + "." + iProperty) != null;
}
public static String getDocumentBoundField(final Class> iClass) {
getClassFields(iClass);
final Field f = boundDocumentFields.get(iClass);
return f != null ? f.getName() : null;
}
public static Class> getFieldType(final Object iPojo, final String iProperty) {
final Class> c = iPojo.getClass();
final String className = c.getName();
getClassFields(c);
try {
final Object o = getters.get(className + "." + iProperty);
if (o == null)
return null;
else if (o instanceof Field)
return ((Field) o).getType();
else
return ((Method) o).getReturnType();
} catch (Exception e) {
throw new OSchemaException("Cannot get the value of the property: " + iProperty, e);
}
}
public static Class> getFieldType(ODocument iDocument, final OEntityManager iEntityManager) {
if (iDocument.getInternalStatus() == ORecordElement.STATUS.NOT_LOADED)
iDocument = (ODocument) iDocument.load();
if (iDocument.getClassName() == null) {
return null;
} else {
return iEntityManager.getEntityClass(iDocument.getClassName());
}
}
public static Object getFieldValue(final Object iPojo, final String iProperty) {
final Class> c = iPojo.getClass();
final String className = c.getName();
getClassFields(c);
try {
Object o = getters.get(className + "." + iProperty);
if (o instanceof Method)
return ((Method) o).invoke(iPojo);
else if (o instanceof Field)
return ((Field) o).get(iPojo);
return null;
} catch (Exception e) {
throw new OSchemaException("Cannot get the value of the property: " + iProperty, e);
}
}
public static void setFieldValue(final Object iPojo, final String iProperty, final Object iValue) {
final Class> c = iPojo.getClass();
final String className = c.getName();
getClassFields(c);
try {
Object o = setters.get(className + "." + iProperty);
if (o instanceof Method) {
((Method) o).invoke(iPojo,
OObjectSerializerHelper.convertInObject(iPojo, iProperty, iValue, ((Method) o).getParameterTypes()[0]));
} else if (o instanceof Field) {
((Field) o).set(iPojo, OType.convert(iValue, ((Field) o).getType()));
}
} catch (Exception e) {
throw new OSchemaException(
"Cannot set the value '" + iValue + "' to the property '" + iProperty + "' for the pojo: " + iPojo, e);
}
}
@SuppressWarnings("rawtypes")
public static Object fromStream(final ODocument iRecord, final Object iPojo, final OEntityManager iEntityManager,
final OUserObject2RecordHandler iObj2RecHandler, final String iFetchPlan, final boolean iLazyLoading) {
OFetchHelper.checkFetchPlanValid(iFetchPlan);
final long timer = OProfiler.getInstance().startChrono();
final Class> pojoClass = iPojo.getClass();
final List properties = getClassFields(pojoClass);
String fieldName;
Object fieldValue;
final String idFieldName = setObjectID(iRecord.getIdentity(), iPojo);
final String vFieldName = setObjectVersion(iRecord.getVersion(), iPojo);
// CALL BEFORE UNMARSHALLING
invokeCallback(iPojo, iRecord, OBeforeDeserialization.class);
final String[] fieldNames = new String[properties.size()];
// BIND BASIC FIELDS, LINKS WILL BE BOUND BY THE FETCH API
int f = 0;
for (Field p : properties) {
fieldName = p.getName();
fieldNames[f++] = fieldName;
if (fieldName.equals(idFieldName) || fieldName.equals(vFieldName))
continue;
if (iRecord.containsField(fieldName)) {
// BIND ONLY THE SPECIFIED FIELDS
fieldValue = iRecord.field(fieldName);
Object value = fieldValue;
Type type = null;
if (fieldValue == null
|| !(fieldValue instanceof ODocument)
|| (fieldValue instanceof Collection> && (((Collection>) fieldValue).size() == 0 || !(((Collection>) fieldValue)
.iterator().next() instanceof ODocument)))
|| (!(fieldValue instanceof Map, ?>) || ((Map, ?>) fieldValue).size() == 0 || !(((Map, ?>) fieldValue).values()
.iterator().next() instanceof ODocument))) {
final Class> genericTypeClass = OReflectionHelper.getGenericMultivalueType(p);
if (genericTypeClass != null)
if (genericTypeClass.isEnum()) {
// TRANSFORM THE MULTI-VALUE
if (fieldValue instanceof List) {
// LIST: TRANSFORM EACH SINGLE ITEM
final List