Search in sources :

Example 6 with DecimalPrecision

use of siena.core.DecimalPrecision in project siena by mandubian.

the class GoogleSqlPersistenceManager method addParameters.

@Override
protected int addParameters(Object obj, List<Field> fields, PreparedStatement ps, int i) throws SQLException {
    for (Field field : fields) {
        Class<?> type = field.getType();
        if (ClassInfo.isModel(type) && !ClassInfo.isEmbedded(field)) {
            JdbcClassInfo ci = JdbcClassInfo.getClassInfo(type);
            Object rel = Util.readField(obj, field);
            for (Field f : ci.keys) {
                if (rel != null) {
                    Object value = Util.readField(rel, f);
                    if (value instanceof Json)
                        value = ((Json) value).toString();
                    setParameter(ps, i++, value, f);
                } else {
                    setParameter(ps, i++, null, f);
                }
            }
        } else {
            Object value = Util.readField(obj, field);
            if (value != null) {
                if (Json.class.isAssignableFrom(type)) {
                    value = ((Json) value).toString();
                } else if (field.getAnnotation(Embedded.class) != null) {
                    value = JsonSerializer.serialize(value).toString();
                } else if (field.getAnnotation(Polymorphic.class) != null) {
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    ObjectOutput out;
                    try {
                        out = new ObjectOutputStream(bos);
                        out.writeObject(value);
                        out.close();
                    } catch (IOException e) {
                        throw new SienaException(e);
                    }
                    value = bos.toByteArray();
                } else if (Enum.class.isAssignableFrom(type)) {
                    value = value.toString();
                } else if (BigDecimal.class == type) {
                    DecimalPrecision ann = field.getAnnotation(DecimalPrecision.class);
                    if (ann == null) {
                        value = (BigDecimal) value;
                    } else {
                        switch(ann.storageType()) {
                            case DOUBLE:
                                value = ((BigDecimal) value).doubleValue();
                                break;
                            case STRING:
                                value = ((BigDecimal) value).toPlainString();
                                break;
                            case NATIVE:
                                value = (BigDecimal) value;
                                break;
                        }
                    }
                }
            }
            setParameter(ps, i++, value, field);
        }
    }
    return i;
}
Also used : ObjectOutput(java.io.ObjectOutput) DecimalPrecision(siena.core.DecimalPrecision) Json(siena.Json) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ObjectOutputStream(java.io.ObjectOutputStream) Field(java.lang.reflect.Field) SienaException(siena.SienaException) Polymorphic(siena.core.Polymorphic)

Example 7 with DecimalPrecision

use of siena.core.DecimalPrecision in project siena by mandubian.

the class GaeNativeSerializer method embed.

public static void embed(Entity entity, String embeddingColumnName, Object embeddedObj, int level) {
    // the level prevents from stackoverflow in case of a circular ref
    if (level > 2)
        return;
    Class<?> clazz = embeddedObj.getClass();
    if (clazz.isArray() || Collection.class.isAssignableFrom(clazz)) {
        throw new SienaException("can't serializer Array/Collection in native mode");
    }
    for (Field f : ClassInfo.getClassInfo(clazz).allFields) {
        // doesn't try to analyze fields, just try to store it
        Class<?> fieldClass = f.getType();
        String propName = embeddingColumnName + "." + ClassInfo.getSingleColumnName(f);
        Object propValue = Util.readField(embeddedObj, f);
        if (propValue != null) {
            if (fieldClass == Json.class) {
                propValue = propValue.toString();
            } else if (propValue instanceof String) {
                String s = (String) propValue;
                if (s.length() > 500)
                    propValue = new Text(s);
            } else if (propValue instanceof byte[]) {
                byte[] arr = (byte[]) propValue;
                // GAE Blob doesn't accept more than 1MB
                if (arr.length < 1000000)
                    propValue = new Blob(arr);
                else
                    propValue = new Blob(Arrays.copyOf(arr, 1000000));
            } else if (ClassInfo.isEmbedded(f)) {
                Embedded embed = f.getAnnotation(Embedded.class);
                switch(embed.mode()) {
                    case SERIALIZE_JSON:
                        propValue = JsonSerializer.serialize(propValue).toString();
                        String s = (String) propValue;
                        if (s.length() > 500)
                            propValue = new Text(s);
                        break;
                    case SERIALIZE_JAVA:
                        // this embedding mode doesn't manage @EmbedIgnores
                        try {
                            byte[] b = JavaSerializer.serialize(propValue);
                            // if length is less than 1Mb, can store in a blob else???
                            if (b.length <= 1000000) {
                                propValue = new Blob(b);
                            } else {
                                throw new SienaException("object can be java serialized because it's too large >1mb");
                            }
                        } catch (IOException ex) {
                            throw new SienaException(ex);
                        }
                        break;
                    case NATIVE:
                        GaeNativeSerializer.embed(entity, embeddingColumnName + "." + ClassInfo.getSingleColumnName(f), propValue, level + 1);
                        // has set several new properties in entity so go to next field
                        continue;
                }
            } else if (fieldClass == BigDecimal.class) {
                DecimalPrecision ann = f.getAnnotation(DecimalPrecision.class);
                if (ann == null) {
                    propValue = ((BigDecimal) propValue).toPlainString();
                } else {
                    switch(ann.storageType()) {
                        case DOUBLE:
                            propValue = ((BigDecimal) propValue).doubleValue();
                            break;
                        case STRING:
                        case NATIVE:
                            propValue = ((BigDecimal) propValue).toPlainString();
                            break;
                    }
                }
            } else // don't know if anyone will use it but it will work :)
            if (Enum.class.isAssignableFrom(fieldClass)) {
                propValue = propValue.toString();
            } else if (ClassInfo.isModel(fieldClass)) {
                // if it's a model and as there a no join, we can't fetch everything! So only the key is embedded
                //GaeNativeSerializer.embed(entity, embeddingColumnName + "." + ClassInfo.getSingleColumnName(f), propValue, level + 1);
                propValue = Util.readField(propValue, ClassInfo.getIdField(fieldClass));
            }
        }
        Unindexed ui = f.getAnnotation(Unindexed.class);
        if (ui == null) {
            entity.setProperty(propName, propValue);
        } else {
            entity.setUnindexedProperty(propName, propValue);
        }
    }
}
Also used : Blob(com.google.appengine.api.datastore.Blob) DecimalPrecision(siena.core.DecimalPrecision) Text(com.google.appengine.api.datastore.Text) IOException(java.io.IOException) Field(java.lang.reflect.Field) Collection(java.util.Collection) SienaException(siena.SienaException) Embedded(siena.embed.Embedded)

Example 8 with DecimalPrecision

use of siena.core.DecimalPrecision in project siena by mandubian.

the class JdbcMappingUtils method fromObject.

public static Object fromObject(Field field, Object value) {
    Class<?> type = field.getType();
    // in H2 database, mediumtext is mapped to CLOB
    if (Json.class.isAssignableFrom(type) && value != null && java.sql.Clob.class.isAssignableFrom(value.getClass())) {
        java.sql.Clob clob = (java.sql.Clob) value;
        try {
            return Json.load(new BufferedReader(clob.getCharacterStream()));
        } catch (SQLException e) {
            throw new SienaException(e);
        }
    }
    if (field.getAnnotation(Embedded.class) != null && value != null && java.sql.Clob.class.isAssignableFrom(value.getClass())) {
        java.sql.Clob clob = (java.sql.Clob) value;
        try {
            Json data = Json.load(new BufferedReader(clob.getCharacterStream()));
            return JsonSerializer.deserialize(field, data);
        } catch (SQLException e) {
            throw new SienaException(e);
        }
    }
    // issue https://github.com/mandubian/siena/issues/5
    if (value != null && java.sql.Clob.class.isAssignableFrom(value.getClass())) {
        java.sql.Clob clob = (java.sql.Clob) value;
        try {
            // @see http://osdir.com/ml/h2-database/2011-06/msg00170.html
            return clob.getSubString(1, (int) clob.length());
        } catch (SQLException e) {
            throw new SienaException(e);
        }
    }
    if (field.isAnnotationPresent(Polymorphic.class)) {
        try {
            if (java.sql.Blob.class.isAssignableFrom(value.getClass())) {
                java.sql.Blob blob = (java.sql.Blob) value;
                ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(blob.getBytes(0, (int) blob.length())));
                return in.readObject();
            } else {
                ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream((byte[]) value));
                return in.readObject();
            }
        } catch (IOException e) {
            throw new SienaException(e);
        } catch (ClassNotFoundException e) {
            throw new SienaException(e);
        } catch (SQLException e) {
            throw new SienaException(e);
        }
    }
    if (byte[].class == type && value != null && java.sql.Blob.class.isAssignableFrom(value.getClass())) {
        java.sql.Blob blob = (java.sql.Blob) value;
        try {
            // TODO what to do with a very long blob????
            return blob.getBytes(0, (int) blob.length());
        } catch (SQLException e) {
            throw new SienaException(e);
        }
    }
    if (BigDecimal.class == type) {
        DecimalPrecision ann = field.getAnnotation(DecimalPrecision.class);
        if (ann == null) {
            return (BigDecimal) value;
        } else {
            switch(ann.storageType()) {
                case DOUBLE:
                    return BigDecimal.valueOf((Double) value);
                case STRING:
                    return new BigDecimal((String) value);
                case NATIVE:
                    return (BigDecimal) value;
            }
        }
    }
    return Util.fromObject(field, value);
}
Also used : SQLException(java.sql.SQLException) DecimalPrecision(siena.core.DecimalPrecision) Json(siena.Json) IOException(java.io.IOException) BigDecimal(java.math.BigDecimal) ByteArrayInputStream(java.io.ByteArrayInputStream) BufferedReader(java.io.BufferedReader) SienaException(siena.SienaException) Embedded(siena.embed.Embedded) ObjectInputStream(java.io.ObjectInputStream)

Aggregations

DecimalPrecision (siena.core.DecimalPrecision)8 IOException (java.io.IOException)6 SienaException (siena.SienaException)6 Field (java.lang.reflect.Field)5 Json (siena.Json)5 Embedded (siena.embed.Embedded)5 Polymorphic (siena.core.Polymorphic)4 BigDecimal (java.math.BigDecimal)3 SienaRestrictedApiException (siena.SienaRestrictedApiException)3 Blob (com.google.appengine.api.datastore.Blob)2 Text (com.google.appengine.api.datastore.Text)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 ObjectOutput (java.io.ObjectOutput)2 ObjectOutputStream (java.io.ObjectOutputStream)2 DateTime (siena.DateTime)2 SimpleDate (siena.SimpleDate)2 Key (com.google.appengine.api.datastore.Key)1 BufferedReader (java.io.BufferedReader)1 ObjectInputStream (java.io.ObjectInputStream)1