package de.jpaw.bonaparte.core; import java.math.BigDecimal; import java.math.BigInteger; import java.util.List; import java.util.UUID; import org.joda.time.Instant; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; import de.jpaw.bonaparte.pojos.meta.AlphanumericElementaryDataItem; import de.jpaw.bonaparte.pojos.meta.BasicNumericElementaryDataItem; import de.jpaw.bonaparte.pojos.meta.BinaryElementaryDataItem; import de.jpaw.bonaparte.pojos.meta.EnumDataItem; import de.jpaw.bonaparte.pojos.meta.FieldDefinition; import de.jpaw.bonaparte.pojos.meta.MiscElementaryDataItem; import de.jpaw.bonaparte.pojos.meta.NumericElementaryDataItem; import de.jpaw.bonaparte.pojos.meta.ObjectReference; import de.jpaw.bonaparte.pojos.meta.TemporalElementaryDataItem; import de.jpaw.bonaparte.pojos.meta.XEnumDataItem; import de.jpaw.enums.AbstractXEnumBase; import de.jpaw.enums.XEnumFactory; import de.jpaw.util.ByteArray; /** A parser which takes data through a provided functional interface, any implementation which provides a String get(String). * Mainly intended for use from Java 8 applications. */ public class StringProviderParser extends AbstractPartialJsonStringParser implements MessageParser<MessageParserException> { private final StringParserUtil stringParser = new StringParserUtil(); // TODO; in the form with the provided classname, push it down to the Util private final String currentClass; private final StringGetter requestParameters; public static interface StringGetter { /** Returns the contents of the field named by name, or null if that field has not been provided. */ String get(String name) throws MessageParserException; } @Override protected MessageParserException newMPE(int errorCode, FieldDefinition di, String msg) { return new MessageParserException(errorCode, di.getName(), -1, currentClass, msg); } /** Utility method: populate BonaPortable from provided getter. * Example for Xtend, using a val Map<String,String> m: obj.unmarshal[m.get(it)]. * Example for Java 8: unmarshal(obj, m::get) */ public static void unmarshal(BonaPortable obj, StringGetter getter) throws MessageParserException { obj.deserialize(new StringProviderParser(getter, obj.ret$PQON())); } public StringProviderParser(StringGetter requestParameters) { this.requestParameters = requestParameters; this.currentClass = "N/A"; } public StringProviderParser(StringGetter requestParameters, String classname) { this.requestParameters = requestParameters; this.currentClass = classname; } private String getParameter(FieldDefinition di) throws MessageParserException { String data = requestParameters.get(di.getName()); if (data == null && di.getIsRequired()) throw new MessageParserException(MessageParserException.EMPTY_BUT_REQUIRED_FIELD, di.getName(), -1, currentClass); return data; } @Override public Character readCharacter(MiscElementaryDataItem di) throws MessageParserException { return stringParser.readCharacter(di, getParameter(di)); } @Override public UUID readUUID(MiscElementaryDataItem di) throws MessageParserException { return stringParser.readUUID(di, getParameter(di)); } @Override public Boolean readBoolean(MiscElementaryDataItem di) throws MessageParserException { return stringParser.readBoolean(di, getParameter(di)); } @Override public Double readDouble(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readDouble(di, getParameter(di)); } @Override public Float readFloat(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readFloat(di, getParameter(di)); } @Override public Long readLong(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readLong(di, getParameter(di)); } @Override public Integer readInteger(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readInteger(di, getParameter(di)); } @Override public Short readShort(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readShort(di, getParameter(di)); } @Override public Byte readByte(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readByte(di, getParameter(di)); } @Override public BigInteger readBigInteger(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readBigInteger(di, getParameter(di)); } @Override public BigDecimal readBigDecimal(NumericElementaryDataItem di) throws MessageParserException { return stringParser.readBigDecimal(di, getParameter(di)); } @Override public String readAscii(AlphanumericElementaryDataItem di) throws MessageParserException { return stringParser.readAscii(di, getParameter(di)); } @Override public String readString(AlphanumericElementaryDataItem di) throws MessageParserException { return stringParser.readString(di, getParameter(di)); } @Override public ByteArray readByteArray(BinaryElementaryDataItem di) throws MessageParserException { return stringParser.readByteArray(di, getParameter(di)); } @Override public byte[] readRaw(BinaryElementaryDataItem di) throws MessageParserException { return stringParser.readRaw(di, getParameter(di)); } @Override public Instant readInstant(TemporalElementaryDataItem di) throws MessageParserException { return stringParser.readInstant(di, getParameter(di)); } @Override public LocalDate readDay(TemporalElementaryDataItem di) throws MessageParserException { return stringParser.readDay(di, getParameter(di)); } @Override public LocalTime readTime(TemporalElementaryDataItem di) throws MessageParserException { return stringParser.readTime(di, getParameter(di)); } @Override public LocalDateTime readDayTime(TemporalElementaryDataItem di) throws MessageParserException { return stringParser.readDayTime(di, getParameter(di)); } @Override public <R extends BonaPortable> R readObject(ObjectReference di, Class<R> type) throws MessageParserException { throw new MessageParserException(MessageParserException.UNSUPPORTED_DATA_TYPE, di.getName(), -1, currentClass); } @Override public int parseMapStart(FieldDefinition di) throws MessageParserException { throw new MessageParserException(MessageParserException.UNSUPPORTED_DATA_TYPE, di.getName(), -1, currentClass); } @Override public int parseArrayStart(FieldDefinition di, int sizeOfElement) throws MessageParserException { throw new MessageParserException(MessageParserException.UNSUPPORTED_DATA_TYPE, di.getName(), -1, currentClass); } @Override public void parseArrayEnd() throws MessageParserException { throw new MessageParserException(MessageParserException.UNSUPPORTED_DATA_TYPE); } @Override public BonaPortable readRecord() throws MessageParserException { throw new MessageParserException(MessageParserException.UNSUPPORTED_DATA_TYPE); } @Override public List<BonaPortable> readTransmission() throws MessageParserException { throw new MessageParserException(MessageParserException.UNSUPPORTED_DATA_TYPE); } @Override public void setClassName(String newClassName) { // ignored } @Override public void eatParentSeparator() throws MessageParserException { } @Override public <T extends AbstractXEnumBase<T>> T readXEnum(XEnumDataItem di, XEnumFactory<T> factory) throws MessageParserException { return stringParser.readXEnum(di, factory, getParameter(di)); } @Override public MessageParserException enumExceptionConverter(IllegalArgumentException e) throws MessageParserException { return new MessageParserException(MessageParserException.INVALID_ENUM_TOKEN, e.getMessage(), -1, currentClass); } @Override public MessageParserException customExceptionConverter(String msg, Exception e) throws MessageParserException { return new MessageParserException(MessageParserException.CUSTOM_OBJECT_EXCEPTION, e != null ? msg + e.toString() : msg, -1, currentClass); } @Override public boolean readPrimitiveBoolean(MiscElementaryDataItem di) throws MessageParserException { return stringParser.readPrimitiveBoolean(di, getParameter(di)); } @Override public char readPrimitiveCharacter(MiscElementaryDataItem di) throws MessageParserException { return stringParser.readPrimitiveCharacter(di, getParameter(di)); } @Override public double readPrimitiveDouble(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readPrimitiveDouble(di, getParameter(di)); } @Override public float readPrimitiveFloat(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readPrimitiveFloat(di, getParameter(di)); } @Override public long readPrimitiveLong(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readPrimitiveLong(di, getParameter(di)); } @Override public int readPrimitiveInteger(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readPrimitiveInteger(di, getParameter(di)); } @Override public short readPrimitiveShort(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readPrimitiveShort(di, getParameter(di)); } @Override public byte readPrimitiveByte(BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readPrimitiveByte(di, getParameter(di)); } // special internal method for AbstractPartialJsonStringParser @Override protected String getString(FieldDefinition di) throws MessageParserException { return getParameter(di); } // special handling of enums: access the original name, not the one with $token suffix: take care when di and when edi is used! @Override public Integer readEnum(EnumDataItem edi, BasicNumericElementaryDataItem di) throws MessageParserException { return stringParser.readInteger(di, getParameter(edi)); } // special handling of enums: access the original name, not the one with $token suffix: take care when di and when edi is used! @Override public String readEnum(EnumDataItem edi, AlphanumericElementaryDataItem di) throws MessageParserException { return stringParser.readString(di, getParameter(edi)); } }