use of org.qi4j.api.entity.EntityDescriptor in project qi4j-sdk by Qi4j.
the class JSONMapEntityStoreMixin method readEntityState.
protected JSONEntityState readEntityState(DefaultEntityStoreUnitOfWork unitOfWork, Reader entityState) throws EntityStoreException {
try {
Module module = unitOfWork.module();
JSONObject jsonObject = new JSONObject(new JSONTokener(entityState));
EntityStatus status = EntityStatus.LOADED;
String version = jsonObject.getString(JSONKeys.VERSION);
long modified = jsonObject.getLong(JSONKeys.MODIFIED);
String identity = jsonObject.getString(JSONKeys.IDENTITY);
// Check if NamedAssociation is supported
if (!jsonObject.has(JSONKeys.NAMED_ASSOCIATIONS)) {
jsonObject.put(JSONKeys.NAMED_ASSOCIATIONS, new JSONObject());
}
// Check if version is correct
String currentAppVersion = jsonObject.optString(JSONKeys.APPLICATION_VERSION, "0.0");
if (!currentAppVersion.equals(application.version())) {
if (migration != null) {
migration.migrate(jsonObject, application.version(), this);
} else {
// Do nothing - set version to be correct
jsonObject.put(JSONKeys.APPLICATION_VERSION, application.version());
}
LoggerFactory.getLogger(getClass()).debug("Updated version nr on " + identity + " from " + currentAppVersion + " to " + application.version());
// State changed
status = EntityStatus.UPDATED;
}
String type = jsonObject.getString(JSONKeys.TYPE);
EntityDescriptor entityDescriptor = module.entityDescriptor(type);
if (entityDescriptor == null) {
throw new EntityTypeNotFoundException(type);
}
return new JSONEntityState(unitOfWork, valueSerialization, version, modified, EntityReference.parseEntityReference(identity), status, entityDescriptor, jsonObject);
} catch (JSONException e) {
throw new EntityStoreException(e);
}
}
use of org.qi4j.api.entity.EntityDescriptor in project qi4j-sdk by Qi4j.
the class JSONMapEntityStoreMixin method fetchCachedState.
private EntityState fetchCachedState(EntityReference identity, DefaultEntityStoreUnitOfWork unitOfWork) {
CacheState cacheState = cache.get(identity.identity());
if (cacheState != null) {
JSONObject data = cacheState.json;
try {
String type = data.getString(JSONKeys.TYPE);
EntityDescriptor entityDescriptor = unitOfWork.module().entityDescriptor(type);
return new JSONEntityState(unitOfWork, valueSerialization, identity, entityDescriptor, data);
} catch (JSONException e) {
// Should not be able to happen, unless internal error in the cache system.
throw new EntityStoreException(e);
}
}
return null;
}
use of org.qi4j.api.entity.EntityDescriptor in project qi4j-sdk by Qi4j.
the class MapEntityStoreMixin method writeEntityState.
protected void writeEntityState(DefaultEntityState state, Writer writer, String version, long lastModified) throws EntityStoreException {
try {
JSONWriter json = new JSONWriter(writer);
JSONWriter properties = json.object().key(JSONKeys.IDENTITY).value(state.identity().identity()).key(JSONKeys.APPLICATION_VERSION).value(application.version()).key(JSONKeys.TYPE).value(first(state.entityDescriptor().types()).getName()).key(JSONKeys.VERSION).value(version).key(JSONKeys.MODIFIED).value(lastModified).key(JSONKeys.PROPERTIES).object();
EntityDescriptor entityType = state.entityDescriptor();
for (PropertyDescriptor persistentProperty : entityType.state().properties()) {
Object value = state.properties().get(persistentProperty.qualifiedName());
json.key(persistentProperty.qualifiedName().name());
if (value == null || ValueType.isPrimitiveValue(value)) {
json.value(value);
} else {
String serialized = valueSerialization.serialize(value);
if (serialized.startsWith("{")) {
json.value(new JSONObject(serialized));
} else if (serialized.startsWith("[")) {
json.value(new JSONArray(serialized));
} else {
json.value(serialized);
}
}
}
JSONWriter associations = properties.endObject().key(JSONKeys.ASSOCIATIONS).object();
for (Map.Entry<QualifiedName, EntityReference> stateNameEntityReferenceEntry : state.associations().entrySet()) {
EntityReference value = stateNameEntityReferenceEntry.getValue();
associations.key(stateNameEntityReferenceEntry.getKey().name()).value(value != null ? value.identity() : null);
}
JSONWriter manyAssociations = associations.endObject().key(JSONKeys.MANY_ASSOCIATIONS).object();
for (Map.Entry<QualifiedName, List<EntityReference>> stateNameListEntry : state.manyAssociations().entrySet()) {
JSONWriter assocs = manyAssociations.key(stateNameListEntry.getKey().name()).array();
for (EntityReference entityReference : stateNameListEntry.getValue()) {
assocs.value(entityReference.identity());
}
assocs.endArray();
}
JSONWriter namedAssociations = manyAssociations.endObject().key(JSONKeys.NAMED_ASSOCIATIONS).object();
for (Map.Entry<QualifiedName, Map<String, EntityReference>> stateNameMapEntry : state.namedAssociations().entrySet()) {
JSONWriter assocs = namedAssociations.key(stateNameMapEntry.getKey().name()).object();
for (Map.Entry<String, EntityReference> namedRef : stateNameMapEntry.getValue().entrySet()) {
assocs.key(namedRef.getKey()).value(namedRef.getValue().identity());
}
assocs.endObject();
}
namedAssociations.endObject().endObject();
} catch (JSONException e) {
throw new EntityStoreException("Could not store EntityState", e);
}
}
use of org.qi4j.api.entity.EntityDescriptor in project qi4j-sdk by Qi4j.
the class PreferencesEntityStoreMixin method entityStateOf.
@Override
public EntityState entityStateOf(EntityStoreUnitOfWork unitOfWork, EntityReference identity) {
try {
DefaultEntityStoreUnitOfWork desuw = (DefaultEntityStoreUnitOfWork) unitOfWork;
Module module = desuw.module();
if (!root.nodeExists(identity.identity())) {
throw new NoSuchEntityException(identity, UnknownType.class);
}
Preferences entityPrefs = root.node(identity.identity());
String type = entityPrefs.get("type", null);
EntityStatus status = EntityStatus.LOADED;
EntityDescriptor entityDescriptor = module.entityDescriptor(type);
if (entityDescriptor == null) {
throw new EntityTypeNotFoundException(type);
}
Map<QualifiedName, Object> properties = new HashMap<>();
Preferences propsPrefs = null;
for (PropertyDescriptor persistentPropertyDescriptor : entityDescriptor.state().properties()) {
if (persistentPropertyDescriptor.qualifiedName().name().equals("identity")) {
// Fake identity property
properties.put(persistentPropertyDescriptor.qualifiedName(), identity.identity());
continue;
}
if (propsPrefs == null) {
propsPrefs = entityPrefs.node("properties");
}
ValueType propertyType = persistentPropertyDescriptor.valueType();
Class<?> mainType = propertyType.mainType();
if (Number.class.isAssignableFrom(mainType)) {
if (mainType.equals(Long.class)) {
properties.put(persistentPropertyDescriptor.qualifiedName(), this.getNumber(propsPrefs, persistentPropertyDescriptor, LONG_PARSER));
} else if (mainType.equals(Integer.class)) {
properties.put(persistentPropertyDescriptor.qualifiedName(), this.getNumber(propsPrefs, persistentPropertyDescriptor, INT_PARSER));
} else if (mainType.equals(Double.class)) {
properties.put(persistentPropertyDescriptor.qualifiedName(), this.getNumber(propsPrefs, persistentPropertyDescriptor, DOUBLE_PARSER));
} else if (mainType.equals(Float.class)) {
properties.put(persistentPropertyDescriptor.qualifiedName(), this.getNumber(propsPrefs, persistentPropertyDescriptor, FLOAT_PARSER));
} else {
// Load as string even though it's a number
String json = propsPrefs.get(persistentPropertyDescriptor.qualifiedName().name(), null);
Object value;
if (json == null) {
value = null;
} else {
value = valueSerialization.deserialize(persistentPropertyDescriptor.valueType(), json);
}
properties.put(persistentPropertyDescriptor.qualifiedName(), value);
}
} else if (mainType.equals(Boolean.class)) {
Boolean initialValue = (Boolean) persistentPropertyDescriptor.initialValue(module);
properties.put(persistentPropertyDescriptor.qualifiedName(), propsPrefs.getBoolean(persistentPropertyDescriptor.qualifiedName().name(), initialValue == null ? false : initialValue));
} else if (propertyType instanceof ValueCompositeType || propertyType instanceof MapType || propertyType instanceof CollectionType || propertyType instanceof EnumType) {
String json = propsPrefs.get(persistentPropertyDescriptor.qualifiedName().name(), null);
Object value;
if (json == null) {
value = null;
} else {
value = valueSerialization.deserialize(persistentPropertyDescriptor.valueType(), json);
}
properties.put(persistentPropertyDescriptor.qualifiedName(), value);
} else {
String json = propsPrefs.get(persistentPropertyDescriptor.qualifiedName().name(), null);
if (json == null) {
if (persistentPropertyDescriptor.initialValue(module) != null) {
properties.put(persistentPropertyDescriptor.qualifiedName(), persistentPropertyDescriptor.initialValue(module));
} else {
properties.put(persistentPropertyDescriptor.qualifiedName(), null);
}
} else {
Object value = valueSerialization.deserialize(propertyType, json);
properties.put(persistentPropertyDescriptor.qualifiedName(), value);
}
}
}
// Associations
Map<QualifiedName, EntityReference> associations = new HashMap<>();
Preferences assocs = null;
for (AssociationDescriptor associationType : entityDescriptor.state().associations()) {
if (assocs == null) {
assocs = entityPrefs.node("associations");
}
String associatedEntity = assocs.get(associationType.qualifiedName().name(), null);
EntityReference value = associatedEntity == null ? null : EntityReference.parseEntityReference(associatedEntity);
associations.put(associationType.qualifiedName(), value);
}
// ManyAssociations
Map<QualifiedName, List<EntityReference>> manyAssociations = new HashMap<>();
Preferences manyAssocs = null;
for (AssociationDescriptor manyAssociationType : entityDescriptor.state().manyAssociations()) {
if (manyAssocs == null) {
manyAssocs = entityPrefs.node("manyassociations");
}
List<EntityReference> references = new ArrayList<>();
String entityReferences = manyAssocs.get(manyAssociationType.qualifiedName().name(), null);
if (entityReferences == null) {
// ManyAssociation not found, default to empty one
manyAssociations.put(manyAssociationType.qualifiedName(), references);
} else {
String[] refs = entityReferences.split("\n");
for (String ref : refs) {
EntityReference value = ref == null ? null : EntityReference.parseEntityReference(ref);
references.add(value);
}
manyAssociations.put(manyAssociationType.qualifiedName(), references);
}
}
// NamedAssociations
Map<QualifiedName, Map<String, EntityReference>> namedAssociations = new HashMap<>();
Preferences namedAssocs = null;
for (AssociationDescriptor namedAssociationType : entityDescriptor.state().namedAssociations()) {
if (namedAssocs == null) {
namedAssocs = entityPrefs.node("namedassociations");
}
Map<String, EntityReference> references = new LinkedHashMap<>();
String entityReferences = namedAssocs.get(namedAssociationType.qualifiedName().name(), null);
if (entityReferences == null) {
// NamedAssociation not found, default to empty one
namedAssociations.put(namedAssociationType.qualifiedName(), references);
} else {
String[] namedRefs = entityReferences.split("\n");
if (namedRefs.length % 2 != 0) {
throw new EntityStoreException("Invalid NamedAssociation storage format");
}
for (int idx = 0; idx < namedRefs.length; idx += 2) {
String name = namedRefs[idx];
String ref = namedRefs[idx + 1];
references.put(name, EntityReference.parseEntityReference(ref));
}
namedAssociations.put(namedAssociationType.qualifiedName(), references);
}
}
return new DefaultEntityState(desuw, entityPrefs.get("version", ""), entityPrefs.getLong("modified", unitOfWork.currentTime()), identity, status, entityDescriptor, properties, associations, manyAssociations, namedAssociations);
} catch (ValueSerializationException | BackingStoreException e) {
throw new EntityStoreException(e);
}
}
use of org.qi4j.api.entity.EntityDescriptor in project qi4j-sdk by Qi4j.
the class JCloudsMapEntityStoreMixin method applyChanges.
@Override
public void applyChanges(MapChanges changes) throws IOException {
final BlobStore blobStore = storeContext.getBlobStore();
changes.visitMap(new MapChanger() {
@Override
public Writer newEntity(final EntityReference ref, EntityDescriptor entityDescriptor) throws IOException {
return new StringWriter() {
@Override
public void close() throws IOException {
super.close();
Blob blob = blobStore.blobBuilder(ref.identity()).payload(ByteSource.wrap(toString().getBytes(UTF_8))).build();
blobStore.putBlob(container, blob);
}
};
}
@Override
public Writer updateEntity(final EntityReference ref, EntityDescriptor entityDescriptor) throws IOException {
if (!blobStore.blobExists(container, ref.identity())) {
throw new EntityNotFoundException(ref);
}
return new StringWriter() {
@Override
public void close() throws IOException {
super.close();
Blob blob = blobStore.blobBuilder(ref.identity()).payload(ByteSource.wrap(toString().getBytes(UTF_8))).build();
blobStore.putBlob(container, blob);
}
};
}
@Override
public void removeEntity(EntityReference ref, EntityDescriptor entityDescriptor) throws EntityNotFoundException {
if (!blobStore.blobExists(container, ref.identity())) {
throw new EntityNotFoundException(ref);
}
blobStore.removeBlob(container, ref.identity());
}
});
}
Aggregations