final List<String> fields = OStringSerializerHelper.smartSplit(iSource, PARAMETER_SEPARATOR, 0, -1, true, true, false, false,
' ', '\n', '\r', '\t');
if (fields.size() % 2 != 0)
throw new OSerializationException("Error on unmarshalling JSON content: wrong format \"" + iSource
+ "\". Use <field> : <value>");
Map<String, Character> fieldTypes = null;
if (fields != null && fields.size() > 0) {
// SEARCH FOR FIELD TYPES IF ANY
for (int i = 0; i < fields.size(); i += 2) {
final String fieldName = OStringSerializerHelper.getStringContent(fields.get(i));
final String fieldValue = fields.get(i + 1);
final String fieldValueAsString = OStringSerializerHelper.getStringContent(fieldValue);
if (fieldName.equals(ATTRIBUTE_FIELD_TYPES) && iRecord instanceof ODocument) {
fieldTypes = loadFieldTypes(fieldTypes, fieldValueAsString);
} else if (fieldName.equals(ODocumentHelper.ATTRIBUTE_TYPE)) {
if (iRecord == null || ORecordInternal.getRecordType(iRecord) != fieldValueAsString.charAt(0)) {
// CREATE THE RIGHT RECORD INSTANCE
iRecord = Orient.instance().getRecordFactoryManager().newInstance((byte) fieldValueAsString.charAt(0));
}
} else if (needReload && fieldName.equals(ODocumentHelper.ATTRIBUTE_RID) && iRecord instanceof ODocument) {
if (fieldValue != null && fieldValue.length() > 0) {
ORecord localRecord = ODatabaseRecordThreadLocal.INSTANCE.get().load(new ORecordId(fieldValueAsString));
if (localRecord != null)
iRecord = localRecord;
}
} else if (fieldName.equals(ODocumentHelper.ATTRIBUTE_CLASS) && iRecord instanceof ODocument) {
((ODocument) iRecord).setClassNameIfExists("null".equals(fieldValueAsString) ? null : fieldValueAsString);
}
}
if (iRecord == null)
iRecord = new ODocument();
try {
int recordVersion = 0;
long timestamp = 0L;
long macAddress = 0L;
for (int i = 0; i < fields.size(); i += 2) {
final String fieldName = OStringSerializerHelper.getStringContent(fields.get(i));
final String fieldValue = fields.get(i + 1);
final String fieldValueAsString = OStringSerializerHelper.getStringContent(fieldValue);
// RECORD ATTRIBUTES
if (fieldName.equals(ODocumentHelper.ATTRIBUTE_RID))
ORecordInternal.setIdentity(iRecord, new ORecordId(fieldValueAsString));
else if (fieldName.equals(ODocumentHelper.ATTRIBUTE_VERSION))
if (OGlobalConfiguration.DB_USE_DISTRIBUTED_VERSION.getValueAsBoolean())
recordVersion = Integer.parseInt(fieldValue);
else
iRecord.getRecordVersion().setCounter(Integer.parseInt(fieldValue));
else if (fieldName.equals(ODocumentHelper.ATTRIBUTE_VERSION_TIMESTAMP)) {
if (OGlobalConfiguration.DB_USE_DISTRIBUTED_VERSION.getValueAsBoolean())
timestamp = Long.parseLong(fieldValue);
} else if (fieldName.equals(ODocumentHelper.ATTRIBUTE_VERSION_MACADDRESS)) {
if (OGlobalConfiguration.DB_USE_DISTRIBUTED_VERSION.getValueAsBoolean())
macAddress = Long.parseLong(fieldValue);
} else if (fieldName.equals(ODocumentHelper.ATTRIBUTE_TYPE)) {
continue;
} else if (fieldName.equals(ATTRIBUTE_FIELD_TYPES) && iRecord instanceof ODocument) {
continue;
} else if (fieldName.equals("value") && !(iRecord instanceof ODocument)) {
// RECORD VALUE(S)
if ("null".equals(fieldValue))
iRecord.fromStream(new byte[] {});
else if (iRecord instanceof ORecordBytes) {
// BYTES
iRecord.fromStream(OBase64Utils.decode(fieldValueAsString));
} else if (iRecord instanceof ORecordStringable) {
((ORecordStringable) iRecord).value(fieldValueAsString);
} else
throw new IllegalArgumentException("unsupported type of record");
} else if (iRecord instanceof ODocument) {
final ODocument doc = ((ODocument) iRecord);
// DETERMINE THE TYPE FROM THE SCHEMA
OType type = determineType(doc, fieldName);
final Object v = getValue(doc, fieldName, fieldValue, fieldValueAsString, type, null, fieldTypes, noMap, iOptions);
if (v != null)
if (v instanceof Collection<?> && !((Collection<?>) v).isEmpty()) {
if (v instanceof ORecordLazyMultiValue)
((ORecordLazyMultiValue) v).setAutoConvertToRecord(false);
// CHECK IF THE COLLECTION IS EMBEDDED
if (type == null) {
// TRY TO UNDERSTAND BY FIRST ITEM
Object first = ((Collection<?>) v).iterator().next();
if (first != null && first instanceof ORecord && !((ORecord) first).getIdentity().isValid())
type = v instanceof Set<?> ? OType.EMBEDDEDSET : OType.EMBEDDEDLIST;
}
if (type != null) {
// TREAT IT AS EMBEDDED
doc.field(fieldName, v, type);
continue;
}
} else if (v instanceof Map<?, ?> && !((Map<?, ?>) v).isEmpty()) {
// CHECK IF THE MAP IS EMBEDDED
Object first = ((Map<?, ?>) v).values().iterator().next();
if (first != null && first instanceof ORecord && !((ORecord) first).getIdentity().isValid()) {
doc.field(fieldName, v, OType.EMBEDDEDMAP);
continue;
}
} else if (v instanceof ODocument && type != null && type.isLink()) {
String className = ((ODocument) v).getClassName();
if (className != null && className.length() > 0)
((ODocument) v).save();
}
if (type == null && fieldTypes != null && fieldTypes.containsKey(fieldName))
type = ORecordSerializerStringAbstract.getType(fieldValue, fieldTypes.get(fieldName));
if (v instanceof OTrackedSet<?>) {
if (OMultiValue.getFirstValue((Set<?>) v) instanceof OIdentifiable)
type = OType.LINKSET;
} else if (v instanceof OTrackedList<?>) {
if (OMultiValue.getFirstValue((List<?>) v) instanceof OIdentifiable)
type = OType.LINKLIST;
}
if (type != null)
doc.field(fieldName, v, type);
else
doc.field(fieldName, v);
}
}
if (timestamp != 0 && OGlobalConfiguration.DB_USE_DISTRIBUTED_VERSION.getValueAsBoolean()) {
((ODistributedVersion) iRecord.getRecordVersion()).update(recordVersion, timestamp, macAddress);
}
} catch (Exception e) {
if (iRecord.getIdentity().isValid())
throw new OSerializationException("Error on unmarshalling JSON content for record " + iRecord.getIdentity(), e);
else
throw new OSerializationException("Error on unmarshalling JSON content for record: " + iSource, e);
}
}
return iRecord;
}