diff --git a/src/main/java/org/caosdb/server/entity/Message.java b/src/main/java/org/caosdb/server/entity/Message.java index 63cf8210becc916447ac9e64cebcf094e179f865..e8c1a63080eca37451eebf8b1a39e5457b8c3732 100644 --- a/src/main/java/org/caosdb/server/entity/Message.java +++ b/src/main/java/org/caosdb/server/entity/Message.java @@ -67,7 +67,7 @@ public class Message extends Exception implements Comparable<Message>, ToElement public String toString() { return this.type.toString() + " (" - + (this.code != null ? this.code.toString() : "") + + (this.code != null ? this.code.toString() : "0") + ") - " + (this.description != null ? this.description : ""); } diff --git a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java new file mode 100644 index 0000000000000000000000000000000000000000..aa6a260dfb52b5e36520d130219632d26095b0d1 --- /dev/null +++ b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java @@ -0,0 +1,441 @@ +package org.caosdb.server.grpc; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.caosdb.api.entity.v1.AtomicDataType; +import org.caosdb.api.entity.v1.CollectionValues; +import org.caosdb.api.entity.v1.DataType; +import org.caosdb.api.entity.v1.Entity; +import org.caosdb.api.entity.v1.Entity.Builder; +import org.caosdb.api.entity.v1.EntityResponse; +import org.caosdb.api.entity.v1.EntityRole; +import org.caosdb.api.entity.v1.Importance; +import org.caosdb.api.entity.v1.ListDataType; +import org.caosdb.api.entity.v1.MessageCode; +import org.caosdb.api.entity.v1.Parent; +import org.caosdb.api.entity.v1.ReferenceDataType; +import org.caosdb.api.entity.v1.ScalarValue; +import org.caosdb.api.entity.v1.SpecialValue; +import org.caosdb.api.entity.v1.Version; +import org.caosdb.datetime.DateTimeInterface; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.datatype.BooleanDatatype; +import org.caosdb.server.datatype.BooleanValue; +import org.caosdb.server.datatype.CollectionValue; +import org.caosdb.server.datatype.DateTimeDatatype; +import org.caosdb.server.datatype.DoubleDatatype; +import org.caosdb.server.datatype.FileDatatype; +import org.caosdb.server.datatype.GenericValue; +import org.caosdb.server.datatype.IndexedSingleValue; +import org.caosdb.server.datatype.IntegerDatatype; +import org.caosdb.server.datatype.ReferenceDatatype; +import org.caosdb.server.datatype.ReferenceDatatype2; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.datatype.TextDatatype; +import org.caosdb.server.datatype.Value; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.MagicTypes; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.entity.container.ParentContainer; +import org.caosdb.server.entity.container.PropertyContainer; +import org.caosdb.server.entity.wrapper.Property; + +public class CaosDBToGrpcConverters { + + /** Get the unit as string. */ + public String getStringUnit(final EntityInterface entity) { + final Iterator<Property> iterator = entity.getProperties().iterator(); + while (iterator.hasNext()) { + final Property p = iterator.next(); + if (MagicTypes.UNIT.getId() == p.getId()) { + iterator.remove(); + return p.getValue().toString(); + } + } + return null; + } + + public EntityResponse.Builder convert(final EntityInterface from) { + + final Builder entityBuilder = Entity.newBuilder(); + + if (from.hasId()) { + entityBuilder.setId(Integer.toString(from.getId())); + } + if (from.getRole() != null) { + entityBuilder.setRole(convert(from.getRole())); + } + if (from.hasName()) { + entityBuilder.setName(from.getName()); + } + if (from.hasDescription()) { + entityBuilder.setDescription(from.getDescription()); + } + if (from.hasDatatype()) { + entityBuilder.setDataType(convert(from.getDatatype())); + } + if (from.hasValue()) { + try { + from.parseValue(); + } catch (final Message e) { + // ignore. This problem should be handled elsewhere because this is + // only for the serialization of the data and not for the validation. + // In any case, the string representation can be used. + } + entityBuilder.setValue(convert(from.getValue())); + } + final String unit = getStringUnit(from); + if (unit != null) { + entityBuilder.setUnit(unit); + } + if (from.hasProperties()) { + entityBuilder.addAllProperties(convert(from.getProperties())); + } + if (from.hasParents()) { + entityBuilder.addAllParents(convert(from.getParents())); + } + + final EntityResponse.Builder responseBuilder = EntityResponse.newBuilder(); + responseBuilder.setEntity(entityBuilder); + + appendMessages(from, responseBuilder); + + return responseBuilder; + } + + private EntityRole convert(final Role role) { + switch (role) { + case RecordType: + return EntityRole.ENTITY_ROLE_RECORD_TYPE; + case Record: + return EntityRole.ENTITY_ROLE_RECORD; + case Property: + return EntityRole.ENTITY_ROLE_PROPERTY; + case File: + return EntityRole.ENTITY_ROLE_FILE; + default: + return EntityRole.ENTITY_ROLE_UNSPECIFIED; + } + } + + public Iterable<? extends org.caosdb.api.entity.v1.Message> convert( + final List<Message> messages) { + final List<org.caosdb.api.entity.v1.Message> result = new LinkedList<>(); + for (final Message m : messages) { + result.add(convert(m)); + } + return result; + } + + public org.caosdb.api.entity.v1.Message convert(final Message m) { + final org.caosdb.api.entity.v1.Message.Builder builder = + org.caosdb.api.entity.v1.Message.newBuilder(); + final MessageCode code = getMessageCode(m); + builder.setCode(code.getNumber()); + builder.setDescription(m.getDescription()); + return builder.build(); + } + + public static MessageCode getMessageCode(final Message m) { + return m.getCode(); + } + + public Version convert(final org.caosdb.server.entity.Version from) { + final org.caosdb.api.entity.v1.Version.Builder builder = Version.newBuilder(); + + builder.setId(from.getId()); + return builder.build(); + } + + public Parent convert(final org.caosdb.server.entity.wrapper.Parent from) { + final org.caosdb.api.entity.v1.Parent.Builder builder = Parent.newBuilder(); + if (from.hasId()) { + builder.setId(from.getId().toString()); + } + if (from.hasName()) { + builder.setName(from.getName()); + } + if (from.hasDescription()) { + builder.setDescription(from.getDescription()); + } + + return builder.build(); + } + + public org.caosdb.api.entity.v1.Property convert(final Property from) { + final org.caosdb.api.entity.v1.Property.Builder builder = + org.caosdb.api.entity.v1.Property.newBuilder(); + + if (from.hasId()) { + builder.setId(from.getId().toString()); + } + if (from.hasName()) { + builder.setName(from.getName()); + } + if (from.hasDescription()) { + builder.setDescription(from.getDescription()); + } + if (from.hasDatatype()) { + builder.setDataType(convert(from.getDatatype())); + } + final String unit = getStringUnit(from); + if (unit != null) { + builder.setUnit(unit); + } + if (from.hasValue()) { + try { + from.parseValue(); + } catch (final Message e) { + // ignore. This problem should be handled elsewhere because this is + // only for the serialization of the data and not for the validation. + // In any case, the string representation can be used. + } + builder.setValue(convert(from.getValue())); + } + builder.setImportance(convert(from.getStatementStatus())); + return builder.build(); + } + + private org.caosdb.api.entity.v1.Value.Builder convert(final Value value) { + if (value instanceof CollectionValue) { + return convertCollectionValue((CollectionValue) value); + } + final org.caosdb.api.entity.v1.Value.Builder builder = + org.caosdb.api.entity.v1.Value.newBuilder(); + builder.setScalarValue(convertScalarValue(value)); + return builder; + } + + private ScalarValue.Builder convertScalarValue(final Value value) { + + if (value instanceof BooleanValue) { + return convertBooleanValue((BooleanValue) value); + + } else if (value instanceof ReferenceValue) { + return convertReferenceValue((ReferenceValue) value); + + } else if (value instanceof DateTimeInterface) { + return convertDateTimeInterface((DateTimeInterface) value); + + } else if (value instanceof GenericValue) { + return convertGenericValue((GenericValue) value); + } + return null; + } + + private ScalarValue.Builder convertGenericValue(final GenericValue value) { + final Object wrappedValue = value.getValue(); + if (wrappedValue instanceof Double) { + return ScalarValue.newBuilder().setDoubleValue((Double) wrappedValue); + } else if (wrappedValue instanceof Integer) { + return ScalarValue.newBuilder().setIntegerValue((Integer) wrappedValue); + } else { + return convertStringValue(value); + } + } + + private org.caosdb.api.entity.v1.ScalarValue.Builder convertStringValue(final Value value) { + if (value.toString().isEmpty()) { + return ScalarValue.newBuilder().setSpecialValue(SpecialValue.SPECIAL_VALUE_EMPTY_STRING); + } + return ScalarValue.newBuilder().setStringValue(value.toString()); + } + + private org.caosdb.api.entity.v1.ScalarValue.Builder convertDateTimeInterface( + final DateTimeInterface value) { + return convertStringValue(value); + } + + private org.caosdb.api.entity.v1.ScalarValue.Builder convertBooleanValue( + final BooleanValue value) { + return ScalarValue.newBuilder().setBooleanValue(value.getValue()); + } + + private ScalarValue.Builder convertReferenceValue(final ReferenceValue value) { + return convertStringValue(value); + } + + private org.caosdb.api.entity.v1.Value.Builder convertCollectionValue( + final CollectionValue value) { + + final org.caosdb.api.entity.v1.Value.Builder builder = + org.caosdb.api.entity.v1.Value.newBuilder(); + final List<ScalarValue> values = new LinkedList<>(); + value.forEach( + (v) -> { + values.add(convertScalarValue(v)); + }); + builder.setListValues(CollectionValues.newBuilder().addAllValues(values)); + return builder; + } + + private ScalarValue convertScalarValue(final IndexedSingleValue v) { + return convertScalarValue(v.getWrapped()).build(); + } + + private Importance convert(final StatementStatus statementStatus) { + switch (statementStatus) { + case FIX: + return Importance.IMPORTANCE_FIX; + case OBLIGATORY: + return Importance.IMPORTANCE_OBLIGATORY; + case RECOMMENDED: + return Importance.IMPORTANCE_RECOMMENDED; + case SUGGESTED: + return Importance.IMPORTANCE_SUGGESTED; + default: + return null; + } + } + + private org.caosdb.api.entity.v1.DataType.Builder convert(final AbstractDatatype datatype) { + if (datatype instanceof ReferenceDatatype2) { + return DataType.newBuilder() + .setReferenceDataType(convertReferenceDatatype((ReferenceDatatype2) datatype)); + } else if (datatype instanceof FileDatatype) { + return DataType.newBuilder() + .setReferenceDataType(convertReferenceDatatype((FileDatatype) datatype)); + } else if (datatype instanceof ReferenceDatatype) { + return DataType.newBuilder() + .setReferenceDataType(convertReferenceDatatype((ReferenceDatatype) datatype)); + } else if (datatype instanceof AbstractCollectionDatatype) { + return DataType.newBuilder() + .setListDataType( + convertAbstractCollectionDatatype((AbstractCollectionDatatype) datatype)); + } else if (datatype instanceof BooleanDatatype) { + return DataType.newBuilder() + .setAtomicDataType(convertBooleanDatatype((BooleanDatatype) datatype)); + + } else if (datatype instanceof DateTimeDatatype) { + return DataType.newBuilder() + .setAtomicDataType(convertDateTimeDatatype((DateTimeDatatype) datatype)); + + } else if (datatype instanceof DoubleDatatype) { + return DataType.newBuilder() + .setAtomicDataType(convertDoubleDatatype((DoubleDatatype) datatype)); + + } else if (datatype instanceof IntegerDatatype) { + return DataType.newBuilder() + .setAtomicDataType(convertIntegerDatatype((IntegerDatatype) datatype)); + + } else if (datatype instanceof TextDatatype) { + return DataType.newBuilder().setAtomicDataType(convertTextDatatype((TextDatatype) datatype)); + } + return null; + } + + private AtomicDataType convertTextDatatype(final TextDatatype datatype) { + return AtomicDataType.ATOMIC_DATA_TYPE_TEXT; + } + + private AtomicDataType convertIntegerDatatype(final IntegerDatatype datatype) { + return AtomicDataType.ATOMIC_DATA_TYPE_INTEGER; + } + + private AtomicDataType convertDoubleDatatype(final DoubleDatatype datatype) { + return AtomicDataType.ATOMIC_DATA_TYPE_DOUBLE; + } + + private AtomicDataType convertDateTimeDatatype(final DateTimeDatatype datatype) { + return AtomicDataType.ATOMIC_DATA_TYPE_DATETIME; + } + + private AtomicDataType convertBooleanDatatype(final BooleanDatatype datatype) { + return AtomicDataType.ATOMIC_DATA_TYPE_BOOLEAN; + } + + private org.caosdb.api.entity.v1.ListDataType.Builder convertAbstractCollectionDatatype( + final AbstractCollectionDatatype collectionDatatype) { + + final org.caosdb.api.entity.v1.ListDataType.Builder listBuilder = ListDataType.newBuilder(); + final AbstractDatatype datatype = collectionDatatype.getDatatype(); + if (datatype instanceof ReferenceDatatype) { + listBuilder.setReferenceDataType(convertReferenceDatatype((ReferenceDatatype) datatype)); + } else if (datatype instanceof BooleanDatatype) { + return listBuilder.setAtomicDataType(convertBooleanDatatype((BooleanDatatype) datatype)); + + } else if (datatype instanceof DateTimeDatatype) { + return listBuilder.setAtomicDataType(convertDateTimeDatatype((DateTimeDatatype) datatype)); + + } else if (datatype instanceof DoubleDatatype) { + return listBuilder.setAtomicDataType(convertDoubleDatatype((DoubleDatatype) datatype)); + + } else if (datatype instanceof IntegerDatatype) { + return listBuilder.setAtomicDataType(convertIntegerDatatype((IntegerDatatype) datatype)); + + } else if (datatype instanceof TextDatatype) { + return listBuilder.setAtomicDataType(convertTextDatatype((TextDatatype) datatype)); + } + return listBuilder; + } + + private org.caosdb.api.entity.v1.ReferenceDataType.Builder convertReferenceDatatype( + final ReferenceDatatype datatype) { + return ReferenceDataType.newBuilder().setName(datatype.getName()); + } + + public Iterable<? extends org.caosdb.api.entity.v1.Property> convert( + final PropertyContainer from) { + final Iterator<org.caosdb.server.entity.wrapper.Property> iterator = from.iterator(); + return () -> + new Iterator<>() { + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public org.caosdb.api.entity.v1.Property next() { + return convert(iterator.next()); + } + }; + } + + public Iterable<? extends Parent> convert(final ParentContainer from) { + final Iterator<org.caosdb.server.entity.wrapper.Parent> iterator = from.iterator(); + return () -> + new Iterator<>() { + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public Parent next() { + return convert(iterator.next()); + } + }; + } + + public void appendMessages( + final EntityInterface from, final org.caosdb.api.entity.v1.EntityResponse.Builder builder) { + if (from.hasMessage(Message.MessageType.Error.toString())) { + builder.addAllErrors(convert(from.getMessages(Message.MessageType.Error.toString()))); + } + if (from.hasMessage(Message.MessageType.Warning.toString())) { + builder.addAllWarnings(convert(from.getMessages(Message.MessageType.Warning.toString()))); + } + if (from.hasMessage(Message.MessageType.Info.toString())) { + builder.addAllInfos(convert(from.getMessages(Message.MessageType.Info.toString()))); + } + } + + public void appendMessages( + final EntityInterface from, final org.caosdb.api.entity.v1.IdResponse.Builder builder) { + if (from.hasMessage(Message.MessageType.Error.toString())) { + builder.addAllErrors(convert(from.getMessages(Message.MessageType.Error.toString()))); + } + if (from.hasMessage(Message.MessageType.Warning.toString())) { + builder.addAllWarnings(convert(from.getMessages(Message.MessageType.Warning.toString()))); + } + if (from.hasMessage(Message.MessageType.Info.toString())) { + builder.addAllInfos(convert(from.getMessages(Message.MessageType.Info.toString()))); + } + } +} diff --git a/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java b/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java index eeba659aa5ab0bd2b7271a8bd1fa9987268197fc..4608bd49034d4957a4a19dcf6e03913d99201274 100644 --- a/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java +++ b/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java @@ -1,460 +1,48 @@ package org.caosdb.server.grpc; import io.grpc.stub.StreamObserver; -import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; import java.util.UUID; import org.apache.shiro.SecurityUtils; -import org.caosdb.api.entity.v1.AtomicDataType; -import org.caosdb.api.entity.v1.CollectionValues; -import org.caosdb.api.entity.v1.DataType; import org.caosdb.api.entity.v1.DeleteRequest; import org.caosdb.api.entity.v1.DeleteResponse; import org.caosdb.api.entity.v1.Entity; -import org.caosdb.api.entity.v1.Entity.Builder; import org.caosdb.api.entity.v1.EntityRequest; import org.caosdb.api.entity.v1.EntityResponse; -import org.caosdb.api.entity.v1.EntityRole; import org.caosdb.api.entity.v1.EntityTransactionServiceGrpc.EntityTransactionServiceImplBase; -import org.caosdb.api.entity.v1.FileDescriptor; import org.caosdb.api.entity.v1.IdResponse; -import org.caosdb.api.entity.v1.Importance; import org.caosdb.api.entity.v1.InsertRequest; import org.caosdb.api.entity.v1.InsertResponse; -import org.caosdb.api.entity.v1.ListDataType; -import org.caosdb.api.entity.v1.MessageCode; import org.caosdb.api.entity.v1.MultiTransactionRequest; import org.caosdb.api.entity.v1.MultiTransactionResponse; -import org.caosdb.api.entity.v1.Parent; -import org.caosdb.api.entity.v1.ReferenceDataType; import org.caosdb.api.entity.v1.RetrieveResponse; -import org.caosdb.api.entity.v1.ScalarValue; -import org.caosdb.api.entity.v1.SpecialValue; import org.caosdb.api.entity.v1.TransactionRequest; import org.caosdb.api.entity.v1.TransactionRequest.WrappedRequestsCase; import org.caosdb.api.entity.v1.TransactionResponse; import org.caosdb.api.entity.v1.UpdateRequest; import org.caosdb.api.entity.v1.UpdateResponse; -import org.caosdb.api.entity.v1.Version; -import org.caosdb.datetime.DateTimeInterface; import org.caosdb.server.CaosDBException; -import org.caosdb.server.datatype.AbstractCollectionDatatype; -import org.caosdb.server.datatype.AbstractDatatype; -import org.caosdb.server.datatype.BooleanDatatype; -import org.caosdb.server.datatype.BooleanValue; -import org.caosdb.server.datatype.CollectionValue; -import org.caosdb.server.datatype.DateTimeDatatype; -import org.caosdb.server.datatype.DoubleDatatype; -import org.caosdb.server.datatype.FileDatatype; -import org.caosdb.server.datatype.GenericValue; -import org.caosdb.server.datatype.IndexedSingleValue; -import org.caosdb.server.datatype.IntegerDatatype; -import org.caosdb.server.datatype.ListDatatype; -import org.caosdb.server.datatype.ReferenceDatatype; -import org.caosdb.server.datatype.ReferenceDatatype2; -import org.caosdb.server.datatype.ReferenceValue; -import org.caosdb.server.datatype.TextDatatype; -import org.caosdb.server.datatype.Value; import org.caosdb.server.entity.DeleteEntity; import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.FileProperties; import org.caosdb.server.entity.InsertEntity; -import org.caosdb.server.entity.MagicTypes; -import org.caosdb.server.entity.Message; import org.caosdb.server.entity.RetrieveEntity; -import org.caosdb.server.entity.Role; -import org.caosdb.server.entity.StatementStatus; import org.caosdb.server.entity.UpdateEntity; -import org.caosdb.server.entity.container.ParentContainer; -import org.caosdb.server.entity.container.PropertyContainer; import org.caosdb.server.entity.container.RetrieveContainer; import org.caosdb.server.entity.container.WritableContainer; -import org.caosdb.server.entity.wrapper.Property; import org.caosdb.server.transaction.Retrieve; import org.caosdb.server.transaction.WriteTransaction; -import org.caosdb.server.utils.EntityStatus; import org.caosdb.server.utils.ServerMessages; public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBase { - public EntityTransactionServiceImpl(final FileTransmissionServiceImpl fileTransmissionService) { - this.fileTransmissionService = fileTransmissionService; - } - + /// MOVE END + private final CaosDBToGrpcConverters caosdbToGrpc = new CaosDBToGrpcConverters(); + private final GrpcToCaosDBConverters grpcToCaosdb = new GrpcToCaosDBConverters(); private final FileTransmissionServiceImpl fileTransmissionService; - /** Get the unit as string. */ - public String getStringUnit(final EntityInterface entity) { - final Iterator<Property> iterator = entity.getProperties().iterator(); - while (iterator.hasNext()) { - final Property p = iterator.next(); - if (MagicTypes.UNIT.getId() == p.getId()) { - iterator.remove(); - return p.getValue().toString(); - } - } - return null; - } - - public EntityResponse.Builder convert(final EntityInterface from) { - - final Builder entityBuilder = Entity.newBuilder(); - - if (from.hasId()) { - entityBuilder.setId(Integer.toString(from.getId())); - } - if (from.getRole() != null) { - entityBuilder.setRole(convert(from.getRole())); - } - if (from.hasName()) { - entityBuilder.setName(from.getName()); - } - if (from.hasDescription()) { - entityBuilder.setDescription(from.getDescription()); - } - if (from.hasDatatype()) { - entityBuilder.setDataType(convert(from.getDatatype())); - } - if (from.hasValue()) { - try { - from.parseValue(); - } catch (final Message e) { - // ignore. This problem should be handled elsewhere because this is - // only for the serialization of the data and not for the validation. - // In any case, the string representation can be used. - } - entityBuilder.setValue(convert(from.getValue())); - } - final String unit = getStringUnit(from); - if (unit != null) { - entityBuilder.setUnit(unit); - } - if (from.hasProperties()) { - entityBuilder.addAllProperties(convert(from.getProperties())); - } - if (from.hasParents()) { - entityBuilder.addAllParents(convert(from.getParents())); - } - - final EntityResponse.Builder responseBuilder = EntityResponse.newBuilder(); - responseBuilder.setEntity(entityBuilder); - - appendMessages(from, responseBuilder); - - return responseBuilder; - } - - private EntityRole convert(final Role role) { - switch (role) { - case RecordType: - return EntityRole.ENTITY_ROLE_RECORD_TYPE; - case Record: - return EntityRole.ENTITY_ROLE_RECORD; - case Property: - return EntityRole.ENTITY_ROLE_PROPERTY; - case File: - return EntityRole.ENTITY_ROLE_FILE; - default: - return EntityRole.ENTITY_ROLE_UNSPECIFIED; - } - } - - public static Iterable<? extends org.caosdb.api.entity.v1.Message> convert( - final List<Message> messages) { - final List<org.caosdb.api.entity.v1.Message> result = new LinkedList<>(); - for (final Message m : messages) { - result.add(convert(m)); - } - return result; - } - - public static org.caosdb.api.entity.v1.Message convert(final Message m) { - final org.caosdb.api.entity.v1.Message.Builder builder = - org.caosdb.api.entity.v1.Message.newBuilder(); - final MessageCode code = getMessageCode(m); - builder.setCode(code.getNumber()); - builder.setDescription(m.getDescription()); - return builder.build(); - } - - public static MessageCode getMessageCode(final Message m) { - return m.getCode(); - } - - public Version convert(final org.caosdb.server.entity.Version from) { - final org.caosdb.api.entity.v1.Version.Builder builder = Version.newBuilder(); - - builder.setId(from.getId()); - return builder.build(); - } - - public Parent convert(final org.caosdb.server.entity.wrapper.Parent from) { - final org.caosdb.api.entity.v1.Parent.Builder builder = Parent.newBuilder(); - if (from.hasId()) { - builder.setId(from.getId().toString()); - } - if (from.hasName()) { - builder.setName(from.getName()); - } - if (from.hasDescription()) { - builder.setDescription(from.getDescription()); - } - - return builder.build(); - } - - public org.caosdb.api.entity.v1.Property convert(final Property from) { - final org.caosdb.api.entity.v1.Property.Builder builder = - org.caosdb.api.entity.v1.Property.newBuilder(); - - if (from.hasId()) { - builder.setId(from.getId().toString()); - } - if (from.hasName()) { - builder.setName(from.getName()); - } - if (from.hasDescription()) { - builder.setDescription(from.getDescription()); - } - if (from.hasDatatype()) { - builder.setDataType(convert(from.getDatatype())); - } - final String unit = getStringUnit(from); - if (unit != null) { - builder.setUnit(unit); - } - if (from.hasValue()) { - try { - from.parseValue(); - } catch (final Message e) { - // ignore. This problem should be handled elsewhere because this is - // only for the serialization of the data and not for the validation. - // In any case, the string representation can be used. - } - builder.setValue(convert(from.getValue())); - } - builder.setImportance(convert(from.getStatementStatus())); - return builder.build(); - } - - private org.caosdb.api.entity.v1.Value.Builder convert(final Value value) { - if (value instanceof CollectionValue) { - return convertCollectionValue((CollectionValue) value); - } - final org.caosdb.api.entity.v1.Value.Builder builder = - org.caosdb.api.entity.v1.Value.newBuilder(); - builder.setScalarValue(convertScalarValue(value)); - return builder; - } - - private ScalarValue.Builder convertScalarValue(final Value value) { - - if (value instanceof BooleanValue) { - return convertBooleanValue((BooleanValue) value); - - } else if (value instanceof ReferenceValue) { - return convertReferenceValue((ReferenceValue) value); - - } else if (value instanceof DateTimeInterface) { - return convertDateTimeInterface((DateTimeInterface) value); - - } else if (value instanceof GenericValue) { - return convertGenericValue((GenericValue) value); - } - return null; - } - - private ScalarValue.Builder convertGenericValue(final GenericValue value) { - final Object wrappedValue = value.getValue(); - if (wrappedValue instanceof Double) { - return ScalarValue.newBuilder().setDoubleValue((Double) wrappedValue); - } else if (wrappedValue instanceof Integer) { - return ScalarValue.newBuilder().setIntegerValue((Integer) wrappedValue); - } else { - return convertStringValue(value); - } - } - - private org.caosdb.api.entity.v1.ScalarValue.Builder convertStringValue(final Value value) { - if (value.toString().isEmpty()) { - return ScalarValue.newBuilder().setSpecialValue(SpecialValue.SPECIAL_VALUE_EMPTY_STRING); - } - return ScalarValue.newBuilder().setStringValue(value.toString()); - } - - private org.caosdb.api.entity.v1.ScalarValue.Builder convertDateTimeInterface( - final DateTimeInterface value) { - return convertStringValue(value); - } - - private org.caosdb.api.entity.v1.ScalarValue.Builder convertBooleanValue( - final BooleanValue value) { - return ScalarValue.newBuilder().setBooleanValue(value.getValue()); - } - - private ScalarValue.Builder convertReferenceValue(final ReferenceValue value) { - return convertStringValue(value); - } - - private org.caosdb.api.entity.v1.Value.Builder convertCollectionValue( - final CollectionValue value) { - - final org.caosdb.api.entity.v1.Value.Builder builder = - org.caosdb.api.entity.v1.Value.newBuilder(); - final List<ScalarValue> values = new LinkedList<>(); - value.forEach( - (v) -> { - values.add(convertScalarValue(v)); - }); - builder.setListValues(CollectionValues.newBuilder().addAllValues(values)); - return builder; - } - - private ScalarValue convertScalarValue(final IndexedSingleValue v) { - return convertScalarValue(v.getWrapped()).build(); - } - - private Importance convert(final StatementStatus statementStatus) { - switch (statementStatus) { - case FIX: - return Importance.IMPORTANCE_FIX; - case OBLIGATORY: - return Importance.IMPORTANCE_OBLIGATORY; - case RECOMMENDED: - return Importance.IMPORTANCE_RECOMMENDED; - case SUGGESTED: - return Importance.IMPORTANCE_SUGGESTED; - default: - return null; - } - } - - private org.caosdb.api.entity.v1.DataType.Builder convert(final AbstractDatatype datatype) { - if (datatype instanceof ReferenceDatatype2) { - return DataType.newBuilder() - .setReferenceDataType(convertReferenceDatatype((ReferenceDatatype2) datatype)); - } else if (datatype instanceof FileDatatype) { - return DataType.newBuilder() - .setReferenceDataType(convertReferenceDatatype((FileDatatype) datatype)); - } else if (datatype instanceof ReferenceDatatype) { - return DataType.newBuilder() - .setReferenceDataType(convertReferenceDatatype((ReferenceDatatype) datatype)); - } else if (datatype instanceof AbstractCollectionDatatype) { - return DataType.newBuilder() - .setListDataType( - convertAbstractCollectionDatatype((AbstractCollectionDatatype) datatype)); - } else if (datatype instanceof BooleanDatatype) { - return DataType.newBuilder() - .setAtomicDataType(convertBooleanDatatype((BooleanDatatype) datatype)); - - } else if (datatype instanceof DateTimeDatatype) { - return DataType.newBuilder() - .setAtomicDataType(convertDateTimeDatatype((DateTimeDatatype) datatype)); - - } else if (datatype instanceof DoubleDatatype) { - return DataType.newBuilder() - .setAtomicDataType(convertDoubleDatatype((DoubleDatatype) datatype)); - - } else if (datatype instanceof IntegerDatatype) { - return DataType.newBuilder() - .setAtomicDataType(convertIntegerDatatype((IntegerDatatype) datatype)); - - } else if (datatype instanceof TextDatatype) { - return DataType.newBuilder().setAtomicDataType(convertTextDatatype((TextDatatype) datatype)); - } - return null; - } - - private AtomicDataType convertTextDatatype(final TextDatatype datatype) { - return AtomicDataType.ATOMIC_DATA_TYPE_TEXT; - } - - private AtomicDataType convertIntegerDatatype(final IntegerDatatype datatype) { - return AtomicDataType.ATOMIC_DATA_TYPE_INTEGER; - } - - private AtomicDataType convertDoubleDatatype(final DoubleDatatype datatype) { - return AtomicDataType.ATOMIC_DATA_TYPE_DOUBLE; - } - - private AtomicDataType convertDateTimeDatatype(final DateTimeDatatype datatype) { - return AtomicDataType.ATOMIC_DATA_TYPE_DATETIME; - } - - private AtomicDataType convertBooleanDatatype(final BooleanDatatype datatype) { - return AtomicDataType.ATOMIC_DATA_TYPE_BOOLEAN; - } - - private org.caosdb.api.entity.v1.ListDataType.Builder convertAbstractCollectionDatatype( - final AbstractCollectionDatatype collectionDatatype) { - - final org.caosdb.api.entity.v1.ListDataType.Builder listBuilder = ListDataType.newBuilder(); - final AbstractDatatype datatype = collectionDatatype.getDatatype(); - if (datatype instanceof ReferenceDatatype) { - listBuilder.setReferenceDataType(convertReferenceDatatype((ReferenceDatatype) datatype)); - } else if (datatype instanceof BooleanDatatype) { - return listBuilder.setAtomicDataType(convertBooleanDatatype((BooleanDatatype) datatype)); - - } else if (datatype instanceof DateTimeDatatype) { - return listBuilder.setAtomicDataType(convertDateTimeDatatype((DateTimeDatatype) datatype)); - - } else if (datatype instanceof DoubleDatatype) { - return listBuilder.setAtomicDataType(convertDoubleDatatype((DoubleDatatype) datatype)); - - } else if (datatype instanceof IntegerDatatype) { - return listBuilder.setAtomicDataType(convertIntegerDatatype((IntegerDatatype) datatype)); - - } else if (datatype instanceof TextDatatype) { - return listBuilder.setAtomicDataType(convertTextDatatype((TextDatatype) datatype)); - } - return listBuilder; - } - - private org.caosdb.api.entity.v1.ReferenceDataType.Builder convertReferenceDatatype( - final ReferenceDatatype datatype) { - return ReferenceDataType.newBuilder().setName(datatype.getName()); - } - - public Iterable<? extends org.caosdb.api.entity.v1.Property> convert( - final PropertyContainer from) { - final Iterator<org.caosdb.server.entity.wrapper.Property> iterator = from.iterator(); - return () -> - new Iterator<>() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public org.caosdb.api.entity.v1.Property next() { - return convert(iterator.next()); - } - }; - } - - public Iterable<? extends Parent> convert(final ParentContainer from) { - final Iterator<org.caosdb.server.entity.wrapper.Parent> iterator = from.iterator(); - return () -> - new Iterator<>() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public Parent next() { - return convert(iterator.next()); - } - }; - } - - public Integer getId(final String id) { - return Integer.parseInt(id); + public EntityTransactionServiceImpl(final FileTransmissionServiceImpl fileTransmissionService) { + this.fileTransmissionService = fileTransmissionService; } /** @@ -490,7 +78,7 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa final String id = sub_request.getRetrieveRequest().getId(); if (!id.isBlank()) { try { - final RetrieveEntity entity = new RetrieveEntity(getId(id)); + final RetrieveEntity entity = new RetrieveEntity(grpcToCaosdb.getId(id)); if (fileDownload) { entity.setFlag("download_files", "true"); } @@ -512,7 +100,7 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa } else { final boolean download_files_container = container.getFlags().containsKey("download_files"); for (final EntityInterface entity : container) { - final EntityResponse.Builder entityResponse = convert(entity); + final EntityResponse.Builder entityResponse = caosdbToGrpc.convert(entity); if ((download_files_container || entity.getFlags().containsKey("download_files")) && entity.hasFileProperties()) { if (file_download == null) { @@ -534,7 +122,7 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa final String id = sub_request.getRetrieveRequest().getId(); if (!id.isBlank()) { try { - getId(id); + grpcToCaosdb.getId(id); } catch (final NumberFormatException e) { // ID wasn't an integer - the server doesn't support string id's yet, so that entity // cannot @@ -551,7 +139,7 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa private EntityResponse entityDoesNotExist(final String id) { return EntityResponse.newBuilder() - .addErrors(convert(ServerMessages.ENTITY_DOES_NOT_EXIST)) + .addErrors(caosdbToGrpc.convert(ServerMessages.ENTITY_DOES_NOT_EXIST)) .setEntity(Entity.newBuilder().setId(id)) .build(); } @@ -619,8 +207,8 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa final InsertEntity entity = new InsertEntity( insertEntity.getName().isEmpty() ? null : insertEntity.getName(), - convert(insertEntity.getRole())); - convert(insertEntity, entity); + grpcToCaosdb.convert(insertEntity.getRole())); + grpcToCaosdb.convert(insertEntity, entity); addFileUpload(container, entity, insertRequest.getEntityRequest()); container.add(entity); } @@ -631,9 +219,11 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa try { final UpdateEntity entity = - new UpdateEntity(getId(updateEntity.getId()), convert(updateEntity.getRole())); + new UpdateEntity( + grpcToCaosdb.getId(updateEntity.getId()), + grpcToCaosdb.convert(updateEntity.getRole())); entity.setName(updateEntity.getName().isEmpty() ? null : updateEntity.getName()); - convert(updateEntity, entity); + grpcToCaosdb.convert(updateEntity, entity); addFileUpload(container, entity, updateRequest.getEntityRequest()); container.add(entity); } catch (final NumberFormatException e) { @@ -644,7 +234,7 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa case DELETE_REQUEST: final DeleteRequest deleteRequest = subRequest.getDeleteRequest(); try { - final DeleteEntity entity = new DeleteEntity(getId(deleteRequest.getId())); + final DeleteEntity entity = new DeleteEntity(grpcToCaosdb.getId(deleteRequest.getId())); container.add(entity); } catch (final NumberFormatException e) { @@ -671,7 +261,7 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa if (entity.getId() != null) { idResponse.setId(entity.getId().toString()); } - appendMessages(entity, idResponse); + caosdbToGrpc.appendMessages(entity, idResponse); if (entity instanceof InsertEntity) { builder @@ -717,10 +307,10 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa idResponse.setId(updateEntity.getId()); try { - getId(updateEntity.getId()); + grpcToCaosdb.getId(updateEntity.getId()); } catch (final NumberFormatException e) { // ID wasn't an integer - idResponse.addErrors(convert(ServerMessages.ENTITY_DOES_NOT_EXIST)); + idResponse.addErrors(caosdbToGrpc.convert(ServerMessages.ENTITY_DOES_NOT_EXIST)); } builder .addResponsesBuilder() @@ -730,10 +320,10 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa final DeleteRequest deleteRequest = subRequest.getDeleteRequest(); idResponse.setId(deleteRequest.getId()); try { - getId(deleteRequest.getId()); + grpcToCaosdb.getId(deleteRequest.getId()); } catch (final NumberFormatException e) { // ID wasn't an integer - idResponse.addErrors(convert(ServerMessages.ENTITY_DOES_NOT_EXIST)); + idResponse.addErrors(caosdbToGrpc.convert(ServerMessages.ENTITY_DOES_NOT_EXIST)); } builder .addResponsesBuilder() @@ -765,280 +355,6 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa } } - private Role convert(final EntityRole role) { - switch (role) { - case ENTITY_ROLE_FILE: - return Role.File; - case ENTITY_ROLE_PROPERTY: - return Role.Property; - case ENTITY_ROLE_RECORD: - return Role.Record; - case ENTITY_ROLE_RECORD_TYPE: - return Role.RecordType; - default: - return null; - } - } - - private void appendMessages( - final EntityInterface from, final org.caosdb.api.entity.v1.EntityResponse.Builder builder) { - if (from.hasMessage(Message.MessageType.Error.toString())) { - builder.addAllErrors(convert(from.getMessages(Message.MessageType.Error.toString()))); - } - if (from.hasMessage(Message.MessageType.Warning.toString())) { - builder.addAllWarnings(convert(from.getMessages(Message.MessageType.Warning.toString()))); - } - if (from.hasMessage(Message.MessageType.Info.toString())) { - builder.addAllInfos(convert(from.getMessages(Message.MessageType.Info.toString()))); - } - } - - private void appendMessages( - final EntityInterface from, final org.caosdb.api.entity.v1.IdResponse.Builder builder) { - if (from.hasMessage(Message.MessageType.Error.toString())) { - builder.addAllErrors(convert(from.getMessages(Message.MessageType.Error.toString()))); - } - if (from.hasMessage(Message.MessageType.Warning.toString())) { - builder.addAllWarnings(convert(from.getMessages(Message.MessageType.Warning.toString()))); - } - if (from.hasMessage(Message.MessageType.Info.toString())) { - builder.addAllInfos(convert(from.getMessages(Message.MessageType.Info.toString()))); - } - } - - public Property getUnit(final String unitStr) { - final EntityInterface magicUnit = MagicTypes.UNIT.getEntity(); - final Property unit = new Property(); - unit.setDescription(magicUnit.getDescription()); - unit.setName(magicUnit.getName()); - unit.setId(magicUnit.getId()); - unit.setDatatype(magicUnit.getDatatype()); - unit.setStatementStatus(StatementStatus.FIX); - unit.setValue(new GenericValue(unitStr)); - unit.setEntityStatus(EntityStatus.QUALIFIED); - return unit; - } - - public Value getValue(final String valString) { - return new GenericValue(valString); - } - - private EntityInterface convert(final Entity from, final EntityInterface entity) { - entity.setName(from.getName().isEmpty() ? null : from.getName()); - entity.setDescription(from.getDescription().isBlank() ? null : from.getDescription()); - if (!from.getUnit().isBlank()) { - entity.addProperty(getUnit(from.getUnit())); - } - if (from.hasDataType()) { - entity.setDatatype(convert(from.getDataType())); - } - if (from.hasValue()) { - entity.setValue(convert(from.getValue())); - } - - if (from.getPropertiesCount() > 0) { - final StatementStatus defaultImportance = - entity.getRole() == Role.RecordType ? StatementStatus.RECOMMENDED : StatementStatus.FIX; - entity.getProperties().addAll(convertProperties(from.getPropertiesList(), defaultImportance)); - } - if (from.getParentsCount() > 0) { - entity.getParents().addAll(convertParents(from.getParentsList())); - } - if (from.hasFileDescriptor()) { - entity.setFileProperties(convert(from.getFileDescriptor())); - } - return entity; - } - - private Value convert(final org.caosdb.api.entity.v1.Value value) { - switch (value.getValueCase()) { - case LIST_VALUES: - return convertListValue(value.getListValues()); - case SCALAR_VALUE: - return convertScalarValue(value.getScalarValue()); - default: - break; - } - return null; - } - - private CollectionValue convertListValue(final CollectionValues collectionValues) { - final CollectionValue result = new CollectionValue(); - collectionValues - .getValuesList() - .forEach( - (v) -> { - result.add(convertScalarValue(v)); - }); - return result; - } - - private Value convertScalarValue(final org.caosdb.api.entity.v1.ScalarValue value) { - switch (value.getScalarValueCase()) { - case BOOLEAN_VALUE: - return BooleanValue.valueOf(value.getBooleanValue()); - case DOUBLE_VALUE: - return new GenericValue(value.getDoubleValue()); - case INTEGER_VALUE: - return new GenericValue(Long.toString(value.getIntegerValue())); - case SPECIAL_VALUE: - return convertSpecial(value.getSpecialValue()); - case STRING_VALUE: - return new GenericValue(value.getStringValue()); - default: - break; - } - return null; - } - - private Value convertSpecial(final SpecialValue specialValue) { - if (specialValue == SpecialValue.SPECIAL_VALUE_EMPTY_STRING) { - return new GenericValue(""); - } - return null; - } - - private AbstractDatatype convert(final DataType dataType) { - switch (dataType.getDataTypeCase()) { - case ATOMIC_DATA_TYPE: - return convertAtomicType(dataType.getAtomicDataType()); - case LIST_DATA_TYPE: - return convertListDataType(dataType.getListDataType()); - case REFERENCE_DATA_TYPE: - return convertReferenceDataType(dataType.getReferenceDataType()); - default: - break; - } - return null; - } - - private ReferenceDatatype convertReferenceDataType(final ReferenceDataType referenceDataType) { - final String name = referenceDataType.getName(); - if (name.equalsIgnoreCase("REFERENCE")) { - return new ReferenceDatatype(); - } else if (name.equalsIgnoreCase("FILE")) { - return new FileDatatype(); - } - return new ReferenceDatatype2(name); - } - - private AbstractDatatype convertAtomicType(final AtomicDataType dataType) { - switch (dataType) { - case ATOMIC_DATA_TYPE_BOOLEAN: - return AbstractDatatype.datatypeFactory("BOOLEAN"); - case ATOMIC_DATA_TYPE_DATETIME: - return AbstractDatatype.datatypeFactory("DATETIME"); - case ATOMIC_DATA_TYPE_DOUBLE: - return AbstractDatatype.datatypeFactory("DOUBLE"); - case ATOMIC_DATA_TYPE_INTEGER: - return AbstractDatatype.datatypeFactory("INTEGER"); - case ATOMIC_DATA_TYPE_TEXT: - return AbstractDatatype.datatypeFactory("TEXT"); - default: - return null; - } - } - - private AbstractDatatype convertListDataType(final ListDataType dataType) { - switch (dataType.getListDataTypeCase()) { - case ATOMIC_DATA_TYPE: - return new ListDatatype(convertAtomicType(dataType.getAtomicDataType())); - case REFERENCE_DATA_TYPE: - return new ListDatatype(convertReferenceDataType(dataType.getReferenceDataType())); - default: - return null; - } - } - - private FileProperties convert(final FileDescriptor fileDescriptor) { - return new FileProperties( - null, - fileDescriptor.getPath(), - fileDescriptor.getSize() == 0 ? null : fileDescriptor.getSize()); - } - - private Collection<Property> convertProperties( - final List<org.caosdb.api.entity.v1.Property> propertiesList, - final StatementStatus defaultImportance) { - final Collection<Property> result = new LinkedList<>(); - propertiesList.forEach( - e -> { - result.add(convert(e, defaultImportance)); - }); - return result; - } - - private Property convert( - final org.caosdb.api.entity.v1.Property e, final StatementStatus defaultImportance) { - final Property result = new Property(); - - try { - result.setId(e.getId().isBlank() ? null : getId(e.getId())); - } catch (final NumberFormatException exc) { - result.addError(ServerMessages.ENTITY_DOES_NOT_EXIST); - } - result.setName(e.getName().isBlank() ? null : e.getName()); - result.setDescription(e.getDescription().isBlank() ? null : e.getDescription()); - if (!e.getUnit().isBlank()) { - result.addProperty(getUnit(e.getUnit())); - } - if (e.hasDataType()) { - result.setDatatype(convert(e.getDataType())); - } - if (e.hasValue()) { - result.setValue(convert(e.getValue())); - } - if (e.getImportance() != Importance.IMPORTANCE_UNSPECIFIED) { - result.setStatementStatus(convert(e.getImportance())); - } else { - result.setStatementStatus(defaultImportance); - } - // TODO remove this hard-coded setting when the API supports flags - if (result.getFlag("inheritance") == null) { - result.setFlag("inheritance", "fix"); - } - - return result; - } - - private StatementStatus convert(final Importance importance) { - switch (importance) { - case IMPORTANCE_FIX: - return StatementStatus.FIX; - case IMPORTANCE_OBLIGATORY: - return StatementStatus.OBLIGATORY; - case IMPORTANCE_RECOMMENDED: - return StatementStatus.RECOMMENDED; - case IMPORTANCE_SUGGESTED: - return StatementStatus.SUGGESTED; - default: - return null; - } - } - - private Collection<org.caosdb.server.entity.wrapper.Parent> convertParents( - final List<Parent> parentsList) { - final Collection<org.caosdb.server.entity.wrapper.Parent> result = new LinkedList<>(); - parentsList.forEach( - e -> { - result.add(convert(e)); - }); - return result; - } - - private org.caosdb.server.entity.wrapper.Parent convert(final Parent e) { - final org.caosdb.server.entity.wrapper.Parent result = - new org.caosdb.server.entity.wrapper.Parent(); - - try { - result.setId(e.getId().isBlank() ? null : getId(e.getId())); - } catch (final NumberFormatException exc) { - result.addError(ServerMessages.ENTITY_DOES_NOT_EXIST); - } - result.setName(e.getName().isBlank() ? null : e.getName()); - return result; - } - @Override public void multiTransaction( final MultiTransactionRequest request, diff --git a/src/main/java/org/caosdb/server/grpc/GrpcToCaosDBConverters.java b/src/main/java/org/caosdb/server/grpc/GrpcToCaosDBConverters.java new file mode 100644 index 0000000000000000000000000000000000000000..a79f1293f2d0f6ddc343da3b4215db9cc9ec1c94 --- /dev/null +++ b/src/main/java/org/caosdb/server/grpc/GrpcToCaosDBConverters.java @@ -0,0 +1,288 @@ +package org.caosdb.server.grpc; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import org.caosdb.api.entity.v1.AtomicDataType; +import org.caosdb.api.entity.v1.CollectionValues; +import org.caosdb.api.entity.v1.DataType; +import org.caosdb.api.entity.v1.Entity; +import org.caosdb.api.entity.v1.EntityRole; +import org.caosdb.api.entity.v1.FileDescriptor; +import org.caosdb.api.entity.v1.Importance; +import org.caosdb.api.entity.v1.ListDataType; +import org.caosdb.api.entity.v1.Parent; +import org.caosdb.api.entity.v1.ReferenceDataType; +import org.caosdb.api.entity.v1.SpecialValue; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.datatype.BooleanValue; +import org.caosdb.server.datatype.CollectionValue; +import org.caosdb.server.datatype.FileDatatype; +import org.caosdb.server.datatype.GenericValue; +import org.caosdb.server.datatype.ListDatatype; +import org.caosdb.server.datatype.ReferenceDatatype; +import org.caosdb.server.datatype.ReferenceDatatype2; +import org.caosdb.server.datatype.Value; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.MagicTypes; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; + +public class GrpcToCaosDBConverters { + /// MOVE + public Integer getId(final String id) { + return Integer.parseInt(id); + } + + public Role convert(final EntityRole role) { + switch (role) { + case ENTITY_ROLE_FILE: + return Role.File; + case ENTITY_ROLE_PROPERTY: + return Role.Property; + case ENTITY_ROLE_RECORD: + return Role.Record; + case ENTITY_ROLE_RECORD_TYPE: + return Role.RecordType; + default: + return null; + } + } + + public Property getUnit(final String unitStr) { + final EntityInterface magicUnit = MagicTypes.UNIT.getEntity(); + final Property unit = new Property(); + unit.setDescription(magicUnit.getDescription()); + unit.setName(magicUnit.getName()); + unit.setId(magicUnit.getId()); + unit.setDatatype(magicUnit.getDatatype()); + unit.setStatementStatus(StatementStatus.FIX); + unit.setValue(new GenericValue(unitStr)); + unit.setEntityStatus(EntityStatus.QUALIFIED); + return unit; + } + + public Value getValue(final String valString) { + return new GenericValue(valString); + } + + public EntityInterface convert(final Entity from, final EntityInterface entity) { + entity.setName(from.getName().isEmpty() ? null : from.getName()); + entity.setDescription(from.getDescription().isBlank() ? null : from.getDescription()); + if (!from.getUnit().isBlank()) { + entity.addProperty(getUnit(from.getUnit())); + } + if (from.hasDataType()) { + entity.setDatatype(convert(from.getDataType())); + } + if (from.hasValue()) { + entity.setValue(convert(from.getValue())); + } + + if (from.getPropertiesCount() > 0) { + final StatementStatus defaultImportance = + entity.getRole() == Role.RecordType ? StatementStatus.RECOMMENDED : StatementStatus.FIX; + entity.getProperties().addAll(convertProperties(from.getPropertiesList(), defaultImportance)); + } + if (from.getParentsCount() > 0) { + entity.getParents().addAll(convertParents(from.getParentsList())); + } + if (from.hasFileDescriptor()) { + entity.setFileProperties(convert(from.getFileDescriptor())); + } + return entity; + } + + private Value convert(final org.caosdb.api.entity.v1.Value value) { + switch (value.getValueCase()) { + case LIST_VALUES: + return convertListValue(value.getListValues()); + case SCALAR_VALUE: + return convertScalarValue(value.getScalarValue()); + default: + break; + } + return null; + } + + private CollectionValue convertListValue(final CollectionValues collectionValues) { + final CollectionValue result = new CollectionValue(); + collectionValues + .getValuesList() + .forEach( + (v) -> { + result.add(convertScalarValue(v)); + }); + return result; + } + + private Value convertScalarValue(final org.caosdb.api.entity.v1.ScalarValue value) { + switch (value.getScalarValueCase()) { + case BOOLEAN_VALUE: + return BooleanValue.valueOf(value.getBooleanValue()); + case DOUBLE_VALUE: + return new GenericValue(value.getDoubleValue()); + case INTEGER_VALUE: + return new GenericValue(Long.toString(value.getIntegerValue())); + case SPECIAL_VALUE: + return convertSpecial(value.getSpecialValue()); + case STRING_VALUE: + return new GenericValue(value.getStringValue()); + default: + break; + } + return null; + } + + private Value convertSpecial(final SpecialValue specialValue) { + if (specialValue == SpecialValue.SPECIAL_VALUE_EMPTY_STRING) { + return new GenericValue(""); + } + return null; + } + + private AbstractDatatype convert(final DataType dataType) { + switch (dataType.getDataTypeCase()) { + case ATOMIC_DATA_TYPE: + return convertAtomicType(dataType.getAtomicDataType()); + case LIST_DATA_TYPE: + return convertListDataType(dataType.getListDataType()); + case REFERENCE_DATA_TYPE: + return convertReferenceDataType(dataType.getReferenceDataType()); + default: + break; + } + return null; + } + + private ReferenceDatatype convertReferenceDataType(final ReferenceDataType referenceDataType) { + final String name = referenceDataType.getName(); + if (name.equalsIgnoreCase("REFERENCE")) { + return new ReferenceDatatype(); + } else if (name.equalsIgnoreCase("FILE")) { + return new FileDatatype(); + } + return new ReferenceDatatype2(name); + } + + private AbstractDatatype convertAtomicType(final AtomicDataType dataType) { + switch (dataType) { + case ATOMIC_DATA_TYPE_BOOLEAN: + return AbstractDatatype.datatypeFactory("BOOLEAN"); + case ATOMIC_DATA_TYPE_DATETIME: + return AbstractDatatype.datatypeFactory("DATETIME"); + case ATOMIC_DATA_TYPE_DOUBLE: + return AbstractDatatype.datatypeFactory("DOUBLE"); + case ATOMIC_DATA_TYPE_INTEGER: + return AbstractDatatype.datatypeFactory("INTEGER"); + case ATOMIC_DATA_TYPE_TEXT: + return AbstractDatatype.datatypeFactory("TEXT"); + default: + return null; + } + } + + private AbstractDatatype convertListDataType(final ListDataType dataType) { + switch (dataType.getListDataTypeCase()) { + case ATOMIC_DATA_TYPE: + return new ListDatatype(convertAtomicType(dataType.getAtomicDataType())); + case REFERENCE_DATA_TYPE: + return new ListDatatype(convertReferenceDataType(dataType.getReferenceDataType())); + default: + return null; + } + } + + private FileProperties convert(final FileDescriptor fileDescriptor) { + return new FileProperties( + null, + fileDescriptor.getPath(), + fileDescriptor.getSize() == 0 ? null : fileDescriptor.getSize()); + } + + private Collection<Property> convertProperties( + final List<org.caosdb.api.entity.v1.Property> propertiesList, + final StatementStatus defaultImportance) { + final Collection<Property> result = new LinkedList<>(); + propertiesList.forEach( + e -> { + result.add(convert(e, defaultImportance)); + }); + return result; + } + + private Property convert( + final org.caosdb.api.entity.v1.Property e, final StatementStatus defaultImportance) { + final Property result = new Property(); + + try { + result.setId(e.getId().isBlank() ? null : getId(e.getId())); + } catch (final NumberFormatException exc) { + result.addError(ServerMessages.ENTITY_DOES_NOT_EXIST); + } + result.setName(e.getName().isBlank() ? null : e.getName()); + result.setDescription(e.getDescription().isBlank() ? null : e.getDescription()); + if (!e.getUnit().isBlank()) { + result.addProperty(getUnit(e.getUnit())); + } + if (e.hasDataType()) { + result.setDatatype(convert(e.getDataType())); + } + if (e.hasValue()) { + result.setValue(convert(e.getValue())); + } + if (e.getImportance() != Importance.IMPORTANCE_UNSPECIFIED) { + result.setStatementStatus(convert(e.getImportance())); + } else { + result.setStatementStatus(defaultImportance); + } + // TODO remove this hard-coded setting when the API supports flags + if (result.getFlag("inheritance") == null) { + result.setFlag("inheritance", "fix"); + } + + return result; + } + + private StatementStatus convert(final Importance importance) { + switch (importance) { + case IMPORTANCE_FIX: + return StatementStatus.FIX; + case IMPORTANCE_OBLIGATORY: + return StatementStatus.OBLIGATORY; + case IMPORTANCE_RECOMMENDED: + return StatementStatus.RECOMMENDED; + case IMPORTANCE_SUGGESTED: + return StatementStatus.SUGGESTED; + default: + return null; + } + } + + private Collection<org.caosdb.server.entity.wrapper.Parent> convertParents( + final List<Parent> parentsList) { + final Collection<org.caosdb.server.entity.wrapper.Parent> result = new LinkedList<>(); + parentsList.forEach( + e -> { + result.add(convert(e)); + }); + return result; + } + + private org.caosdb.server.entity.wrapper.Parent convert(final Parent e) { + final org.caosdb.server.entity.wrapper.Parent result = + new org.caosdb.server.entity.wrapper.Parent(); + + try { + result.setId(e.getId().isBlank() ? null : getId(e.getId())); + } catch (final NumberFormatException exc) { + result.addError(ServerMessages.ENTITY_DOES_NOT_EXIST); + } + result.setName(e.getName().isBlank() ? null : e.getName()); + return result; + } +} diff --git a/src/main/java/org/caosdb/server/utils/ServerMessages.java b/src/main/java/org/caosdb/server/utils/ServerMessages.java index 6280ca28eb0515ce395b51ea3e75fd7984385a58..759aeef837092b3d1e004cbd4ec1d2016c388b83 100644 --- a/src/main/java/org/caosdb/server/utils/ServerMessages.java +++ b/src/main/java/org/caosdb/server/utils/ServerMessages.java @@ -55,7 +55,7 @@ public class ServerMessages { new Message(MessageType.Error, MessageCode.MESSAGE_CODE_UNKNOWN, "Parsing failed."); public static final Message UNKNOWN_DATATYPE = - new Message(MessageType.Error, MessageCode.MESSAGE_CODE_UNKNOWN, "Unknown data type."); + new Message(MessageType.Error, MessageCode.MESSAGE_CODE_UNKNOWN, "Unknown datatype."); public static final Message UNKNOWN_IMPORTANCE = new Message(MessageType.Error, MessageCode.MESSAGE_CODE_UNKNOWN, "Unknown importance.");