package io.gridgo.bean; import java.util.Base64; import io.gridgo.bean.exceptions.InvalidTypeException; import io.gridgo.bean.factory.BFactory; import io.gridgo.utils.ByteArrayUtils; import io.gridgo.utils.PrimitiveUtils; public interface BValue extends BElement { static BValue ofEmpty() { return BFactory.newDefaultValue(); } static BValue of(Object data) { return BFactory.DEFAULT.newValue(data); } @Override default boolean isValue() { return true; } @Override default BType getType() { if (this.isNull()) return BType.NULL; if (Boolean.class.isInstance(this.getData())) return BType.BOOLEAN; if (Character.class.isInstance(this.getData())) return BType.CHAR; if (Byte.class.isInstance(this.getData())) return BType.BYTE; if (Short.class.isInstance(this.getData())) return BType.SHORT; if (Integer.class.isInstance(this.getData())) return BType.INTEGER; if (Float.class.isInstance(this.getData())) return BType.FLOAT; if (Long.class.isInstance(this.getData())) return BType.LONG; if (Double.class.isInstance(this.getData())) return BType.DOUBLE; if (String.class.isInstance(this.getData())) return BType.STRING; if (byte[].class.isInstance(this.getData())) return BType.RAW; if (Number.class.isInstance(this.getData())) return BType.GENERIC_NUMBER; throw new InvalidTypeException("Cannot recognize data type: " + this.getData().getClass()); } void setData(Object data); Object getData(); default boolean isNull() { return this.getData() == null; } default Boolean getBoolean() { if (!this.isNull()) { return PrimitiveUtils.getBooleanValueFrom(this.getData()); } return null; } default Character getChar() { if (!this.isNull()) { return PrimitiveUtils.getCharValueFrom(this.getData()); } return null; } default Byte getByte() { if (!this.isNull()) { return PrimitiveUtils.getByteValueFrom(this.getData()); } return null; } default Short getShort() { if (!this.isNull()) { return PrimitiveUtils.getShortValueFrom(this.getData()); } return null; } default Integer getInteger() { if (!this.isNull()) { return PrimitiveUtils.getIntegerValueFrom(this.getData()); } return null; } default Float getFloat() { if (!this.isNull()) { return PrimitiveUtils.getFloatValueFrom(this.getData()); } return null; } default Long getLong() { if (!this.isNull()) { return PrimitiveUtils.getLongValueFrom(this.getData()); } return null; } default Double getDouble() { if (!this.isNull()) { return PrimitiveUtils.getDoubleValueFrom(this.getData()); } return null; } default String getString() { if (!this.isNull()) { return PrimitiveUtils.getStringValueFrom(this.getData()); } return null; } default byte[] getRaw() { if (!this.isNull()) { return ByteArrayUtils.primitiveToBytes(this.getData()); } return null; } default BValue encodeHex() { if (!(this.getData() instanceof byte[])) { throw new InvalidTypeException("Cannot encode hex from data which is not in raw (byte[]) format"); } this.setData(ByteArrayUtils.toHex(getRaw(), "0x")); return this; } default BValue decodeHex() { if (this.getData() instanceof byte[]) { // skip decode if data already in byte[] return this; } if (!(this.getData() instanceof String)) { throw new InvalidTypeException("Cannot decode hex from data which is not in String format"); } String hex = this.getString(); this.setData(ByteArrayUtils.fromHex(hex)); return this; } default BValue encodeBase64() { if (!(this.getData() instanceof byte[])) { throw new InvalidTypeException("Cannot encode base64 from data which is not in raw (byte[]) format"); } this.setData(Base64.getEncoder().encodeToString(getRaw())); return this; } default BValue decodeBase64() { if (!(this.getData() instanceof String)) { throw new InvalidTypeException("Cannot decode base64 from data which is not in String format"); } String base64 = this.getString(); this.setData(Base64.getDecoder().decode(base64)); return this; } default <T> T getDataAs(Class<T> targetType) { return PrimitiveUtils.getValueFrom(targetType, this.getData()); } default BValue convertToBoolean() { this.setData(this.getBoolean()); return this; } default BValue convertToChar() { this.setData(this.getChar()); return this; } default BValue convertToByte() { this.setData(this.getByte()); return this; } default BValue convertToShort() { this.setData(this.getShort()); return this; } default BValue convertToInteger() { this.setData(this.getInteger()); return this; } default BValue convertToLong() { this.setData(this.getLong()); return this; } default BValue convertToFloat() { this.setData(this.getFloat()); return this; } default BValue convertToDouble() { this.setData(this.getDouble()); return this; } default BValue convertToRaw() { this.setData(this.getRaw()); return this; } default BValue convertToString() { this.setData(this.getString()); return this; } @Override @SuppressWarnings("unchecked") default <T extends BElement> T deepClone() { return (T) of(this.getData()); } @SuppressWarnings("unchecked") @Override default <T> T getInnerValue() { return (T) getData(); } }