diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/EscapeJson.java b/src/main/java/com/avaje/ebeaninternal/server/type/EscapeJson.java index 320234777..1267aa31a 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/EscapeJson.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/EscapeJson.java @@ -3,10 +3,18 @@ package com.avaje.ebeaninternal.server.type; import java.io.IOException; import com.avaje.ebean.text.TextException; +import com.avaje.ebean.util.StringHelper; import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer; public class EscapeJson { + /** + * Unescape the JSON escaped slash character. + */ + public static String unescapeSlash(String value) { + return StringHelper.replaceString(value, "\\/","/"); + } + /** * Escape and quote the string value. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeBaseVarchar.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeBaseVarchar.java index eb63fbd40..e54a325ce 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeBaseVarchar.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeBaseVarchar.java @@ -11,110 +11,108 @@ import com.avaje.ebean.text.json.JsonValueAdapter; import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer; /** - * Base ScalarType for types which converts to and from a VARCHAR database column. + * Base ScalarType for types which converts to and from a VARCHAR database + * column. */ public abstract class ScalarTypeBaseVarchar extends ScalarTypeBase { - public ScalarTypeBaseVarchar(Class type) { - super(type, false, Types.VARCHAR); - } - - public ScalarTypeBaseVarchar(Class type, boolean jdbcNative, int jdbcType) { - super(type, jdbcNative, jdbcType); - } + public ScalarTypeBaseVarchar(Class type) { + super(type, false, Types.VARCHAR); + } - public abstract String formatValue(T v); - - public abstract T parse(String value); - - public abstract T convertFromDbString(String dbValue); - - public abstract String convertToDbString(T beanValue); - - public void bind(DataBind b, T value) throws SQLException { - if (value == null){ - b.setNull(Types.VARCHAR); - - } else { - String s = convertToDbString(value); - b.setString(s); - } - } + public ScalarTypeBaseVarchar(Class type, boolean jdbcNative, int jdbcType) { + super(type, jdbcNative, jdbcType); + } - public T read(DataReader dataReader) throws SQLException { - String s = dataReader.getString(); - if (s == null){ - return null; - } else { - return convertFromDbString(s); - } - } - - @SuppressWarnings("unchecked") - public T toBeanType(Object value) { - if (value == null){ - return null; - } - if (value instanceof String){ - return parse((String)value); - } - return (T)value; - } - - public Object toJdbcType(Object value){ - if (value instanceof String){ - return parse((String)value); - } - return value; - } - - public T parseDateTime(long systemTimeMillis) { - throw new TextException("Not Supported"); - } - - public boolean isDateTimeCapable() { - return false; - } - - @SuppressWarnings("unchecked") - public String format(Object v) { - return formatValue((T) v); - } - - public T jsonFromString(String value, JsonValueAdapter ctx) { - return parse(value); - } + public abstract String formatValue(T v); - @Override - public void jsonWrite(WriteJsonBuffer buffer, T value, JsonValueAdapter ctx) { - String s = format(value); - EscapeJson.escapeQuote(s, buffer); - } + public abstract T parse(String value); - public String toJsonString(Object value, JsonValueAdapter ctx) { - String s = format(value); - return EscapeJson.escapeQuote(s); - } - - public Object readData(DataInput dataInput) throws IOException { - if (!dataInput.readBoolean()) { - return null; - } else { - String val = dataInput.readUTF(); - return convertFromDbString(val); - } - } + public abstract T convertFromDbString(String dbValue); - @SuppressWarnings("unchecked") - public void writeData(DataOutput dataOutput, Object v) throws IOException { - - T value = (T)v; - if (value == null){ - dataOutput.writeBoolean(false); - } else { - dataOutput.writeBoolean(true); - String s = convertToDbString(value); - dataOutput.writeUTF(s); - } + public abstract String convertToDbString(T beanValue); + + public void bind(DataBind b, T value) throws SQLException { + if (value == null) { + b.setNull(Types.VARCHAR); + + } else { + b.setString(convertToDbString(value)); } + } + + public T read(DataReader dataReader) throws SQLException { + String s = dataReader.getString(); + if (s == null) { + return null; + } else { + return convertFromDbString(s); + } + } + + @SuppressWarnings("unchecked") + public T toBeanType(Object value) { + if (value == null) { + return null; + } + if (value instanceof String) { + return parse((String) value); + } + return (T) value; + } + + public Object toJdbcType(Object value) { + if (value instanceof String) { + return parse((String) value); + } + return value; + } + + public T parseDateTime(long systemTimeMillis) { + throw new TextException("Not Supported"); + } + + public boolean isDateTimeCapable() { + return false; + } + + @SuppressWarnings("unchecked") + public String format(Object v) { + return formatValue((T) v); + } + + public T jsonFromString(String value, JsonValueAdapter ctx) { + return parse(EscapeJson.unescapeSlash(value)); + } + + public String toJsonString(Object value, JsonValueAdapter ctx) { + return EscapeJson.escapeQuote(format(value)); + } + + @Override + public void jsonWrite(WriteJsonBuffer buffer, T value, JsonValueAdapter ctx) { + EscapeJson.escapeQuote(format(value), buffer); + } + + public Object readData(DataInput dataInput) throws IOException { + if (!dataInput.readBoolean()) { + return null; + } else { + String val = dataInput.readUTF(); + return convertFromDbString(val); + } + } + + @SuppressWarnings("unchecked") + public void writeData(DataOutput dataOutput, Object v) throws IOException { + + T value = (T) v; + if (value == null) { + dataOutput.writeBoolean(false); + } else { + dataOutput.writeBoolean(true); + String s = convertToDbString(value); + dataOutput.writeUTF(s); + } + } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeTimeZone.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeTimeZone.java index 56fba6696..c29e3ef8c 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeTimeZone.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeTimeZone.java @@ -3,35 +3,36 @@ package com.avaje.ebeaninternal.server.type; import java.util.TimeZone; /** - * ScalarType for java.util.TimeZone which converts to and from a VARCHAR database column. + * ScalarType for java.util.TimeZone which converts to and from a VARCHAR + * database column. */ public class ScalarTypeTimeZone extends ScalarTypeBaseVarchar { - public ScalarTypeTimeZone() { - super(TimeZone.class); - } - - @Override - public int getLength() { - return 20; - } - - @Override - public TimeZone convertFromDbString(String dbValue) { - return TimeZone.getTimeZone(dbValue); - } + public ScalarTypeTimeZone() { + super(TimeZone.class); + } - @Override - public String convertToDbString(TimeZone beanValue) { - return ((TimeZone)beanValue).getID(); - } + @Override + public int getLength() { + return 20; + } - public String formatValue(TimeZone v) { - return v.toString(); - } + @Override + public TimeZone convertFromDbString(String dbValue) { + return TimeZone.getTimeZone(dbValue); + } + + @Override + public String convertToDbString(TimeZone beanValue) { + return ((TimeZone) beanValue).getID(); + } + + public String formatValue(TimeZone v) { + return v.getID(); + } + + public TimeZone parse(String value) { + return TimeZone.getTimeZone(value); + } - public TimeZone parse(String value) { - return TimeZone.getTimeZone(value); - } - } diff --git a/src/test/java/com/avaje/tests/model/basic/BeanWithTimeZone.java b/src/test/java/com/avaje/tests/model/basic/BeanWithTimeZone.java new file mode 100644 index 000000000..7e1210841 --- /dev/null +++ b/src/test/java/com/avaje/tests/model/basic/BeanWithTimeZone.java @@ -0,0 +1,42 @@ +package com.avaje.tests.model.basic; + +import java.util.TimeZone; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class BeanWithTimeZone { + + @Id + Long id; + + String name; + + TimeZone timezone; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public TimeZone getTimezone() { + return timezone; + } + + public void setTimezone(TimeZone timezone) { + this.timezone = timezone; + } + +} diff --git a/src/test/java/com/avaje/tests/model/basic/BeanWithTimezone.java b/src/test/java/com/avaje/tests/model/basic/BeanWithTimezone.java new file mode 100644 index 000000000..132d20e12 --- /dev/null +++ b/src/test/java/com/avaje/tests/model/basic/BeanWithTimezone.java @@ -0,0 +1,42 @@ +package com.avaje.tests.model.basic; + +import java.util.TimeZone; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class BeanWithTimezone { + + @Id + Long id; + + String name; + + TimeZone timezone; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public TimeZone getTimezone() { + return timezone; + } + + public void setTimezone(TimeZone timezone) { + this.timezone = timezone; + } + +} diff --git a/src/test/java/com/avaje/tests/model/basic/SomeEnum.java b/src/test/java/com/avaje/tests/model/basic/SomeEnum.java new file mode 100644 index 000000000..a24d24591 --- /dev/null +++ b/src/test/java/com/avaje/tests/model/basic/SomeEnum.java @@ -0,0 +1,17 @@ +package com.avaje.tests.model.basic; + +public enum SomeEnum { + + ALPHA("Some nice Alpha"), + BETA("Some nice Beta"); + + String description; + + SomeEnum(String description) { + this.description = description; + } + + public String toString() { + return description; + } +} diff --git a/src/test/java/com/avaje/tests/model/basic/SomeEnumBean.java b/src/test/java/com/avaje/tests/model/basic/SomeEnumBean.java new file mode 100644 index 000000000..8611981ec --- /dev/null +++ b/src/test/java/com/avaje/tests/model/basic/SomeEnumBean.java @@ -0,0 +1,42 @@ +package com.avaje.tests.model.basic; + +import javax.persistence.Entity; +import javax.persistence.Enumerated; +import javax.persistence.Id; + +@Entity +public class SomeEnumBean { + + @Id + Long id; + + @Enumerated + SomeEnum someEnum; + + String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public SomeEnum getSomeEnum() { + return someEnum; + } + + public void setSomeEnum(SomeEnum someEnum) { + this.someEnum = someEnum; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/src/test/java/com/avaje/tests/text/json/TestJsonBeanWithTimeZone.java b/src/test/java/com/avaje/tests/text/json/TestJsonBeanWithTimeZone.java new file mode 100644 index 000000000..a1b0894dd --- /dev/null +++ b/src/test/java/com/avaje/tests/text/json/TestJsonBeanWithTimeZone.java @@ -0,0 +1,42 @@ +package com.avaje.tests.text.json; + +import java.util.TimeZone; + +import com.avaje.ebean.Ebean; +import com.avaje.ebean.text.json.JsonContext; +import com.avaje.tests.model.basic.BeanWithTimeZone; + +import junit.framework.TestCase; + +public class TestJsonBeanWithTimeZone extends TestCase { + + public void testSimple() { + + TimeZone defaultTimeZone = TimeZone.getDefault(); + + String[] ids = TimeZone.getAvailableIDs(defaultTimeZone.getRawOffset()); + System.out.println(ids); + + String id = defaultTimeZone.getID(); + TimeZone timeZone = TimeZone.getTimeZone(id); + assertEquals(defaultTimeZone, timeZone); + + BeanWithTimeZone bean = new BeanWithTimeZone(); + bean.setName("foo"); + bean.setTimezone(TimeZone.getDefault()); + + JsonContext jsonContext = Ebean.createJsonContext(); + String jsonContent = jsonContext.toJsonString(bean); + + BeanWithTimeZone bean2 = jsonContext.toBean(BeanWithTimeZone.class, jsonContent); + + assertEquals(bean.getTimezone(), bean2.getTimezone()); + + Ebean.save(bean); + BeanWithTimeZone bean3 = Ebean.find(BeanWithTimeZone.class, bean.getId()); + + assertEquals(bean.getTimezone(), bean3.getTimezone()); + + } + +} diff --git a/src/test/java/com/avaje/tests/text/json/TestJsonSomeEnumWithToString.java b/src/test/java/com/avaje/tests/text/json/TestJsonSomeEnumWithToString.java new file mode 100644 index 000000000..8f0581cae --- /dev/null +++ b/src/test/java/com/avaje/tests/text/json/TestJsonSomeEnumWithToString.java @@ -0,0 +1,31 @@ +package com.avaje.tests.text.json; + +import com.avaje.ebean.Ebean; +import com.avaje.ebean.text.json.JsonContext; +import com.avaje.tests.model.basic.SomeEnum; +import com.avaje.tests.model.basic.SomeEnumBean; + +import junit.framework.TestCase; + +public class TestJsonSomeEnumWithToString extends TestCase { + + public void testJsonConversion() { + + SomeEnumBean bean = new SomeEnumBean(); + bean.setId(100l); + bean.setName("Some name"); + bean.setSomeEnum(SomeEnum.ALPHA); + + JsonContext json = Ebean.createJsonContext(); + String jsonContent = json.toJsonString(bean); + + SomeEnumBean bean2 = json.toBean(SomeEnumBean.class, jsonContent); + + assertEquals(bean.getSomeEnum(), bean2.getSomeEnum()); + assertEquals(bean.getName(), bean2.getName()); + assertEquals(bean.getId(), bean2.getId()); + + } + + +}