protected StringBuilder toString(ORecordInternal<?> iRecord, final StringBuilder iOutput, final String iFormat,
final OUserObject2RecordHandler iObjHandler, final Set<Integer> iMarshalledRecords, final boolean iOnlyDelta) {
if (!(iRecord instanceof ODocument))
throw new OSerializationException("Can't marshall a record of type " + iRecord.getClass().getSimpleName() + " to CSV");
final ODocument record = (ODocument) iRecord;
// CHECK IF THE RECORD IS PENDING TO BE MARSHALLED
final Integer identityRecord = System.identityHashCode(record);
if (iMarshalledRecords != null)
if (iMarshalledRecords.contains(identityRecord)) {
return iOutput;
} else
iMarshalledRecords.add(identityRecord);
final ODatabaseRecord database = ODatabaseRecordThreadLocal.INSTANCE.get();
if (!iOnlyDelta && record.getSchemaClass() != null) {
// MARSHALL THE CLASSNAME
iOutput.append(record.getSchemaClass().getStreamableName());
iOutput.append(OStringSerializerHelper.CLASS_SEPARATOR);
}
OProperty prop;
OType type;
OClass linkedClass;
OType linkedType;
String fieldClassName;
int i = 0;
final String[] fieldNames = iOnlyDelta && record.isTrackingChanges() ? record.getDirtyFields() : record.fieldNames();
// MARSHALL ALL THE FIELDS OR DELTA IF TRACKING IS ENABLED
for (String fieldName : fieldNames) {
Object fieldValue = record.rawField(fieldName);
if (i > 0)
iOutput.append(OStringSerializerHelper.RECORD_SEPARATOR);
// SEARCH FOR A CONFIGURED PROPERTY
prop = record.getSchemaClass() != null ? record.getSchemaClass().getProperty(fieldName) : null;
fieldClassName = getClassName(fieldValue);
type = record.fieldType(fieldName);
linkedClass = null;
linkedType = null;
if (prop != null) {
// RECOGNIZED PROPERTY
type = prop.getType();
linkedClass = prop.getLinkedClass();
linkedType = prop.getLinkedType();
} else if (fieldValue != null) {
// NOT FOUND: TRY TO DETERMINE THE TYPE FROM ITS CONTENT
if (type == null) {
if (fieldValue.getClass() == byte[].class)
type = OType.BINARY;
else if (database != null && fieldValue instanceof ORecord<?>) {
if (type == null)
// DETERMINE THE FIELD TYPE
if (fieldValue instanceof ODocument && ((ODocument) fieldValue).hasOwners())
type = OType.EMBEDDED;
else
type = OType.LINK;
linkedClass = getLinkInfo(database, fieldClassName);
} else if (fieldValue instanceof ORID)
// DETERMINE THE FIELD TYPE
type = OType.LINK;
else if (database != null && database.getDatabaseOwner() instanceof ODatabaseObject
&& ((ODatabaseObject) database.getDatabaseOwner()).getEntityManager().getEntityClass(fieldClassName) != null) {
// DETERMINE THE FIELD TYPE
type = OType.LINK;
linkedClass = getLinkInfo(database, fieldClassName);
} else if (fieldValue instanceof Date)
type = OType.DATETIME;
else if (fieldValue instanceof String)
type = OType.STRING;
else if (fieldValue instanceof Integer)
type = OType.INTEGER;
else if (fieldValue instanceof Long)
type = OType.LONG;
else if (fieldValue instanceof Float)
type = OType.FLOAT;
else if (fieldValue instanceof Short)
type = OType.SHORT;
else if (fieldValue instanceof Byte)
type = OType.BYTE;
else if (fieldValue instanceof Double)
type = OType.DOUBLE;
}
if (fieldValue instanceof Collection<?> || fieldValue.getClass().isArray()) {
int size = OMultiValue.getSize(fieldValue);
if (size > 0) {
final Object firstValue = OMultiValue.getFirstValue(fieldValue);
if (firstValue != null) {
if (firstValue instanceof ORID) {
linkedClass = null;
linkedType = OType.LINK;
if (fieldValue instanceof Set<?>)
type = OType.LINKSET;
else
type = OType.LINKLIST;
} else if (database != null
&& (firstValue instanceof ORecordSchemaAware<?> || (database.getDatabaseOwner() instanceof ODatabaseObject && ((ODatabaseObject) database
.getDatabaseOwner()).getEntityManager().getEntityClass(getClassName(firstValue)) != null))) {
linkedClass = getLinkInfo(database, getClassName(firstValue));
if (type == null) {
// LINK: GET THE CLASS
linkedType = OType.LINK;
if (fieldValue instanceof Set<?>)
type = OType.LINKSET;
else
type = OType.LINKLIST;
} else
linkedType = OType.EMBEDDED;
} else {
if (firstValue instanceof Enum<?>)
linkedType = OType.STRING;
else {
linkedType = OType.getTypeByClass(firstValue.getClass());
if (linkedType != OType.LINK) {
// EMBEDDED FOR SURE SINCE IT CONTAINS JAVA TYPES
if (linkedType == null) {
linkedType = OType.EMBEDDED;
// linkedClass = new OClass(firstValue.getClass());
}
}
}
if (type == null)
if (fieldValue instanceof Set<?>)
type = OType.EMBEDDEDSET;
else
type = OType.EMBEDDEDLIST;
}
}
} else if (type == null)
type = OType.EMBEDDEDLIST;
} else if (fieldValue instanceof Map<?, ?>) {
if (type == null)
type = OType.EMBEDDEDMAP;
if (OMultiValue.getSize(fieldValue) > 0) {
Object firstValue = OMultiValue.getFirstValue(fieldValue);
if (firstValue instanceof ORID) {
linkedClass = null;
linkedType = OType.LINK;
type = OType.LINKMAP;
} else if (database != null
&& (firstValue instanceof ORecordSchemaAware<?> || (database.getDatabaseOwner() instanceof ODatabaseObject && ((ODatabaseObject) database
.getDatabaseOwner()).getEntityManager().getEntityClass(getClassName(firstValue)) != null))) {
if (((ORecordInternal<?>) firstValue).getIdentity().isValid())
type = OType.LINKMAP;
// LINK: GET THE CLASS
linkedType = type == OType.EMBEDDEDLIST || type == OType.EMBEDDEDSET || type == OType.EMBEDDEDMAP ? OType.EMBEDDED
: OType.LINK;
linkedClass = getLinkInfo(database, getClassName(firstValue));
} else {
linkedType = OType.getTypeByClass(firstValue.getClass());
if (linkedType == OType.LINK && type == OType.EMBEDDEDMAP)
type = OType.LINKMAP;
}
}
}
}
if (type == OType.TRANSIENT)
// TRANSIENT FIELD
continue;
if (type == null)
type = OType.EMBEDDED;
iOutput.append(fieldName);
iOutput.append(FIELD_VALUE_SEPARATOR);
fieldToStream((ODocument) iRecord, iRecord.getDatabase(), iOutput, iObjHandler, type, linkedClass, linkedType, fieldName,
fieldValue, iMarshalledRecords, true);
i++;
}
if (iMarshalledRecords != null)
iMarshalledRecords.remove(identityRecord);
// GET THE OVERSIZE IF ANY
final float overSize;
if (record.getSchemaClass() != null)
// GET THE CONFIGURED OVERSIZE SETTED PER CLASS
overSize = record.getSchemaClass().getOverSize();
else
overSize = 0;
// APPEND BLANKS IF NEEDED
final int newSize;
if (record.hasOwners())
// EMBEDDED: GET REAL SIZE
newSize = iOutput.length();
else if (record.getSize() == iOutput.length())
// IDENTICAL! DO NOTHING
newSize = record.getSize();
else if (record.getSize() > iOutput.length()) {
// APPEND EXTRA SPACES TO FILL ALL THE AVAILABLE SPACE AND AVOID FRAGMENTATION
newSize = record.getSize();
} else if (overSize > 0) {
// APPEND EXTRA SPACES TO GET A LARGER iOutput
newSize = (int) (iOutput.length() * overSize);
} else
// NO OVERSIZE