use of com.orientechnologies.orient.core.db.object.ODatabaseObject in project orientdb by orientechnologies.
the class OObjectEntitySerializer method toStream.
/**
* Serialize the user POJO to a ORecordDocument instance.
*
* @param iPojo User pojo to serialize
*
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@SuppressWarnings("unchecked")
protected static <T> T toStream(final T iPojo, final Proxy iProxiedPojo, ODatabaseObject db) throws IllegalArgumentException, IllegalAccessException {
final ODocument iRecord = getDocument(iProxiedPojo);
final long timer = Orient.instance().getProfiler().startChrono();
final Integer identityRecord = System.identityHashCode(iPojo);
if (OObjectSerializationThreadLocal.INSTANCE.get().containsKey(identityRecord))
return (T) OObjectSerializationThreadLocal.INSTANCE.get().get(identityRecord);
OObjectSerializationThreadLocal.INSTANCE.get().put(identityRecord, iProxiedPojo);
OProperty schemaProperty;
final Class<?> pojoClass = iPojo.getClass();
final OClass schemaClass = iRecord.getSchemaClass();
// CHECK FOR ID BINDING
final Field idField = getIdField(pojoClass);
if (idField != null) {
Object id = getFieldValue(idField, iPojo);
if (id != null) {
// FOUND
if (id instanceof ORecordId) {
ORecordInternal.setIdentity(iRecord, (ORecordId) id);
} else if (id instanceof Number) {
// TREATS AS CLUSTER POSITION
((ORecordId) iRecord.getIdentity()).setClusterId(schemaClass.getDefaultClusterId());
((ORecordId) iRecord.getIdentity()).setClusterPosition(((Number) id).longValue());
} else if (id instanceof String)
((ORecordId) iRecord.getIdentity()).fromString((String) id);
else if (id.getClass().equals(Object.class))
ORecordInternal.setIdentity(iRecord, (ORecordId) id);
else
OLogManager.instance().warn(OObjectSerializerHelper.class, "@Id field has been declared as %s while the supported are: ORID, Number, String, Object", id.getClass());
}
if (iRecord.getIdentity().isValid() && iRecord.getIdentity().isPersistent())
iRecord.reload();
}
// CHECK FOR VERSION BINDING
final Field vField = getVersionField(pojoClass);
boolean versionConfigured = false;
if (vField != null) {
versionConfigured = true;
Object ver = getFieldValue(vField, iPojo);
if (ver != null) {
// FOUND
int version = iRecord.getVersion();
if (ver instanceof Number) {
// TREATS AS CLUSTER POSITION
version = ((Number) ver).intValue();
} else if (ver instanceof String)
version = Integer.parseInt((String) ver);
else
OLogManager.instance().warn(OObjectSerializerHelper.class, "@Version field has been declared as %s while the supported are: Number, String", ver.getClass());
ORecordInternal.setVersion(iRecord, version);
}
}
if (db.isMVCC() && !versionConfigured && db.getTransaction() instanceof OTransactionOptimistic)
throw new OTransactionException("Cannot involve an object of class '" + pojoClass + "' in an Optimistic Transaction commit because it does not define @Version or @OVersion and therefore cannot handle MVCC");
String fieldName;
Object fieldValue;
// CALL BEFORE MARSHALLING
invokeCallback(pojoClass, iPojo, iRecord, OBeforeSerialization.class);
Class<?> currentClass = pojoClass;
OObjectEntitySerializedSchema serializedSchema = getCurrentSerializedSchema();
while (!currentClass.equals(Object.class) && serializedSchema.classes.contains(pojoClass)) {
for (Field p : getDeclaredFields(currentClass)) {
if (Modifier.isStatic(p.getModifiers()) || Modifier.isNative(p.getModifiers()) || Modifier.isTransient(p.getModifiers()) || p.getType().isAnonymousClass())
continue;
fieldName = p.getName();
List<String> classTransientFields = serializedSchema.transientFields.get(currentClass);
if ((idField != null && fieldName.equals(idField.getName()) || (vField != null && fieldName.equals(vField.getName())) || (classTransientFields != null && classTransientFields.contains(fieldName))))
continue;
fieldValue = getFieldValue(p, iPojo);
if (fieldValue != null && fieldValue.getClass().isAnonymousClass())
continue;
if (isSerializedType(p))
fieldValue = serializeFieldValue(p.getType(), fieldValue);
schemaProperty = schemaClass != null ? schemaClass.getProperty(fieldName) : null;
OType fieldType = schemaProperty != null ? schemaProperty.getType() : getTypeByClass(currentClass, fieldName);
if (fieldValue != null) {
if (isEmbeddedObject(p)) {
// AUTO CREATE SCHEMA CLASS
if (iRecord.getSchemaClass() == null) {
db.getMetadata().getSchema().createClass(iPojo.getClass());
iRecord.setClassNameIfExists(iPojo.getClass().getSimpleName());
}
}
}
fieldValue = typeToStream(fieldValue, fieldType, db, iRecord);
iRecord.field(fieldName, fieldValue, fieldType);
}
currentClass = currentClass.getSuperclass();
if (currentClass == null || currentClass.equals(ODocument.class))
// POJO EXTENDS ODOCUMENT: SPECIAL CASE: AVOID TO CONSIDER
// ODOCUMENT FIELDS
currentClass = Object.class;
}
// CALL AFTER MARSHALLING
invokeCallback(pojoClass, iPojo, iRecord, OAfterSerialization.class);
OObjectSerializationThreadLocal.INSTANCE.get().remove(identityRecord);
Orient.instance().getProfiler().stopChrono("Object.toStream", "Serialize a POJO", timer);
return (T) iProxiedPojo;
}
use of com.orientechnologies.orient.core.db.object.ODatabaseObject in project orientdb by orientechnologies.
the class OObjectSerializerHelper method multiValueToStream.
private static Object multiValueToStream(final Object iMultiValue, OType iType, final OEntityManager iEntityManager, final OUserObject2RecordHandler iObj2RecHandler, final ODatabaseObject db, final ODocument iRecord, final boolean iSaveOnlyDirty) {
if (iMultiValue == null)
return null;
final Collection<Object> sourceValues;
if (iMultiValue instanceof Collection<?>) {
sourceValues = (Collection<Object>) iMultiValue;
} else {
sourceValues = (Collection<Object>) ((Map<?, ?>) iMultiValue).values();
}
if (iType == null) {
if (sourceValues.size() == 0)
return iMultiValue;
// TRY TO UNDERSTAND THE COLLECTION TYPE BY ITS CONTENT
final Object firstValue = sourceValues.iterator().next();
if (firstValue == null)
return iMultiValue;
// DETERMINE THE RIGHT TYPE BASED ON SOURCE MULTI VALUE OBJECT
if (OType.isSimpleType(firstValue)) {
if (iMultiValue instanceof List)
iType = OType.EMBEDDEDLIST;
else if (iMultiValue instanceof Set)
iType = OType.EMBEDDEDSET;
else
iType = OType.EMBEDDEDMAP;
} else {
if (iMultiValue instanceof List)
iType = OType.LINKLIST;
else if (iMultiValue instanceof Set)
iType = OType.LINKSET;
else
iType = OType.LINKMAP;
}
}
Object result = iMultiValue;
final OType linkedType;
// CREATE THE RETURN MULTI VALUE OBJECT BASED ON DISCOVERED TYPE
if (iType.equals(OType.EMBEDDEDSET) || iType.equals(OType.LINKSET)) {
if (iRecord != null && iType.equals(OType.EMBEDDEDSET))
result = new OTrackedSet<Object>(iRecord);
else
result = new ORecordLazySet(iRecord);
} else if (iType.equals(OType.EMBEDDEDLIST) || iType.equals(OType.LINKLIST)) {
if (iRecord != null && iType.equals(OType.EMBEDDEDLIST))
result = new OTrackedList<Object>(iRecord);
else
result = new ArrayList<Object>();
}
if (iType.equals(OType.LINKLIST) || iType.equals(OType.LINKSET) || iType.equals(OType.LINKMAP))
linkedType = OType.LINK;
else if (iType.equals(OType.EMBEDDEDLIST) || iType.equals(OType.EMBEDDEDSET) || iType.equals(OType.EMBEDDEDMAP))
linkedType = OType.EMBEDDED;
else
throw new IllegalArgumentException("Type " + iType + " must be a multi value type (collection or map)");
if (iMultiValue instanceof Set<?>) {
for (Object o : sourceValues) {
((Collection<Object>) result).add(typeToStream(o, linkedType, iEntityManager, iObj2RecHandler, db, null, iSaveOnlyDirty));
}
} else if (iMultiValue instanceof List<?>) {
for (int i = 0; i < sourceValues.size(); i++) {
((List<Object>) result).add(typeToStream(((List<?>) sourceValues).get(i), linkedType, iEntityManager, iObj2RecHandler, db, null, iSaveOnlyDirty));
}
} else {
if (iMultiValue instanceof OObjectLazyMap<?>) {
result = ((OObjectLazyMap<?>) iMultiValue).getUnderlying();
} else {
if (iRecord != null && iType.equals(OType.EMBEDDEDMAP))
result = new OTrackedMap<Object>(iRecord);
else
result = new HashMap<Object, Object>();
for (Entry<Object, Object> entry : ((Map<Object, Object>) iMultiValue).entrySet()) {
((Map<Object, Object>) result).put(entry.getKey(), typeToStream(entry.getValue(), linkedType, iEntityManager, iObj2RecHandler, db, null, iSaveOnlyDirty));
}
}
}
return result;
}
use of com.orientechnologies.orient.core.db.object.ODatabaseObject in project orientdb by orientechnologies.
the class OObjectDatabaseTx method delete.
@Override
public ODatabaseObject delete(final ORID iRID) {
checkOpeness();
if (iRID == null)
return this;
final ORecord record = iRID.getRecord();
if (record instanceof ODocument) {
Object iPojo = getUserObjectByRecord(record, null);
deleteCascade((ODocument) record);
underlying.delete(record);
if (getTransaction() instanceof OTransactionNoTx)
unregisterPojo(iPojo, (ODocument) record);
}
return this;
}
use of com.orientechnologies.orient.core.db.object.ODatabaseObject in project orientdb by orientechnologies.
the class OObjectProxyMethodHandler method manageCollectionSave.
@SuppressWarnings({ "unchecked", "rawtypes" })
protected Object manageCollectionSave(final Object self, final Field f, Collection<?> value, final boolean customSerialization, final boolean isFieldUpdate) {
final Class genericType = OReflectionHelper.getGenericMultivalueType(f);
if (customSerialization) {
if (value instanceof List<?>) {
final List<Object> list = new ArrayList<Object>();
setDocFieldValue(f.getName(), list, OType.EMBEDDEDLIST);
value = new OObjectCustomSerializerList(OObjectEntitySerializer.getSerializedType(f), doc, new ArrayList<Object>(), (List<Object>) value);
} else {
final Set<Object> set = new HashSet<Object>();
setDocFieldValue(f.getName(), set, OType.EMBEDDEDSET);
value = new OObjectCustomSerializerSet(OObjectEntitySerializer.getSerializedType(f), doc, set, (Set<Object>) value);
}
} else if (genericType != null && genericType.isEnum()) {
if (value instanceof List<?>) {
final List<Object> list = new ArrayList<Object>();
setDocFieldValue(f.getName(), list, OType.EMBEDDEDLIST);
value = new OObjectEnumLazyList(genericType, doc, list, (List<Object>) value);
} else {
final Set<Object> set = new HashSet<Object>();
setDocFieldValue(f.getName(), set, OType.EMBEDDEDSET);
value = new OObjectEnumLazySet(genericType, doc, set, (Set<Object>) value);
}
} else if (!(value instanceof OObjectLazyMultivalueElement)) {
boolean embedded = OObjectEntitySerializer.isEmbeddedField(self.getClass(), f.getName());
if (value instanceof List) {
OType type = embedded ? OType.EMBEDDEDLIST : OType.LINKLIST;
List<OIdentifiable> docList = doc.field(f.getName(), type);
if (docList == null) {
if (embedded)
docList = new OTrackedList<OIdentifiable>(doc);
else
docList = new ORecordLazyList(doc);
setDocFieldValue(f.getName(), docList, type);
} else if (isFieldUpdate) {
docList.clear();
}
value = new OObjectLazyList(self, docList, value, OObjectEntitySerializer.isCascadeDeleteField(self.getClass(), f.getName()));
} else if (value instanceof Set) {
OType type = embedded ? OType.EMBEDDEDSET : OType.LINKSET;
Set<OIdentifiable> docSet = doc.field(f.getName(), type);
if (docSet == null) {
if (embedded)
docSet = new OTrackedSet<OIdentifiable>(doc);
else
docSet = new ORecordLazySet(doc);
setDocFieldValue(f.getName(), docSet, type);
} else if (isFieldUpdate) {
docSet.clear();
}
value = new OObjectLazySet(self, docSet, (Set<?>) value, OObjectEntitySerializer.isCascadeDeleteField(self.getClass(), f.getName()));
}
}
if (!((ODatabaseObject) ODatabaseRecordThreadLocal.INSTANCE.get().getDatabaseOwner()).isLazyLoading())
((OObjectLazyMultivalueElement) value).detach(false);
return value;
}
use of com.orientechnologies.orient.core.db.object.ODatabaseObject in project orientdb by orientechnologies.
the class OObjectEntityEnhancer method initDocument.
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void initDocument(Class<?> iClass, Object iInstance, ODocument iDocument, ODatabaseObject db) throws IllegalArgumentException, IllegalAccessException {
for (Class<?> currentClass = iClass; currentClass != Object.class; ) {
for (Field f : currentClass.getDeclaredFields()) {
if (f.getName().equals("this$0"))
continue;
if (!f.isAccessible()) {
f.setAccessible(true);
}
Object o = f.get(iInstance);
if (o != null) {
if (OObjectEntitySerializer.isSerializedType(f)) {
if (o instanceof List<?>) {
List<?> list = new ArrayList();
iDocument.field(f.getName(), list);
o = new OObjectCustomSerializerList(OObjectEntitySerializer.getSerializedType(f), iDocument, list, (List<?>) o);
f.set(iInstance, o);
} else if (o instanceof Set<?>) {
Set<?> set = new HashSet();
iDocument.field(f.getName(), set);
o = new OObjectCustomSerializerSet(OObjectEntitySerializer.getSerializedType(f), iDocument, set, (Set<?>) o);
f.set(iInstance, o);
} else if (o instanceof Map<?, ?>) {
Map<?, ?> map = new HashMap();
iDocument.field(f.getName(), map);
o = new OObjectCustomSerializerMap(OObjectEntitySerializer.getSerializedType(f), iDocument, map, (Map<?, ?>) o);
f.set(iInstance, o);
} else {
o = OObjectEntitySerializer.serializeFieldValue(o.getClass(), o);
iDocument.field(f.getName(), o);
}
} else {
iDocument.field(f.getName(), OObjectEntitySerializer.typeToStream(o, OType.getTypeByClass(f.getType()), db, iDocument));
}
}
}
currentClass = currentClass.getSuperclass();
}
}
Aggregations