# gg-9792 - Fixing DR communication

Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/e8daee31
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/e8daee31
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/e8daee31

Branch: refs/heads/ignite-292
Commit: e8daee318b441a8d381886e700f6d0aab79a0410
Parents: 7cfcaa7
Author: Valentin Kulichenko <vkuliche...@gridgain.com>
Authored: Tue Feb 17 15:46:55 2015 -0800
Committer: Valentin Kulichenko <vkuliche...@gridgain.com>
Committed: Tue Feb 17 15:46:55 2015 -0800

----------------------------------------------------------------------
 .../CommunicationMessageCodeGenerator.java      | 784 ------------------
 .../ignite/codegen/MessageCodeGenerator.java    | 799 +++++++++++++++++++
 .../plugin/IgnitePluginProcessor.java           |  16 +-
 3 files changed, 800 insertions(+), 799 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8daee31/modules/codegen/src/main/java/org/apache/ignite/codegen/CommunicationMessageCodeGenerator.java
----------------------------------------------------------------------
diff --git 
a/modules/codegen/src/main/java/org/apache/ignite/codegen/CommunicationMessageCodeGenerator.java
 
b/modules/codegen/src/main/java/org/apache/ignite/codegen/CommunicationMessageCodeGenerator.java
deleted file mode 100644
index 0aa9482..0000000
--- 
a/modules/codegen/src/main/java/org/apache/ignite/codegen/CommunicationMessageCodeGenerator.java
+++ /dev/null
@@ -1,784 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.codegen;
-
-import org.apache.ignite.internal.*;
-import org.apache.ignite.internal.util.typedef.internal.*;
-import org.apache.ignite.lang.*;
-import org.apache.ignite.plugin.extensions.communication.*;
-import org.jetbrains.annotations.*;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.util.*;
-
-import static java.lang.reflect.Modifier.*;
-
-/**
-* Direct marshallable code generator.
-*/
-public class CommunicationMessageCodeGenerator {
-    /** */
-    private static final Comparator<Field> FIELD_CMP = new Comparator<Field>() 
{
-        @Override public int compare(Field f1, Field f2) {
-            return f1.getName().compareTo(f2.getName());
-        }
-    };
-
-    /** */
-    private static final String SRC_DIR = U.getIgniteHome() + 
"/modules/core/src/main/java";
-
-    /** */
-    private static final Class<?> BASE_CLS = MessageAdapter.class;
-
-    /** */
-    private static final String EMPTY = "";
-
-    /** */
-    private static final String TAB = "    ";
-
-    /** */
-    private static final String BUF_VAR = "buf";
-
-    /** */
-    private static final Map<Class<?>, MessageAdapter.Type> TYPES = 
U.newHashMap(30);
-
-    static {
-        TYPES.put(byte.class, MessageAdapter.Type.BYTE);
-        TYPES.put(Byte.class, MessageAdapter.Type.BYTE);
-        TYPES.put(short.class, MessageAdapter.Type.SHORT);
-        TYPES.put(Short.class, MessageAdapter.Type.SHORT);
-        TYPES.put(int.class, MessageAdapter.Type.INT);
-        TYPES.put(Integer.class, MessageAdapter.Type.INT);
-        TYPES.put(long.class, MessageAdapter.Type.LONG);
-        TYPES.put(Long.class, MessageAdapter.Type.LONG);
-        TYPES.put(float.class, MessageAdapter.Type.FLOAT);
-        TYPES.put(Float.class, MessageAdapter.Type.FLOAT);
-        TYPES.put(double.class, MessageAdapter.Type.DOUBLE);
-        TYPES.put(Double.class, MessageAdapter.Type.DOUBLE);
-        TYPES.put(char.class, MessageAdapter.Type.CHAR);
-        TYPES.put(Character.class, MessageAdapter.Type.CHAR);
-        TYPES.put(boolean.class, MessageAdapter.Type.BOOLEAN);
-        TYPES.put(Boolean.class, MessageAdapter.Type.BOOLEAN);
-        TYPES.put(byte[].class, MessageAdapter.Type.BYTE_ARR);
-        TYPES.put(short[].class, MessageAdapter.Type.SHORT_ARR);
-        TYPES.put(int[].class, MessageAdapter.Type.INT_ARR);
-        TYPES.put(long[].class, MessageAdapter.Type.LONG_ARR);
-        TYPES.put(float[].class, MessageAdapter.Type.FLOAT_ARR);
-        TYPES.put(double[].class, MessageAdapter.Type.DOUBLE_ARR);
-        TYPES.put(char[].class, MessageAdapter.Type.CHAR_ARR);
-        TYPES.put(boolean[].class, MessageAdapter.Type.BOOLEAN_ARR);
-        TYPES.put(String.class, MessageAdapter.Type.STRING);
-        TYPES.put(BitSet.class, MessageAdapter.Type.BIT_SET);
-        TYPES.put(UUID.class, MessageAdapter.Type.UUID);
-        TYPES.put(IgniteUuid.class, MessageAdapter.Type.IGNITE_UUID);
-    }
-
-    /**
-     * @param cls Class.
-     * @return Type enum value.
-     */
-    private static MessageAdapter.Type typeEnum(Class<?> cls) {
-        MessageAdapter.Type type = TYPES.get(cls);
-
-        if (type == null) {
-            assert MessageAdapter.class.isAssignableFrom(cls) : cls;
-
-            type = MessageAdapter.Type.MSG;
-        }
-
-        return type;
-    }
-
-    /** */
-    private final Collection<String> write = new ArrayList<>();
-
-    /** */
-    private final Collection<String> read = new ArrayList<>();
-
-    /** */
-    private final Map<Class<?>, Integer> fieldCnt = new HashMap<>();
-
-    /** */
-    private List<Field> fields;
-
-    /** */
-    private int indent;
-
-    /**
-     * @param args Arguments.
-     * @throws Exception In case of error.
-     */
-    public static void main(String[] args) throws Exception {
-        CommunicationMessageCodeGenerator gen = new 
CommunicationMessageCodeGenerator();
-
-        gen.generateAll(true);
-
-//        gen.generateAndWrite(GridDistributedLockRequest.class);
-//        gen.generateAndWrite(GridDistributedLockResponse.class);
-//        gen.generateAndWrite(GridNearLockRequest.class);
-//        gen.generateAndWrite(GridNearLockResponse.class);
-//        gen.generateAndWrite(GridDhtLockRequest.class);
-//        gen.generateAndWrite(GridDhtLockResponse.class);
-//
-//        gen.generateAndWrite(GridDistributedTxPrepareRequest.class);
-//        gen.generateAndWrite(GridDistributedTxPrepareResponse.class);
-//        gen.generateAndWrite(GridNearTxPrepareRequest.class);
-//        gen.generateAndWrite(GridNearTxPrepareResponse.class);
-//        gen.generateAndWrite(GridDhtTxPrepareRequest.class);
-//        gen.generateAndWrite(GridDhtTxPrepareResponse.class);
-//
-//        gen.generateAndWrite(GridDistributedTxFinishRequest.class);
-//        gen.generateAndWrite(GridDistributedTxFinishResponse.class);
-//        gen.generateAndWrite(GridNearTxFinishRequest.class);
-//        gen.generateAndWrite(GridNearTxFinishResponse.class);
-//        gen.generateAndWrite(GridDhtTxFinishRequest.class);
-//        gen.generateAndWrite(GridDhtTxFinishResponse.class);
-//
-//        
gen.generateAndWrite(GridCacheOptimisticCheckPreparedTxRequest.class);
-//        
gen.generateAndWrite(GridCacheOptimisticCheckPreparedTxResponse.class);
-    }
-
-    /**
-     * Generates code for all classes.
-     *
-     * @param write Whether to write to file.
-     * @throws Exception In case of error.
-     */
-    public void generateAll(boolean write) throws Exception {
-        Collection<Class<? extends MessageAdapter>> classes = classes();
-
-        for (Class<? extends MessageAdapter> cls : classes) {
-            boolean isAbstract = Modifier.isAbstract(cls.getModifiers());
-
-            System.out.println("Processing class: " + cls.getName() + 
(isAbstract ? " (abstract)" : ""));
-
-            if (write)
-                generateAndWrite(cls);
-            else
-                generate(cls);
-        }
-    }
-
-    /**
-     * Generates code for provided class and writes it to source file.
-     * Note: this method must be called only from {@code generateAll(boolean)}
-     * and only with updating {@code CLASSES_ORDER_FILE} and other auto 
generated files.
-     *
-     * @param cls Class.
-     * @throws Exception In case of error.
-     */
-    @SuppressWarnings("ConstantConditions")
-    public void generateAndWrite(Class<? extends MessageAdapter> cls) throws 
Exception {
-        assert cls != null;
-
-        generate(cls);
-
-        File file = new File(SRC_DIR, cls.getName().replace('.', 
File.separatorChar) + ".java");
-
-        if (!file.exists() || !file.isFile()) {
-            System.out.println("    Source file not found: " + file.getPath());
-
-            return;
-        }
-
-        Collection<String> src = new ArrayList<>();
-
-        BufferedReader rdr = null;
-
-        try {
-            rdr = new BufferedReader(new FileReader(file));
-
-            String line;
-            boolean skip = false;
-
-            boolean writeFound = false;
-            boolean readFound = false;
-
-            while ((line = rdr.readLine()) != null) {
-                if (!skip) {
-                    src.add(line);
-
-                    if (line.contains("public boolean writeTo(ByteBuffer buf, 
MessageWriter writer)")) {
-                        src.addAll(write);
-
-                        skip = true;
-
-                        writeFound = true;
-                    }
-                    else if (line.contains("public boolean readFrom(ByteBuffer 
buf)")) {
-                        src.addAll(read);
-
-                        skip = true;
-
-                        readFound = true;
-                    }
-                }
-                else if (line.startsWith(TAB + "}")) {
-                    src.add(line);
-
-                    skip = false;
-                }
-            }
-
-            if (!writeFound)
-                System.out.println("    writeTo method doesn't exist.");
-
-            if (!readFound)
-                System.out.println("    readFrom method doesn't exist.");
-        }
-        finally {
-            if (rdr != null)
-                rdr.close();
-        }
-
-        BufferedWriter wr = null;
-
-        try {
-            wr = new BufferedWriter(new FileWriter(file));
-
-            for (String line : src)
-                wr.write(line + '\n');
-        }
-        finally {
-            if (wr != null)
-                wr.close();
-        }
-    }
-
-    /**
-     * Generates code for provided class.
-     *
-     * @param cls Class.
-     * @throws Exception In case of error.
-     */
-    private void generate(Class<? extends MessageAdapter> cls) throws 
Exception {
-        assert cls != null;
-
-        write.clear();
-        read.clear();
-
-        fields = new ArrayList<>();
-
-        Field[] declaredFields = cls.getDeclaredFields();
-
-        for (Field field : declaredFields) {
-            int mod = field.getModifiers();
-
-            if (!isStatic(mod) && !isTransient(mod) && 
!field.isAnnotationPresent(GridDirectTransient.class))
-                fields.add(field);
-        }
-
-        Collections.sort(fields, FIELD_CMP);
-
-        indent = 2;
-
-        boolean hasSuper = cls.getSuperclass() != BASE_CLS;
-
-        start(write, hasSuper ? "writeTo" : null, true);
-        start(read, hasSuper ? "readFrom" : null, false);
-
-        indent++;
-
-        int state = startState(cls);
-
-        for (Field field : fields)
-            processField(field, state++);
-
-        indent--;
-
-        finish(write);
-        finish(read);
-    }
-
-    /**
-     * @param cls Message class.
-     * @return Start state.
-     */
-    private int startState(Class<?> cls) {
-        assert cls != null;
-
-        Class<?> superCls = cls.getSuperclass();
-
-        Integer state = fieldCnt.get(superCls);
-
-        if (state != null)
-            return state;
-
-        state = 0;
-
-        while (cls.getSuperclass() != BASE_CLS) {
-            cls = cls.getSuperclass();
-
-            for (Field field : cls.getDeclaredFields()) {
-                int mod = field.getModifiers();
-
-                if (!isStatic(mod) && !isTransient(mod) && 
!field.isAnnotationPresent(GridDirectTransient.class))
-                    state++;
-            }
-        }
-
-        fieldCnt.put(superCls, state);
-
-        return state;
-    }
-
-    /**
-     * @param code Code lines.
-     * @param superMtd Super class method name.
-     * @param write Whether write code is generated.
-     */
-    private void start(Collection<String> code, @Nullable String superMtd, 
boolean write) {
-        assert code != null;
-
-        code.add(builder().a(write ? "writer" : 
"reader").a(".setBuffer(").a(BUF_VAR).a(");").toString());
-        code.add(EMPTY);
-
-        if (superMtd != null) {
-            if (write)
-                returnFalseIfFailed(code, "super." + superMtd, BUF_VAR, 
"writer");
-            else
-                returnFalseIfFailed(code, "super." + superMtd, BUF_VAR);
-
-            code.add(EMPTY);
-        }
-
-        if (write) {
-            code.add(builder().a("if (!writer.isTypeWritten()) {").toString());
-
-            indent++;
-
-            returnFalseIfFailed(code, "writer.writeByte", "null", 
"directType()");
-
-            code.add(EMPTY);
-            code.add(builder().a("writer.onTypeWritten();").toString());
-
-            indent--;
-
-            code.add(builder().a("}").toString());
-            code.add(EMPTY);
-        }
-
-        if (!fields.isEmpty())
-            code.add(builder().a("switch (").a(write ? "writer.state()" : 
"readState").a(") {").toString());
-    }
-
-    /**
-     * @param code Code lines.
-     */
-    private void finish(Collection<String> code) {
-        assert code != null;
-
-        if (!fields.isEmpty()) {
-            code.add(builder().a("}").toString());
-            code.add(EMPTY);
-        }
-
-        code.add(builder().a("return true;").toString());
-    }
-
-    /**
-     * @param field Field.
-     * @param opt Case option.
-     */
-    private void processField(Field field, int opt) {
-        assert field != null;
-        assert opt >= 0;
-
-        GridDirectCollection colAnn = 
field.getAnnotation(GridDirectCollection.class);
-        GridDirectMap mapAnn = field.getAnnotation(GridDirectMap.class);
-
-        if (colAnn == null && 
Collection.class.isAssignableFrom(field.getType()))
-            throw new IllegalStateException("@GridDirectCollection annotation 
is not provided for field: " +
-                field.getName());
-
-        if (mapAnn == null && Map.class.isAssignableFrom(field.getType()))
-            throw new IllegalStateException("@GridDirectMap annotation is not 
provided for field: " + field.getName());
-
-        writeField(field, opt, colAnn, mapAnn);
-        readField(field, opt, colAnn, mapAnn);
-    }
-
-    /**
-     * @param field Field.
-     * @param opt Case option.
-     * @param colAnn Collection annotation.
-     * @param mapAnn Map annotation.
-     */
-    private void writeField(Field field, int opt, @Nullable 
GridDirectCollection colAnn,
-        @Nullable GridDirectMap mapAnn) {
-        assert field != null;
-        assert opt >= 0;
-
-        write.add(builder().a("case ").a(opt).a(":").toString());
-
-        indent++;
-
-        returnFalseIfWriteFailed(field.getType(), field.getName(), colAnn != 
null ? colAnn.value() : null,
-            mapAnn != null ? mapAnn.keyType() : null, mapAnn != null ? 
mapAnn.valueType() : null, false);
-
-        write.add(EMPTY);
-        write.add(builder().a("writer.incrementState();").toString());
-        write.add(EMPTY);
-
-        indent--;
-    }
-
-    /**
-     * @param field Field.
-     * @param opt Case option.
-     * @param colAnn Collection annotation.
-     * @param mapAnn Map annotation.
-     */
-    private void readField(Field field, int opt, @Nullable 
GridDirectCollection colAnn,
-        @Nullable GridDirectMap mapAnn) {
-        assert field != null;
-        assert opt >= 0;
-
-        read.add(builder().a("case ").a(opt).a(":").toString());
-
-        indent++;
-
-        returnFalseIfReadFailed(field.getType(), field.getName(), colAnn != 
null ? colAnn.value() : null,
-            mapAnn != null ? mapAnn.keyType() : null, mapAnn != null ? 
mapAnn.valueType() : null);
-
-        read.add(EMPTY);
-        read.add(builder().a("readState++;").toString());
-        read.add(EMPTY);
-
-        indent--;
-    }
-
-    /**
-     * @param type Field type.
-     * @param name Field name.
-     * @param colItemType Collection item type.
-     * @param mapKeyType Map key type.
-     * @param mapValType Map key value.
-     * @param raw Raw write flag.
-     */
-    private void returnFalseIfWriteFailed(Class<?> type, String name, 
@Nullable Class<?> colItemType,
-        @Nullable Class<?> mapKeyType, @Nullable Class<?> mapValType, boolean 
raw) {
-        assert type != null;
-        assert name != null;
-
-        String field = raw ? "null" : '"' + name + '"';
-
-        if (type == byte.class)
-            returnFalseIfFailed(write, "writer.writeByte", field, name);
-        else if (type == short.class)
-            returnFalseIfFailed(write, "writer.writeShort", field, name);
-        else if (type == int.class)
-            returnFalseIfFailed(write, "writer.writeInt", field, name);
-        else if (type == long.class)
-            returnFalseIfFailed(write, "writer.writeLong", field, name);
-        else if (type == float.class)
-            returnFalseIfFailed(write, "writer.writeFloat", field, name);
-        else if (type == double.class)
-            returnFalseIfFailed(write, "writer.writeDouble", field, name);
-        else if (type == char.class)
-            returnFalseIfFailed(write, "writer.writeChar", field, name);
-        else if (type == boolean.class)
-            returnFalseIfFailed(write, "writer.writeBoolean", field, name);
-        else if (type == byte[].class)
-            returnFalseIfFailed(write, "writer.writeByteArray", field, name);
-        else if (type == short[].class)
-            returnFalseIfFailed(write, "writer.writeShortArray", field, name);
-        else if (type == int[].class)
-            returnFalseIfFailed(write, "writer.writeIntArray", field, name);
-        else if (type == long[].class)
-            returnFalseIfFailed(write, "writer.writeLongArray", field, name);
-        else if (type == float[].class)
-            returnFalseIfFailed(write, "writer.writeFloatArray", field, name);
-        else if (type == double[].class)
-            returnFalseIfFailed(write, "writer.writeDoubleArray", field, name);
-        else if (type == char[].class)
-            returnFalseIfFailed(write, "writer.writeCharArray", field, name);
-        else if (type == boolean[].class)
-            returnFalseIfFailed(write, "writer.writeBooleanArray", field, 
name);
-        else if (type == String.class)
-            returnFalseIfFailed(write, "writer.writeString", field, name);
-        else if (type == BitSet.class)
-            returnFalseIfFailed(write, "writer.writeBitSet", field, name);
-        else if (type == UUID.class)
-            returnFalseIfFailed(write, "writer.writeUuid", field, name);
-        else if (type == IgniteUuid.class)
-            returnFalseIfFailed(write, "writer.writeIgniteUuid", field, name);
-        else if (type.isEnum()) {
-            String arg = name + " != null ? (byte)" + name + ".ordinal() : -1";
-
-            returnFalseIfFailed(write, "writer.writeByte", field, arg);
-        }
-        else if (BASE_CLS.isAssignableFrom(type))
-            returnFalseIfFailed(write, "writer.writeMessage", field, name);
-        else if (type.isArray()) {
-            returnFalseIfFailed(write, "writer.writeObjectArray", field, name,
-                "Type." + typeEnum(type.getComponentType()));
-        }
-        else if (Collection.class.isAssignableFrom(type) && 
!Set.class.isAssignableFrom(type)) {
-            assert colItemType != null;
-
-            returnFalseIfFailed(write, "writer.writeCollection", field, name, 
"Type." + typeEnum(colItemType));
-        }
-        else if (Map.class.isAssignableFrom(type)) {
-            assert mapKeyType != null;
-            assert mapValType != null;
-
-            returnFalseIfFailed(write, "writer.writeMap", field, name, "Type." 
+ typeEnum(mapKeyType),
-                "Type." + typeEnum(mapValType));
-        }
-        else
-            throw new IllegalStateException("Unsupported type: " + type);
-    }
-
-    /**
-     * @param type Field type.
-     * @param name Field name.
-     * @param colItemType Collection item type.
-     * @param mapKeyType Map key type.
-     * @param mapValType Map value type.
-     */
-    private void returnFalseIfReadFailed(Class<?> type, @Nullable String name, 
@Nullable Class<?> colItemType,
-        @Nullable Class<?> mapKeyType, @Nullable Class<?> mapValType) {
-        assert type != null;
-
-        String field = '"' + name + '"';
-
-        if (type == byte.class)
-            returnFalseIfReadFailed(name, "reader.readByte", field);
-        else if (type == short.class)
-            returnFalseIfReadFailed(name, "reader.readShort", field);
-        else if (type == int.class)
-            returnFalseIfReadFailed(name, "reader.readInt", field);
-        else if (type == long.class)
-            returnFalseIfReadFailed(name, "reader.readLong", field);
-        else if (type == float.class)
-            returnFalseIfReadFailed(name, "reader.readFloat", field);
-        else if (type == double.class)
-            returnFalseIfReadFailed(name, "reader.readDouble", field);
-        else if (type == char.class)
-            returnFalseIfReadFailed(name, "reader.readChar", field);
-        else if (type == boolean.class)
-            returnFalseIfReadFailed(name, "reader.readBoolean", field);
-        else if (type == byte[].class)
-            returnFalseIfReadFailed(name, "reader.readByteArray", field);
-        else if (type == short[].class)
-            returnFalseIfReadFailed(name, "reader.readShortArray", field);
-        else if (type == int[].class)
-            returnFalseIfReadFailed(name, "reader.readIntArray", field);
-        else if (type == long[].class)
-            returnFalseIfReadFailed(name, "reader.readLongArray", field);
-        else if (type == float[].class)
-            returnFalseIfReadFailed(name, "reader.readFloatArray", field);
-        else if (type == double[].class)
-            returnFalseIfReadFailed(name, "reader.readDoubleArray", field);
-        else if (type == char[].class)
-            returnFalseIfReadFailed(name, "reader.readCharArray", field);
-        else if (type == boolean[].class)
-            returnFalseIfReadFailed(name, "reader.readBooleanArray", field);
-        else if (type == String.class)
-            returnFalseIfReadFailed(name, "reader.readString", field);
-        else if (type == BitSet.class)
-            returnFalseIfReadFailed(name, "reader.readBitSet", field);
-        else if (type == UUID.class)
-            returnFalseIfReadFailed(name, "reader.readUuid", field);
-        else if (type == IgniteUuid.class)
-            returnFalseIfReadFailed(name, "reader.readIgniteUuid", field);
-        else if (type.isEnum()) {
-            String loc = name + "Ord";
-
-            read.add(builder().a("byte ").a(loc).a(";").toString());
-            read.add(EMPTY);
-
-            returnFalseIfReadFailed(loc, "reader.readByte", field);
-
-            read.add(EMPTY);
-            read.add(builder().a(name).a(" = 
").a(type.getSimpleName()).a(".fromOrdinal(").a(loc).a(");").toString());
-        }
-        else if (BASE_CLS.isAssignableFrom(type))
-            returnFalseIfReadFailed(name, "reader.readMessage", field);
-        else if (type.isArray()) {
-            Class<?> compType = type.getComponentType();
-
-            returnFalseIfReadFailed(name, "reader.readObjectArray", field, 
"Type." + typeEnum(compType),
-                compType.getSimpleName() + ".class");
-        }
-        else if (Collection.class.isAssignableFrom(type) && 
!Set.class.isAssignableFrom(type)) {
-            assert colItemType != null;
-
-            returnFalseIfReadFailed(name, "reader.readCollection", field, 
"Type." + typeEnum(colItemType));
-        }
-        else if (Map.class.isAssignableFrom(type)) {
-            assert mapKeyType != null;
-            assert mapValType != null;
-
-            boolean linked = type.equals(LinkedHashMap.class);
-
-            returnFalseIfReadFailed(name, "reader.readMap", field, "Type." + 
typeEnum(mapKeyType),
-                "Type." + typeEnum(mapValType), linked ? "true" : "false");
-        }
-        else
-            throw new IllegalStateException("Unsupported type: " + type);
-    }
-
-    /**
-     * @param var Variable name.
-     * @param mtd Method name.
-     * @param args Method arguments.
-     */
-    private void returnFalseIfReadFailed(String var, String mtd, @Nullable 
String... args) {
-        assert mtd != null;
-
-        String argsStr = "";
-
-        if (args != null && args.length > 0) {
-            for (String arg : args)
-                argsStr += arg + ", ";
-
-            argsStr = argsStr.substring(0, argsStr.length() - 2);
-        }
-
-        read.add(builder().a(var).a(" = 
").a(mtd).a("(").a(argsStr).a(");").toString());
-        read.add(EMPTY);
-
-        read.add(builder().a("if (!reader.isLastRead())").toString());
-
-        indent++;
-
-        read.add(builder().a("return false;").toString());
-
-        indent--;
-    }
-
-    /**
-     * @param code Code lines.
-     * @param accessor Field or method name.
-     * @param args Method arguments.
-     */
-    private void returnFalseIfFailed(Collection<String> code, String accessor, 
@Nullable String... args) {
-        assert code != null;
-        assert accessor != null;
-
-        String argsStr = "";
-
-        if (args != null && args.length > 0) {
-            for (String arg : args)
-                argsStr += arg + ", ";
-
-            argsStr = argsStr.substring(0, argsStr.length() - 2);
-        }
-
-        code.add(builder().a("if 
(!").a(accessor).a("(").a(argsStr).a("))").toString());
-
-        indent++;
-
-        code.add(builder().a("return false;").toString());
-
-        indent--;
-    }
-
-    /**
-     * Creates new builder with correct indent.
-     *
-     * @return Builder.
-     */
-    private SB builder() {
-        assert indent > 0;
-
-        SB sb = new SB();
-
-        for (int i = 0; i < indent; i++)
-            sb.a(TAB);
-
-        return sb;
-    }
-
-    /**
-     * Gets all direct marshallable classes.
-     * First classes will be classes from {@code classesOrder} with same order
-     * as ordered values. Other classes will be at the end and ordered by name
-     * (with package prefix).
-     * That orders need for saving {@code directType} value.
-     *
-     * @return Classes.
-     * @throws Exception In case of error.
-     */
-    private Collection<Class<? extends MessageAdapter>> classes() throws 
Exception {
-        Collection<Class<? extends MessageAdapter>> col = new TreeSet<>(
-            new Comparator<Class<? extends MessageAdapter>>() {
-                @Override public int compare(Class<? extends MessageAdapter> 
c1,
-                    Class<? extends MessageAdapter> c2) {
-                    return c1.getName().compareTo(c2.getName());
-                }
-            });
-
-        URLClassLoader ldr = (URLClassLoader)getClass().getClassLoader();
-
-        for (URL url : ldr.getURLs()) {
-            File file = new File(url.toURI());
-
-            int prefixLen = file.getPath().length() + 1;
-
-            processFile(file, ldr, prefixLen, col);
-        }
-
-        return col;
-    }
-
-    /**
-     * Recursively process provided file or directory.
-     *
-     * @param file File.
-     * @param ldr Class loader.
-     * @param prefixLen Path prefix length.
-     * @param col Classes.
-     * @throws Exception In case of error.
-     */
-    @SuppressWarnings("unchecked")
-    private void processFile(File file, ClassLoader ldr, int prefixLen,
-        Collection<Class<? extends MessageAdapter>> col) throws Exception {
-        assert file != null;
-        assert ldr != null;
-        assert prefixLen > 0;
-        assert col != null;
-
-        if (!file.exists())
-            throw new FileNotFoundException("File doesn't exist: " + file);
-
-        if (file.isDirectory()) {
-            for (File f : file.listFiles())
-                processFile(f, ldr, prefixLen, col);
-        }
-        else {
-            assert file.isFile();
-
-            String path = file.getPath();
-
-            if (path.endsWith(".class")) {
-                String clsName = path.substring(prefixLen, path.length() - 
6).replace(File.separatorChar, '.');
-
-                Class<?> cls = Class.forName(clsName, false, ldr);
-
-                if (cls.getDeclaringClass() == null && cls.getEnclosingClass() 
== null &&
-                    !BASE_CLS.equals(cls) && BASE_CLS.isAssignableFrom(cls))
-                    col.add((Class<? extends MessageAdapter>)cls);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8daee31/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
----------------------------------------------------------------------
diff --git 
a/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
 
b/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
new file mode 100644
index 0000000..169aeb9
--- /dev/null
+++ 
b/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
@@ -0,0 +1,799 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.codegen;
+
+import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.plugin.extensions.communication.*;
+import org.jetbrains.annotations.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+
+import static java.lang.reflect.Modifier.*;
+
+/**
+* Direct marshallable code generator.
+*/
+public class MessageCodeGenerator {
+    /** */
+    private static final Comparator<Field> FIELD_CMP = new Comparator<Field>() 
{
+        @Override public int compare(Field f1, Field f2) {
+            return f1.getName().compareTo(f2.getName());
+        }
+    };
+
+    /** */
+    private static final String DFLT_SRC_DIR = U.getIgniteHome() + 
"/modules/core/src/main/java";
+
+    /** */
+    private static final Class<?> BASE_CLS = MessageAdapter.class;
+
+    /** */
+    private static final String EMPTY = "";
+
+    /** */
+    private static final String TAB = "    ";
+
+    /** */
+    private static final String BUF_VAR = "buf";
+
+    /** */
+    private static final Map<Class<?>, MessageAdapter.Type> TYPES = 
U.newHashMap(30);
+
+    static {
+        TYPES.put(byte.class, MessageAdapter.Type.BYTE);
+        TYPES.put(Byte.class, MessageAdapter.Type.BYTE);
+        TYPES.put(short.class, MessageAdapter.Type.SHORT);
+        TYPES.put(Short.class, MessageAdapter.Type.SHORT);
+        TYPES.put(int.class, MessageAdapter.Type.INT);
+        TYPES.put(Integer.class, MessageAdapter.Type.INT);
+        TYPES.put(long.class, MessageAdapter.Type.LONG);
+        TYPES.put(Long.class, MessageAdapter.Type.LONG);
+        TYPES.put(float.class, MessageAdapter.Type.FLOAT);
+        TYPES.put(Float.class, MessageAdapter.Type.FLOAT);
+        TYPES.put(double.class, MessageAdapter.Type.DOUBLE);
+        TYPES.put(Double.class, MessageAdapter.Type.DOUBLE);
+        TYPES.put(char.class, MessageAdapter.Type.CHAR);
+        TYPES.put(Character.class, MessageAdapter.Type.CHAR);
+        TYPES.put(boolean.class, MessageAdapter.Type.BOOLEAN);
+        TYPES.put(Boolean.class, MessageAdapter.Type.BOOLEAN);
+        TYPES.put(byte[].class, MessageAdapter.Type.BYTE_ARR);
+        TYPES.put(short[].class, MessageAdapter.Type.SHORT_ARR);
+        TYPES.put(int[].class, MessageAdapter.Type.INT_ARR);
+        TYPES.put(long[].class, MessageAdapter.Type.LONG_ARR);
+        TYPES.put(float[].class, MessageAdapter.Type.FLOAT_ARR);
+        TYPES.put(double[].class, MessageAdapter.Type.DOUBLE_ARR);
+        TYPES.put(char[].class, MessageAdapter.Type.CHAR_ARR);
+        TYPES.put(boolean[].class, MessageAdapter.Type.BOOLEAN_ARR);
+        TYPES.put(String.class, MessageAdapter.Type.STRING);
+        TYPES.put(BitSet.class, MessageAdapter.Type.BIT_SET);
+        TYPES.put(UUID.class, MessageAdapter.Type.UUID);
+        TYPES.put(IgniteUuid.class, MessageAdapter.Type.IGNITE_UUID);
+    }
+
+    /**
+     * @param cls Class.
+     * @return Type enum value.
+     */
+    private static MessageAdapter.Type typeEnum(Class<?> cls) {
+        MessageAdapter.Type type = TYPES.get(cls);
+
+        if (type == null) {
+            assert MessageAdapter.class.isAssignableFrom(cls) : cls;
+
+            type = MessageAdapter.Type.MSG;
+        }
+
+        return type;
+    }
+
+    /** */
+    private final Collection<String> write = new ArrayList<>();
+
+    /** */
+    private final Collection<String> read = new ArrayList<>();
+
+    /** */
+    private final Map<Class<?>, Integer> fieldCnt = new HashMap<>();
+
+    /** */
+    private final String srcDir;
+
+    /** */
+    private List<Field> fields;
+
+    /** */
+    private int indent;
+
+    /**
+     * @param args Arguments.
+     * @throws Exception In case of error.
+     */
+    public static void main(String[] args) throws Exception {
+        String srcDir = DFLT_SRC_DIR;
+
+        if (args != null && args.length > 0)
+            srcDir = args[0];
+
+        MessageCodeGenerator gen = new MessageCodeGenerator(srcDir);
+
+        gen.generateAll(true);
+
+//        gen.generateAndWrite(GridDistributedLockRequest.class);
+//        gen.generateAndWrite(GridDistributedLockResponse.class);
+//        gen.generateAndWrite(GridNearLockRequest.class);
+//        gen.generateAndWrite(GridNearLockResponse.class);
+//        gen.generateAndWrite(GridDhtLockRequest.class);
+//        gen.generateAndWrite(GridDhtLockResponse.class);
+//
+//        gen.generateAndWrite(GridDistributedTxPrepareRequest.class);
+//        gen.generateAndWrite(GridDistributedTxPrepareResponse.class);
+//        gen.generateAndWrite(GridNearTxPrepareRequest.class);
+//        gen.generateAndWrite(GridNearTxPrepareResponse.class);
+//        gen.generateAndWrite(GridDhtTxPrepareRequest.class);
+//        gen.generateAndWrite(GridDhtTxPrepareResponse.class);
+//
+//        gen.generateAndWrite(GridDistributedTxFinishRequest.class);
+//        gen.generateAndWrite(GridDistributedTxFinishResponse.class);
+//        gen.generateAndWrite(GridNearTxFinishRequest.class);
+//        gen.generateAndWrite(GridNearTxFinishResponse.class);
+//        gen.generateAndWrite(GridDhtTxFinishRequest.class);
+//        gen.generateAndWrite(GridDhtTxFinishResponse.class);
+//
+//        
gen.generateAndWrite(GridCacheOptimisticCheckPreparedTxRequest.class);
+//        
gen.generateAndWrite(GridCacheOptimisticCheckPreparedTxResponse.class);
+    }
+
+    /**
+     * @param srcDir Source directory.
+     */
+    public MessageCodeGenerator(String srcDir) {
+        this.srcDir = srcDir;
+    }
+
+    /**
+     * Generates code for all classes.
+     *
+     * @param write Whether to write to file.
+     * @throws Exception In case of error.
+     */
+    public void generateAll(boolean write) throws Exception {
+        Collection<Class<? extends MessageAdapter>> classes = classes();
+
+        for (Class<? extends MessageAdapter> cls : classes) {
+            boolean isAbstract = Modifier.isAbstract(cls.getModifiers());
+
+            System.out.println("Processing class: " + cls.getName() + 
(isAbstract ? " (abstract)" : ""));
+
+            if (write)
+                generateAndWrite(cls);
+            else
+                generate(cls);
+        }
+    }
+
+    /**
+     * Generates code for provided class and writes it to source file.
+     * Note: this method must be called only from {@code generateAll(boolean)}
+     * and only with updating {@code CLASSES_ORDER_FILE} and other auto 
generated files.
+     *
+     * @param cls Class.
+     * @throws Exception In case of error.
+     */
+    @SuppressWarnings("ConstantConditions")
+    public void generateAndWrite(Class<? extends MessageAdapter> cls) throws 
Exception {
+        assert cls != null;
+
+        generate(cls);
+
+        File file = new File(srcDir, cls.getName().replace('.', 
File.separatorChar) + ".java");
+
+        if (!file.exists() || !file.isFile()) {
+            System.out.println("Source file not found: " + file.getPath());
+
+            return;
+        }
+
+        Collection<String> src = new ArrayList<>();
+
+        BufferedReader rdr = null;
+
+        try {
+            rdr = new BufferedReader(new FileReader(file));
+
+            String line;
+            boolean skip = false;
+
+            boolean writeFound = false;
+            boolean readFound = false;
+
+            while ((line = rdr.readLine()) != null) {
+                if (!skip) {
+                    src.add(line);
+
+                    if (line.contains("public boolean writeTo(ByteBuffer buf, 
MessageWriter writer)")) {
+                        src.addAll(write);
+
+                        skip = true;
+
+                        writeFound = true;
+                    }
+                    else if (line.contains("public boolean readFrom(ByteBuffer 
buf)")) {
+                        src.addAll(read);
+
+                        skip = true;
+
+                        readFound = true;
+                    }
+                }
+                else if (line.startsWith(TAB + "}")) {
+                    src.add(line);
+
+                    skip = false;
+                }
+            }
+
+            if (!writeFound)
+                System.out.println("    writeTo method doesn't exist.");
+
+            if (!readFound)
+                System.out.println("    readFrom method doesn't exist.");
+        }
+        finally {
+            if (rdr != null)
+                rdr.close();
+        }
+
+        BufferedWriter wr = null;
+
+        try {
+            wr = new BufferedWriter(new FileWriter(file));
+
+            for (String line : src)
+                wr.write(line + '\n');
+        }
+        finally {
+            if (wr != null)
+                wr.close();
+        }
+    }
+
+    /**
+     * Generates code for provided class.
+     *
+     * @param cls Class.
+     * @throws Exception In case of error.
+     */
+    private void generate(Class<? extends MessageAdapter> cls) throws 
Exception {
+        assert cls != null;
+
+        write.clear();
+        read.clear();
+
+        fields = new ArrayList<>();
+
+        Field[] declaredFields = cls.getDeclaredFields();
+
+        for (Field field : declaredFields) {
+            int mod = field.getModifiers();
+
+            if (!isStatic(mod) && !isTransient(mod) && 
!field.isAnnotationPresent(GridDirectTransient.class))
+                fields.add(field);
+        }
+
+        Collections.sort(fields, FIELD_CMP);
+
+        indent = 2;
+
+        boolean hasSuper = cls.getSuperclass() != BASE_CLS;
+
+        start(write, hasSuper ? "writeTo" : null, true);
+        start(read, hasSuper ? "readFrom" : null, false);
+
+        indent++;
+
+        int state = startState(cls);
+
+        for (Field field : fields)
+            processField(field, state++);
+
+        indent--;
+
+        finish(write);
+        finish(read);
+    }
+
+    /**
+     * @param cls Message class.
+     * @return Start state.
+     */
+    private int startState(Class<?> cls) {
+        assert cls != null;
+
+        Class<?> superCls = cls.getSuperclass();
+
+        Integer state = fieldCnt.get(superCls);
+
+        if (state != null)
+            return state;
+
+        state = 0;
+
+        while (cls.getSuperclass() != BASE_CLS) {
+            cls = cls.getSuperclass();
+
+            for (Field field : cls.getDeclaredFields()) {
+                int mod = field.getModifiers();
+
+                if (!isStatic(mod) && !isTransient(mod) && 
!field.isAnnotationPresent(GridDirectTransient.class))
+                    state++;
+            }
+        }
+
+        fieldCnt.put(superCls, state);
+
+        return state;
+    }
+
+    /**
+     * @param code Code lines.
+     * @param superMtd Super class method name.
+     * @param write Whether write code is generated.
+     */
+    private void start(Collection<String> code, @Nullable String superMtd, 
boolean write) {
+        assert code != null;
+
+        code.add(builder().a(write ? "writer" : 
"reader").a(".setBuffer(").a(BUF_VAR).a(");").toString());
+        code.add(EMPTY);
+
+        if (superMtd != null) {
+            if (write)
+                returnFalseIfFailed(code, "super." + superMtd, BUF_VAR, 
"writer");
+            else
+                returnFalseIfFailed(code, "super." + superMtd, BUF_VAR);
+
+            code.add(EMPTY);
+        }
+
+        if (write) {
+            code.add(builder().a("if (!writer.isTypeWritten()) {").toString());
+
+            indent++;
+
+            returnFalseIfFailed(code, "writer.writeByte", "null", 
"directType()");
+
+            code.add(EMPTY);
+            code.add(builder().a("writer.onTypeWritten();").toString());
+
+            indent--;
+
+            code.add(builder().a("}").toString());
+            code.add(EMPTY);
+        }
+
+        if (!fields.isEmpty())
+            code.add(builder().a("switch (").a(write ? "writer.state()" : 
"readState").a(") {").toString());
+    }
+
+    /**
+     * @param code Code lines.
+     */
+    private void finish(Collection<String> code) {
+        assert code != null;
+
+        if (!fields.isEmpty()) {
+            code.add(builder().a("}").toString());
+            code.add(EMPTY);
+        }
+
+        code.add(builder().a("return true;").toString());
+    }
+
+    /**
+     * @param field Field.
+     * @param opt Case option.
+     */
+    private void processField(Field field, int opt) {
+        assert field != null;
+        assert opt >= 0;
+
+        GridDirectCollection colAnn = 
field.getAnnotation(GridDirectCollection.class);
+        GridDirectMap mapAnn = field.getAnnotation(GridDirectMap.class);
+
+        if (colAnn == null && 
Collection.class.isAssignableFrom(field.getType()))
+            throw new IllegalStateException("@GridDirectCollection annotation 
is not provided for field: " +
+                field.getName());
+
+        if (mapAnn == null && Map.class.isAssignableFrom(field.getType()))
+            throw new IllegalStateException("@GridDirectMap annotation is not 
provided for field: " + field.getName());
+
+        writeField(field, opt, colAnn, mapAnn);
+        readField(field, opt, colAnn, mapAnn);
+    }
+
+    /**
+     * @param field Field.
+     * @param opt Case option.
+     * @param colAnn Collection annotation.
+     * @param mapAnn Map annotation.
+     */
+    private void writeField(Field field, int opt, @Nullable 
GridDirectCollection colAnn,
+        @Nullable GridDirectMap mapAnn) {
+        assert field != null;
+        assert opt >= 0;
+
+        write.add(builder().a("case ").a(opt).a(":").toString());
+
+        indent++;
+
+        returnFalseIfWriteFailed(field.getType(), field.getName(), colAnn != 
null ? colAnn.value() : null,
+            mapAnn != null ? mapAnn.keyType() : null, mapAnn != null ? 
mapAnn.valueType() : null, false);
+
+        write.add(EMPTY);
+        write.add(builder().a("writer.incrementState();").toString());
+        write.add(EMPTY);
+
+        indent--;
+    }
+
+    /**
+     * @param field Field.
+     * @param opt Case option.
+     * @param colAnn Collection annotation.
+     * @param mapAnn Map annotation.
+     */
+    private void readField(Field field, int opt, @Nullable 
GridDirectCollection colAnn,
+        @Nullable GridDirectMap mapAnn) {
+        assert field != null;
+        assert opt >= 0;
+
+        read.add(builder().a("case ").a(opt).a(":").toString());
+
+        indent++;
+
+        returnFalseIfReadFailed(field.getType(), field.getName(), colAnn != 
null ? colAnn.value() : null,
+            mapAnn != null ? mapAnn.keyType() : null, mapAnn != null ? 
mapAnn.valueType() : null);
+
+        read.add(EMPTY);
+        read.add(builder().a("readState++;").toString());
+        read.add(EMPTY);
+
+        indent--;
+    }
+
+    /**
+     * @param type Field type.
+     * @param name Field name.
+     * @param colItemType Collection item type.
+     * @param mapKeyType Map key type.
+     * @param mapValType Map key value.
+     * @param raw Raw write flag.
+     */
+    private void returnFalseIfWriteFailed(Class<?> type, String name, 
@Nullable Class<?> colItemType,
+        @Nullable Class<?> mapKeyType, @Nullable Class<?> mapValType, boolean 
raw) {
+        assert type != null;
+        assert name != null;
+
+        String field = raw ? "null" : '"' + name + '"';
+
+        if (type == byte.class)
+            returnFalseIfFailed(write, "writer.writeByte", field, name);
+        else if (type == short.class)
+            returnFalseIfFailed(write, "writer.writeShort", field, name);
+        else if (type == int.class)
+            returnFalseIfFailed(write, "writer.writeInt", field, name);
+        else if (type == long.class)
+            returnFalseIfFailed(write, "writer.writeLong", field, name);
+        else if (type == float.class)
+            returnFalseIfFailed(write, "writer.writeFloat", field, name);
+        else if (type == double.class)
+            returnFalseIfFailed(write, "writer.writeDouble", field, name);
+        else if (type == char.class)
+            returnFalseIfFailed(write, "writer.writeChar", field, name);
+        else if (type == boolean.class)
+            returnFalseIfFailed(write, "writer.writeBoolean", field, name);
+        else if (type == byte[].class)
+            returnFalseIfFailed(write, "writer.writeByteArray", field, name);
+        else if (type == short[].class)
+            returnFalseIfFailed(write, "writer.writeShortArray", field, name);
+        else if (type == int[].class)
+            returnFalseIfFailed(write, "writer.writeIntArray", field, name);
+        else if (type == long[].class)
+            returnFalseIfFailed(write, "writer.writeLongArray", field, name);
+        else if (type == float[].class)
+            returnFalseIfFailed(write, "writer.writeFloatArray", field, name);
+        else if (type == double[].class)
+            returnFalseIfFailed(write, "writer.writeDoubleArray", field, name);
+        else if (type == char[].class)
+            returnFalseIfFailed(write, "writer.writeCharArray", field, name);
+        else if (type == boolean[].class)
+            returnFalseIfFailed(write, "writer.writeBooleanArray", field, 
name);
+        else if (type == String.class)
+            returnFalseIfFailed(write, "writer.writeString", field, name);
+        else if (type == BitSet.class)
+            returnFalseIfFailed(write, "writer.writeBitSet", field, name);
+        else if (type == UUID.class)
+            returnFalseIfFailed(write, "writer.writeUuid", field, name);
+        else if (type == IgniteUuid.class)
+            returnFalseIfFailed(write, "writer.writeIgniteUuid", field, name);
+        else if (type.isEnum()) {
+            String arg = name + " != null ? (byte)" + name + ".ordinal() : -1";
+
+            returnFalseIfFailed(write, "writer.writeByte", field, arg);
+        }
+        else if (BASE_CLS.isAssignableFrom(type))
+            returnFalseIfFailed(write, "writer.writeMessage", field, name);
+        else if (type.isArray()) {
+            returnFalseIfFailed(write, "writer.writeObjectArray", field, name,
+                "Type." + typeEnum(type.getComponentType()));
+        }
+        else if (Collection.class.isAssignableFrom(type) && 
!Set.class.isAssignableFrom(type)) {
+            assert colItemType != null;
+
+            returnFalseIfFailed(write, "writer.writeCollection", field, name, 
"Type." + typeEnum(colItemType));
+        }
+        else if (Map.class.isAssignableFrom(type)) {
+            assert mapKeyType != null;
+            assert mapValType != null;
+
+            returnFalseIfFailed(write, "writer.writeMap", field, name, "Type." 
+ typeEnum(mapKeyType),
+                "Type." + typeEnum(mapValType));
+        }
+        else
+            throw new IllegalStateException("Unsupported type: " + type);
+    }
+
+    /**
+     * @param type Field type.
+     * @param name Field name.
+     * @param colItemType Collection item type.
+     * @param mapKeyType Map key type.
+     * @param mapValType Map value type.
+     */
+    private void returnFalseIfReadFailed(Class<?> type, @Nullable String name, 
@Nullable Class<?> colItemType,
+        @Nullable Class<?> mapKeyType, @Nullable Class<?> mapValType) {
+        assert type != null;
+
+        String field = '"' + name + '"';
+
+        if (type == byte.class)
+            returnFalseIfReadFailed(name, "reader.readByte", field);
+        else if (type == short.class)
+            returnFalseIfReadFailed(name, "reader.readShort", field);
+        else if (type == int.class)
+            returnFalseIfReadFailed(name, "reader.readInt", field);
+        else if (type == long.class)
+            returnFalseIfReadFailed(name, "reader.readLong", field);
+        else if (type == float.class)
+            returnFalseIfReadFailed(name, "reader.readFloat", field);
+        else if (type == double.class)
+            returnFalseIfReadFailed(name, "reader.readDouble", field);
+        else if (type == char.class)
+            returnFalseIfReadFailed(name, "reader.readChar", field);
+        else if (type == boolean.class)
+            returnFalseIfReadFailed(name, "reader.readBoolean", field);
+        else if (type == byte[].class)
+            returnFalseIfReadFailed(name, "reader.readByteArray", field);
+        else if (type == short[].class)
+            returnFalseIfReadFailed(name, "reader.readShortArray", field);
+        else if (type == int[].class)
+            returnFalseIfReadFailed(name, "reader.readIntArray", field);
+        else if (type == long[].class)
+            returnFalseIfReadFailed(name, "reader.readLongArray", field);
+        else if (type == float[].class)
+            returnFalseIfReadFailed(name, "reader.readFloatArray", field);
+        else if (type == double[].class)
+            returnFalseIfReadFailed(name, "reader.readDoubleArray", field);
+        else if (type == char[].class)
+            returnFalseIfReadFailed(name, "reader.readCharArray", field);
+        else if (type == boolean[].class)
+            returnFalseIfReadFailed(name, "reader.readBooleanArray", field);
+        else if (type == String.class)
+            returnFalseIfReadFailed(name, "reader.readString", field);
+        else if (type == BitSet.class)
+            returnFalseIfReadFailed(name, "reader.readBitSet", field);
+        else if (type == UUID.class)
+            returnFalseIfReadFailed(name, "reader.readUuid", field);
+        else if (type == IgniteUuid.class)
+            returnFalseIfReadFailed(name, "reader.readIgniteUuid", field);
+        else if (type.isEnum()) {
+            String loc = name + "Ord";
+
+            read.add(builder().a("byte ").a(loc).a(";").toString());
+            read.add(EMPTY);
+
+            returnFalseIfReadFailed(loc, "reader.readByte", field);
+
+            read.add(EMPTY);
+            read.add(builder().a(name).a(" = 
").a(type.getSimpleName()).a(".fromOrdinal(").a(loc).a(");").toString());
+        }
+        else if (BASE_CLS.isAssignableFrom(type))
+            returnFalseIfReadFailed(name, "reader.readMessage", field);
+        else if (type.isArray()) {
+            Class<?> compType = type.getComponentType();
+
+            returnFalseIfReadFailed(name, "reader.readObjectArray", field, 
"Type." + typeEnum(compType),
+                compType.getSimpleName() + ".class");
+        }
+        else if (Collection.class.isAssignableFrom(type) && 
!Set.class.isAssignableFrom(type)) {
+            assert colItemType != null;
+
+            returnFalseIfReadFailed(name, "reader.readCollection", field, 
"Type." + typeEnum(colItemType));
+        }
+        else if (Map.class.isAssignableFrom(type)) {
+            assert mapKeyType != null;
+            assert mapValType != null;
+
+            boolean linked = type.equals(LinkedHashMap.class);
+
+            returnFalseIfReadFailed(name, "reader.readMap", field, "Type." + 
typeEnum(mapKeyType),
+                "Type." + typeEnum(mapValType), linked ? "true" : "false");
+        }
+        else
+            throw new IllegalStateException("Unsupported type: " + type);
+    }
+
+    /**
+     * @param var Variable name.
+     * @param mtd Method name.
+     * @param args Method arguments.
+     */
+    private void returnFalseIfReadFailed(String var, String mtd, @Nullable 
String... args) {
+        assert mtd != null;
+
+        String argsStr = "";
+
+        if (args != null && args.length > 0) {
+            for (String arg : args)
+                argsStr += arg + ", ";
+
+            argsStr = argsStr.substring(0, argsStr.length() - 2);
+        }
+
+        read.add(builder().a(var).a(" = 
").a(mtd).a("(").a(argsStr).a(");").toString());
+        read.add(EMPTY);
+
+        read.add(builder().a("if (!reader.isLastRead())").toString());
+
+        indent++;
+
+        read.add(builder().a("return false;").toString());
+
+        indent--;
+    }
+
+    /**
+     * @param code Code lines.
+     * @param accessor Field or method name.
+     * @param args Method arguments.
+     */
+    private void returnFalseIfFailed(Collection<String> code, String accessor, 
@Nullable String... args) {
+        assert code != null;
+        assert accessor != null;
+
+        String argsStr = "";
+
+        if (args != null && args.length > 0) {
+            for (String arg : args)
+                argsStr += arg + ", ";
+
+            argsStr = argsStr.substring(0, argsStr.length() - 2);
+        }
+
+        code.add(builder().a("if 
(!").a(accessor).a("(").a(argsStr).a("))").toString());
+
+        indent++;
+
+        code.add(builder().a("return false;").toString());
+
+        indent--;
+    }
+
+    /**
+     * Creates new builder with correct indent.
+     *
+     * @return Builder.
+     */
+    private SB builder() {
+        assert indent > 0;
+
+        SB sb = new SB();
+
+        for (int i = 0; i < indent; i++)
+            sb.a(TAB);
+
+        return sb;
+    }
+
+    /**
+     * Gets all direct marshallable classes.
+     * First classes will be classes from {@code classesOrder} with same order
+     * as ordered values. Other classes will be at the end and ordered by name
+     * (with package prefix).
+     * That orders need for saving {@code directType} value.
+     *
+     * @return Classes.
+     * @throws Exception In case of error.
+     */
+    private Collection<Class<? extends MessageAdapter>> classes() throws 
Exception {
+        Collection<Class<? extends MessageAdapter>> col = new TreeSet<>(
+            new Comparator<Class<? extends MessageAdapter>>() {
+                @Override public int compare(Class<? extends MessageAdapter> 
c1,
+                    Class<? extends MessageAdapter> c2) {
+                    return c1.getName().compareTo(c2.getName());
+                }
+            });
+
+        URLClassLoader ldr = (URLClassLoader)getClass().getClassLoader();
+
+        for (URL url : ldr.getURLs()) {
+            File file = new File(url.toURI());
+
+            int prefixLen = file.getPath().length() + 1;
+
+            processFile(file, ldr, prefixLen, col);
+        }
+
+        return col;
+    }
+
+    /**
+     * Recursively process provided file or directory.
+     *
+     * @param file File.
+     * @param ldr Class loader.
+     * @param prefixLen Path prefix length.
+     * @param col Classes.
+     * @throws Exception In case of error.
+     */
+    @SuppressWarnings("unchecked")
+    private void processFile(File file, ClassLoader ldr, int prefixLen,
+        Collection<Class<? extends MessageAdapter>> col) throws Exception {
+        assert file != null;
+        assert ldr != null;
+        assert prefixLen > 0;
+        assert col != null;
+
+        if (!file.exists())
+            throw new FileNotFoundException("File doesn't exist: " + file);
+
+        if (file.isDirectory()) {
+            for (File f : file.listFiles())
+                processFile(f, ldr, prefixLen, col);
+        }
+        else {
+            assert file.isFile();
+
+            String path = file.getPath();
+
+            if (path.endsWith(".class")) {
+                String clsName = path.substring(prefixLen, path.length() - 
6).replace(File.separatorChar, '.');
+
+                Class<?> cls = Class.forName(clsName, false, ldr);
+
+                if (cls.getDeclaringClass() == null && cls.getEnclosingClass() 
== null &&
+                    !BASE_CLS.equals(cls) && BASE_CLS.isAssignableFrom(cls))
+                    col.add((Class<? extends MessageAdapter>)cls);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8daee31/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/IgnitePluginProcessor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/IgnitePluginProcessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/IgnitePluginProcessor.java
index 320c5f2..03f8f81 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/IgnitePluginProcessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/IgnitePluginProcessor.java
@@ -112,21 +112,7 @@ public class IgnitePluginProcessor extends 
GridProcessorAdapter {
     public <T> T[] extensions(Class<T> extensionItf) {
         Map<Class<?>, Object[]> extensions = this.extensions;
 
-        T[] res = (T[])extensions.get(extensionItf);
-
-        if (res != null)
-            return res;
-
-        res = (T[])Array.newInstance(extensionItf, 0);
-
-        // Store empty array to map to avoid array creation on the next access.
-        Map<Class<?>, Object[]> extensionsCp = new 
HashMap<>((extensions.size() + 1) * 2, 2.0f);
-
-        extensionsCp.put(extensionItf, res);
-
-        this.extensions = extensionsCp;
-
-        return res;
+        return (T[])extensions.get(extensionItf);
     }
 
     /**

Reply via email to