Сериализация/Конвертация в другие объекты
От: Mamut Швеция http://dmitriid.com
Дата: 20.08.10 17:03
Оценка:
Сижу, чешу репу Хочется, как всегда, странного

Есть у нас с одной стороны Java, с другой стороны Erlang (и его библиотеки для инетрфейса с Java'ой).

Со стороны Java String, со стороны Erlang'а — OtpErlangString.
Со стороны Java Integer, со стороны Erlang'а — OtpErlangInt.
ну и т.п.

То есть для передачи чего-то там в Erlang нужно делать что-то типа:
String s = "text";
OtpeErlangString s1 = new OtpErlangString(s);
// куда-то там передаем


На простейших объектах и когда оно делается ручками, оно все понятно. Но хочется слегка автоматизировать процесс То есть если у нас есть

ArrayList arr = new ArrayList();
arr.add("aaa");
arr.add(123);

ArrayList arr2 = new ArrayList();
arr2.add(new ArrayList());

arr.add(arr);


то хочется магического:

ErlangObject eo = new ErlangObject(arr); // из примера выше

eo.get(); // Получем OtpErlangObject, соедржащий OtpErlangList,
          // в котором есть OtpErlangString, OtpErlangInt
          // еще один OtpErlangList и т.п.



неужели нет ничего более удобного чем
if(object instanceof Boolean){
    return OtpErlangBoolean((Boolean)object);
} else if(object instanceof String){
    return OtpErlangString((String)object);
} else if(object instanceof Integer){
    return OtpErlangInt((Integer)object);
} else ...


А если мне все это дело захочется расширить? Например, унаследоваться от этого класса и добавить для сериализации новые типы?

В общем, куда копать


dmitriid.comGitHubLinkedIn
Re: Сериализация/Конвертация в другие объекты
От: kinoman http://pseudo-tech-notes.blogspot.com/
Дата: 22.08.10 20:59
Оценка:
M>В общем, куда копать

Если смотреть на задачу в целом то: написать реализацию на эрланге для protobuf http://code.google.com/p/protobuf/ ? Или найти готовую (хотя я сомневаюсь что оно есть для эрланга).

Впрочем если куски данных гоняются большие (скажем пара мегабайт), то про protobuf можно сразу забыть.
Re: Сериализация/Конвертация в другие объекты
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 23.08.10 05:59
Оценка: 51 (1)
Здравствуйте, Mamut, Вы писали:

M>...


M>неужели нет ничего более удобного чем

M>
M>if(object instanceof Boolean){
M>    return OtpErlangBoolean((Boolean)object);
M>} else if(object instanceof String){
M>    return OtpErlangString((String)object);
M>} else if(object instanceof Integer){
M>    return OtpErlangInt((Integer)object);
M>} else ...
M>


M>А если мне все это дело захочется расширить? Например, унаследоваться от этого класса и добавить для сериализации новые типы?


M>В общем, куда копать



public interface Converter {
    Set<Class<?>> getSupportedClasses();
    <I, O> O convert(I in) throws IllegalArgumentException;
}

public abstract class AbstractErlangJavaConverter<J, E> implements Converter {

    private final Set<Class<?>> classes = new HashSet<Class<?>>();
    private final Class<J> javaClass;
    private final Class<E> erlangClass;

    protected AbstractErlangJavaConverter(Class<J> javaClass, Class<E> erlangClass) {
        this.classes.add(javaClass);
        this.classes.add(erlangClass);
        this.javaClass = javaClass;
        this.erlangClass = erlangClass;
    }

    @Override
    public Set<Class<?>> getSupportedClasses() {
        return classes;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <I, O> convert(I in) throws IllegalArgumentException {
        Class<?> argClass = in.getClass();

        // Exact match.
        if (argClass == javaClass) {
            return fromJava((J)in);
        } else if (argClass == erlangClass()) {
            return fromErlang((E)in);
        }

        // IS-A match.
        if (javaClass.isAssignableFrom(argClass)) {
            return fromJava((J)in)
        } else if (erlangClass.isAssignableFrom(argClass)) {
            return fromErlang((E)in);
        }
        throw new IllegalArgumentException(/* describe supported arguments and given one */)
    }

    protected abstract E fromJava(J in);
    protected abstract J fromErlang(E in);
}

public class BooleanConverter extends AbstractErlangJavaConverter<Boolean, OtpErlangBoolean> {

    public BooleanConverter() {
        super(Boolean.class, OtpErlangBoolean.class);
    }

    public OtpErlangBoolean fromJava(Boolean b) {
        return OtpErlangBoolean((Boolean)object);
    }

    public Boolean toJava(OtpErlangBoolean b) {
        // ...
    }
}

...

public class ConversionManager {

    private final Map<Class<?>, Converter<?, ?>> converters = new HashMap<>();

    @SuppressWarnings("unchecked")
    public <I, O> O convert(I in) throws IllegalArgumentException {
        // Try exact match.
        Converter<I, O> converter = (Converter<I, O>)converters.get(in.getClass());
        if (converter != null {
            return converter.convert(in);
        }

        // Try IS-A match.
        for (Map.Entry<Class<?>, Converter<?, ?>> entry : converters.entrySet()) {
            if (entry.getKey().isAssignableFrom(in.getClass()) {
                return (O)entry.getValue().convert(in);
            }
        }

        throw new IllegalArgumentException(/* describe supported arguments and given one */)
    }

    //@Autowired
    public void register(Converter<?, ?> ... converters) {
        for (Converter<?, ?> converter: converters) {
            for (Class<?> clazz : converter.getSupportedClasses()) {
                if (converters.contains(clazz)) {
                    // handle
                }
                converters.put(clazz, converter);
            }            
        }
    }
}


Т.е. основная идея — разделить движок и стратегии конвертирования. При этом для обобщенного конвертирования со стороны джавы можно использовать рефлекшн, т.е. если во время выполнения ConversionManager.convert() не найдено подходящего конвертера, можно делегировать этому обобщенному.
http://denis-zhdanov.blogspot.com
Re[2]: Сериализация/Конвертация в другие объекты
От: Mamut Швеция http://dmitriid.com
Дата: 23.08.10 06:46
Оценка:
K>Если смотреть на задачу в целом то: написать реализацию на эрланге для protobuf http://code.google.com/p/protobuf/ ? Или найти готовую (хотя я сомневаюсь что оно есть для эрланга).

K>Впрочем если куски данных гоняются большие (скажем пара мегабайт), то про protobuf можно сразу забыть.


Не, через промежуточный слой, конечно, можно, но не хочется


dmitriid.comGitHubLinkedIn
Re[2]: Сериализация/Конвертация в другие объекты
От: Mamut Швеция http://dmitriid.com
Дата: 23.08.10 06:48
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:


DZ>Т.е. основная идея — разделить движок и стратегии конвертирования. При этом для обобщенного конвертирования со стороны джавы можно использовать рефлекшн, т.е. если во время выполнения ConversionManager.convert() не найдено подходящего конвертера, можно делегировать этому обобщенному.


0_O

Спасибо, буду заворачивать мозг вокруг этого кода


dmitriid.comGitHubLinkedIn
Re[2]: Естественно, вопросы :)
От: Mamut Швеция http://dmitriid.com
Дата: 23.08.10 09:02
Оценка:
То, что общий опыт в Java у меня около недели не способствует скорейшему разруливанию ситуации

Возникли вопросы. Вопросы в коде

public class ConversionManager {

// на все Converter<?, ?> : Converter does not have type parameters 
// при замене на  AbstractErlangJavaConverter<?, ?> возникают ошибки ниже 


    private final Map<Class<?>, Converter<?, ?>> converters = new HashMap<>();

    @SuppressWarnings("unchecked")
    public <I, O> O convert(I in) throws IllegalArgumentException {
        // Try exact match.
        Converter<I, O> converter = (Converter<I, O>)converters.get(in.getClass());
        if (converter != null {
//type parameters of <O>O cannot be determined; no unique maximal instance exists
 //for type variable O with upper bounds O,java.lang.Object
            return converter.convert(in);
        }

        // Try IS-A match.
        for (Map.Entry<Class<?>, Converter<?, ?>> entry : converters.entrySet()) {
            if (entry.getKey().isAssignableFrom(in.getClass()) {
                return (O)entry.getValue().convert(in);
            }
        }

        throw new IllegalArgumentException(/* describe supported arguments and given one */)
    }

    //@Autowired
    public void register(Converter<?, ?> ... converters) {
        for (Converter<?, ?> converter: converters) {
            for (Class<?> clazz : converter.getSupportedClasses()) {
//cannot find symbol method contains(java.lang.Class<capture#138 of ?>)
                if (converters.contains(clazz)) {
                    // handle
                }
                converters.put(clazz, converter);
            }            
        }
    }
}


dmitriid.comGitHubLinkedIn
Re[3]: Естественно, вопросы :)
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 23.08.10 09:39
Оценка: 51 (1)
Здравствуйте, Mamut, Вы писали:

M>То, что общий опыт в Java у меня около недели не способствует скорейшему разруливанию ситуации


M>Возникли вопросы. Вопросы в коде


Сорри, писал не в ide, не проверял на компилабельность.

Этот код компилируется под java6:

public interface Converter {
    Set<Class<?>> getSupportedClasses();
    <I, O> O convert(I in) throws IllegalArgumentException;
}

public abstract class AbstractErlangJavaConverter<J, E> implements Converter {

    private final Set<Class<?>> classes = new HashSet<Class<?>>();
    private final Class<J> javaClass;
    private final Class<E> erlangClass;

    protected AbstractErlangJavaConverter(Class<J> javaClass, Class<E> erlangClass) {
        this.classes.add(javaClass);
        this.classes.add(erlangClass);
        this.javaClass = javaClass;
        this.erlangClass = erlangClass;
    }

    @Override
    public Set<Class<?>> getSupportedClasses() {
        return classes;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <I, O> O convert(I in) throws IllegalArgumentException {
        Class<?> argClass = in.getClass();

        // Exact match.
        if (argClass == javaClass) {
            return (O) fromJava((J)in);
        } else if (argClass == erlangClass) {
            return (O) fromErlang((E)in);
        }

        // IS-A match.
        if (javaClass.isAssignableFrom(argClass)) {
            return (O) fromJava((J)in);
        } else if (erlangClass.isAssignableFrom(argClass)) {
            return (O) fromErlang((E)in);
        }
        throw new IllegalArgumentException(/* describe supported arguments and given one */);
    }

    protected abstract E fromJava(J in);
    protected abstract J fromErlang(E in);
}

public class BooleanConverter extends AbstractErlangJavaConverter<Boolean, OtpErlangBoolean> {

    public BooleanConverter() {
        super(Boolean.class, OtpErlangBoolean.class);
    }

    public OtpErlangBoolean fromJava(Boolean b) {
        //TODO implement
        return null;
    }

    @Override
    protected Boolean fromErlang(OtpErlangBoolean in) {
        //TODO implement
        return null;
    }
}


public class ConversionManager {

    private final Map<Class<?>, Converter> converters = new HashMap<Class<?>, Converter>();

    @SuppressWarnings("unchecked")
    public <I, O> O convert(I in) throws IllegalArgumentException {
        // Try exact match.
        Converter converter = converters.get(in.getClass());
        if (converter != null) {
            return converter.<I, O>convert(in);
        }

        // Try IS-A match.
        for (Map.Entry<Class<?>, Converter> entry : converters.entrySet()) {
            if (entry.getKey().isAssignableFrom(in.getClass())) {
                return (O)entry.getValue().convert(in);
            }
        }

        throw new IllegalArgumentException(/* describe supported arguments and given one */);
    }

    //@Autowired
    public void register(Converter ... converters) {
        for (Converter converter: converters) {
            for (Class<?> clazz : converter.getSupportedClasses()) {
                if (this.converters.containsKey(clazz)) {
                    // handle
                }
                this.converters.put(clazz, converter);
            }
        }
    }
}
http://denis-zhdanov.blogspot.com
Re[4]: Естественно, вопросы :)
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 23.08.10 09:43
Оценка: 32 (1)
Здравствуйте, denis.zhdanov, Вы писали:

DZ>Здравствуйте, Mamut, Вы писали:


M>>То, что общий опыт в Java у меня около недели не способствует скорейшему разруливанию ситуации


M>>Возникли вопросы. Вопросы в коде


DZ>Сорри, писал не в ide, не проверял на компилабельность.


DZ>Этот код компилируется под java6:


public abstract class AbstractErlangJavaConverter<J, E> implements Converter {

    private final Set<Class<?>> classes = new HashSet<Class<?>>();
    private final Class<J> javaClass;
    private final Class<E> erlangClass;

    protected AbstractErlangJavaConverter(Class<J> javaClass, Class<E> erlangClass) {
        this.classes.add(javaClass);
        this.classes.add(erlangClass);
        this.javaClass = javaClass;
        this.erlangClass = erlangClass;
    }
...


(на правах саморекламы) — можно не заставлять передавать в конструктор объекты Class явно — их можно выводить в рантайм — тыц
http://denis-zhdanov.blogspot.com
Re[4]: Естественно, вопросы :)
От: Mamut Швеция http://dmitriid.com
Дата: 23.08.10 11:19
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:

DZ>Здравствуйте, Mamut, Вы писали:


M>>То, что общий опыт в Java у меня около недели не способствует скорейшему разруливанию ситуации


M>>Возникли вопросы. Вопросы в коде


DZ>Сорри, писал не в ide, не проверял на компилабельность.


Да ладно И так ошибок было на грамм


DZ>Этот код компилируется под java6:


О!

Сча буду ковырять Спасибо!


dmitriid.comGitHubLinkedIn
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.