geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jdil...@apache.org
Subject svn commit: r577140 - in /geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote: codec/ message/ transport/
Date Wed, 19 Sep 2007 03:21:14 GMT
Author: jdillon
Date: Tue Sep 18 20:21:12 2007
New Revision: 577140

URL: http://svn.apache.org/viewvc?rev=577140&view=rev
Log:
Learned some more from gcache (yay), updating the marshalling bits to hopefully work better
and not keep freaking out now weird shiz

Added:
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/Externalizable.java
  (with props)
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MarshallingUtil.java
  (with props)
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MessageCodecFactory.java
  (with props)
Removed:
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MagicNumber.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageCodecFactory.java
Modified:
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/TransportSupport.java

Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/Externalizable.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/Externalizable.java?rev=577140&view=auto
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/Externalizable.java
(added)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/Externalizable.java
Tue Sep 18 20:21:12 2007
@@ -0,0 +1,34 @@
+/*
+ * 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.geronimo.gshell.remote.codec;
+
+import org.apache.mina.common.ByteBuffer;
+
+/**
+ * ???
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Externalizable
+{
+    void writeExternal(final ByteBuffer out) throws Exception;
+
+    void readExternal(final ByteBuffer in) throws Exception;
+}
\ No newline at end of file

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/Externalizable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/Externalizable.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/Externalizable.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MarshallingUtil.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MarshallingUtil.java?rev=577140&view=auto
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MarshallingUtil.java
(added)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MarshallingUtil.java
Tue Sep 18 20:21:12 2007
@@ -0,0 +1,246 @@
+/*
+ * 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.geronimo.gshell.remote.codec;
+
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.CharacterCodingException;
+import java.util.UUID;
+
+import org.apache.mina.common.ByteBuffer;
+
+/**
+ * ???
+ *
+ * @version $Rev$ $Date$
+ */
+public class MarshallingUtil
+{
+    //
+    // Boolean Serialization
+    //
+
+    private static final byte TRUE = 1;
+
+    private static final byte FALSE = 0;
+
+    public static boolean readBoolean(final ByteBuffer in) {
+        assert in != null;
+
+        byte b = in.get();
+
+        if (b == TRUE) {
+            return true;
+        }
+        else if (b == FALSE) {
+            return false;
+        }
+        else {
+            throw new Error();
+        }
+    }
+
+    public static void writeBoolean(final ByteBuffer out, final boolean bool) {
+        assert out != null;
+
+        if (bool) {
+            out.put(TRUE);
+        }
+        else {
+            out.put(FALSE);
+        }
+    }
+
+    //
+    // Byte[] Serialization
+    //
+
+    public static byte[] readBytes(final ByteBuffer in) {
+        assert in != null;
+
+        boolean isNull = readBoolean(in);
+
+        if (isNull) {
+            return null;
+        }
+
+        int len = in.getInt();
+
+        byte[] bytes = new byte[len];
+
+        in.get(bytes);
+
+        return bytes;
+    }
+
+    public static void writeBytes(final ByteBuffer out, final byte[] bytes) {
+        assert out != null;
+
+        if (bytes == null) {
+            writeBoolean(out, true);
+        }
+        else {
+            writeBoolean(out, false);
+
+            out.putInt(bytes.length);
+
+            out.put(bytes);
+        }
+    }
+
+    //
+    // ByteBuffer Serialization
+    //
+
+    public static ByteBuffer readBuffer(final ByteBuffer in) {
+        assert in != null;
+
+        byte[] bytes = readBytes(in);
+
+        if (bytes == null) {
+            return null;
+        }
+
+        return ByteBuffer.wrap(bytes);
+    }
+
+    public static void writeBuffer(final ByteBuffer out, final ByteBuffer buffer) {
+        assert out != null;
+
+        if (buffer == null) {
+            writeBytes(out, null);
+        }
+        else {
+            writeBoolean(out, false);
+
+            out.putInt(buffer.remaining());
+
+            out.put(buffer);
+        }
+    }
+
+    //
+    // Object Serialization
+    //
+
+    public static Object readObject(final ByteBuffer in) throws IOException, ClassNotFoundException
{
+        assert in != null;
+
+        byte[] bytes = readBytes(in);
+
+        if (bytes == null) {
+            return null;
+        }
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+
+        return ois.readObject();
+    }
+
+    public static void writeObject(final ByteBuffer out, final Object obj) throws IOException
{
+        assert out != null;
+
+        byte[] bytes = null;
+
+        if (obj != null) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+            oos.writeObject(obj);
+            oos.flush();
+
+            bytes = baos.toByteArray();
+        }
+
+        writeBytes(out, bytes);
+    }
+
+    //
+    // String Serialization
+    //
+
+    private static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
+
+    public static String readString(final ByteBuffer in) throws CharacterCodingException
{
+        assert in != null;
+
+        int len = in.getInt();
+
+        if (len == -1) {
+            return null;
+        }
+
+        return in.getString(len, UTF_8_CHARSET.newDecoder());
+    }
+
+    public static void writeString(final ByteBuffer out, final String str) throws CharacterCodingException
{
+        assert out != null;
+
+        if (str == null) {
+            out.putInt(-1);
+        }
+        else {
+            int len = str.length();
+            out.putInt(len);
+
+            out.putString(str, len, UTF_8_CHARSET.newEncoder());
+        }
+    }
+
+    //
+    // UUID Serialization
+    //
+
+    public static UUID readUuid(final ByteBuffer in) throws Exception {
+        assert in != null;
+
+        boolean isNull = readBoolean(in);
+
+        if (isNull) {
+            return null;
+        }
+
+        long msb = in.getLong();
+
+        long lsb = in.getLong();
+
+        return new UUID(msb, lsb);
+    }
+
+    public static void writeUuid(final ByteBuffer out, final UUID uuid) throws Exception
{
+        assert out != null;
+
+        if (uuid == null) {
+            writeBoolean(out, true);
+        }
+        else {
+            writeBoolean(out, false);
+
+            out.putLong(uuid.getMostSignificantBits());
+
+            out.putLong(uuid.getLeastSignificantBits());
+        }
+    }
+}
\ No newline at end of file

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MarshallingUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MarshallingUtil.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MarshallingUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MessageCodecFactory.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MessageCodecFactory.java?rev=577140&view=auto
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MessageCodecFactory.java
(added)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MessageCodecFactory.java
Tue Sep 18 20:21:12 2007
@@ -0,0 +1,266 @@
+/*
+ * 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.geronimo.gshell.remote.codec;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
+import java.util.Set;
+import java.util.Arrays;
+
+import org.apache.geronimo.gshell.remote.message.Message;
+import org.apache.geronimo.gshell.remote.message.MessageType;
+import org.apache.geronimo.gshell.remote.crypto.CryptoContext;
+import org.apache.geronimo.gshell.remote.crypto.CryptoContextAware;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.apache.mina.filter.codec.ProtocolEncoderOutput;
+import org.apache.mina.filter.codec.ProtocolCodecException;
+import org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory;
+import org.apache.mina.filter.codec.demux.MessageDecoderAdapter;
+import org.apache.mina.filter.codec.demux.MessageDecoderResult;
+import org.apache.mina.filter.codec.demux.MessageEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Provides encoding and decoding support for {@link Message} instances.
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role=MessageCodecFactory.class)
+public class MessageCodecFactory
+    extends DemuxingProtocolCodecFactory
+{
+    private static final byte[] MAGIC = { 'g', 's', 'h', 0 };
+
+    private static final byte VERSION = 1;
+
+    private static final int HEADER_SIZE =
+            MAGIC.length +
+            1 + // version (byte)
+            1 + // message type (enum byte)
+            4;  // body length (int)
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Requirement
+    private CryptoContext crypto;
+
+    public MessageCodecFactory() {
+        register(new Decoder());
+
+        //noinspection unchecked
+        register(new Encoder());
+    }
+
+    private void attachCryptoContext(final Message msg) {
+        // We need to do a little bit of extra fluff to hook up support for encrypted messages
+        if (msg instanceof CryptoContextAware) {
+            log.debug("Attaching crypto context to: {}", msg);
+
+            ((CryptoContextAware)msg).setCryptoContext(crypto);
+        }
+    }
+
+    private void writeMagic(final ByteBuffer out) throws Exception {
+        assert out != null;
+
+        out.put(MAGIC);
+    }
+
+    private byte[] readMagic(final ByteBuffer in) throws Exception {
+        assert in != null;
+
+        byte[] bytes = new byte[MAGIC.length];
+
+        in.get(bytes);
+
+        if (!Arrays.equals(MAGIC, bytes)) {
+            throw new ProtocolCodecException("Invalid MAGIC");
+        }
+
+        return bytes;
+    }
+
+    private void writeVersion(final ByteBuffer out) throws Exception {
+        assert out != null;
+
+        out.put(VERSION);
+    }
+
+    private byte readVersion(final ByteBuffer in) throws Exception {
+        assert in != null;
+
+        byte version = in.get();
+
+        if (VERSION != version) {
+            throw new ProtocolCodecException("Invalid version");
+        }
+
+        return version;
+    }
+
+    private byte[] marshal(final Message msg) throws Exception {
+        assert msg != null;
+
+        log.debug("Marshalling: {}", msg);
+        
+        ByteBuffer out = ByteBuffer.allocate(256, false);
+        out.setAutoExpand(true);
+
+        writeMagic(out);
+
+        writeVersion(out);
+
+        out.putEnum(msg.getType());
+
+        // Determine the length of the message body
+        out.mark();
+        out.putInt(0);
+        msg.writeExternal(out);
+
+        int bodyStart = HEADER_SIZE;
+        int pos = out.position();
+        int len = pos - bodyStart;
+
+        out.reset();
+        
+        // Write the length of the body
+        out.putInt(len);
+        out.position(pos);
+        out.limit(pos);
+        out.flip();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+        WritableByteChannel channel = Channels.newChannel(baos);
+        channel.write(out.buf());
+        channel.close();
+
+        byte[] bytes = baos.toByteArray();
+
+        log.debug("Marshalled size: {} bytes", bytes.length);
+
+        return bytes;
+    }
+
+    //
+    // Encoder
+    //
+
+    public class Encoder
+        implements MessageEncoder
+    {
+        public Set getMessageTypes() {
+            return MessageType.types();
+        }
+
+        public void encode(final IoSession session, final Object message, final ProtocolEncoderOutput
out) throws Exception {
+            assert session != null;
+            assert message != null;
+            assert out != null;
+
+            Message msg = (Message)message;
+
+            log.debug("Encoding: {}", msg);
+
+            attachCryptoContext(msg);
+
+            byte[] bytes = marshal(msg);
+
+            log.debug("Encoded {} bytes", bytes.length);
+
+            out.write(ByteBuffer.wrap(bytes));
+        }
+    }
+
+    //
+    // Decoder
+    //
+
+    public class Decoder
+        extends MessageDecoderAdapter
+    {
+        public MessageDecoderResult decodable(final IoSession session, final ByteBuffer in)
{
+            assert session != null;
+            assert in != null;
+
+            if (in.remaining() < HEADER_SIZE) {
+                return MessageDecoderResult.NEED_DATA;
+            }
+
+            try {
+                readMagic(in);
+
+                readVersion(in);
+
+                MessageType type = in.getEnum(MessageType.class);
+
+                if (type == null) {
+                    return MessageDecoderResult.NOT_OK;
+                }
+            }
+            catch (Exception e) {
+                return MessageDecoderResult.NOT_OK;
+            }
+
+            // Make sure we have all of the data we need
+            int len = in.getInt();
+            
+            if (in.remaining() != len) {
+                return MessageDecoderResult.NEED_DATA;
+            }
+
+            return MessageDecoderResult.OK;
+        }
+
+        public MessageDecoderResult decode(final IoSession session, final ByteBuffer in,
final ProtocolDecoderOutput out) throws Exception {
+            assert session != null;
+            assert in != null;
+            assert out != null;
+
+            readMagic(in);
+
+            readVersion(in);
+
+            MessageType type = in.getEnum(MessageType.class);
+
+            Message msg = MessageType.create(type);
+
+            attachCryptoContext(msg);
+
+            int len = in.getInt();
+
+            log.debug("Decoding {} bytes", len);
+
+            msg.readExternal(in);
+
+            log.debug("Decoded: {}", msg);
+
+            out.write(msg);
+
+            return MessageDecoderResult.OK;
+        }
+    }
+}
\ No newline at end of file

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MessageCodecFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MessageCodecFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/codec/MessageCodecFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java?rev=577140&r1=577139&r2=577140&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
Tue Sep 18 20:21:12 2007
@@ -19,6 +19,10 @@
 
 package org.apache.geronimo.gshell.remote.message;
 
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Collections;
+
 /**
  * Enumeration of supported message types and factory for message instances.
  *
@@ -66,5 +70,15 @@
         catch (IllegalAccessException e) {
             throw new Error(e);
         }
+    }
+
+    public static Set<Class> types() {
+        Set<Class> set = new HashSet<Class>();
+
+        for (MessageType type : values()) {
+            set.add(type.type);
+        }
+
+        return Collections.unmodifiableSet(set);
     }
 }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/TransportSupport.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/TransportSupport.java?rev=577140&r1=577139&r2=577140&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/TransportSupport.java
(original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/TransportSupport.java
Tue Sep 18 20:21:12 2007
@@ -23,7 +23,7 @@
 
 import org.apache.geronimo.gshell.common.tostring.ReflectionToStringBuilder;
 import org.apache.geronimo.gshell.remote.logging.LoggingFilter;
-import org.apache.geronimo.gshell.remote.message.MessageCodecFactory;
+import org.apache.geronimo.gshell.remote.codec.MessageCodecFactory;
 import org.apache.geronimo.gshell.remote.message.MessageVisitor;
 import org.apache.mina.common.DefaultIoFilterChainBuilder;
 import org.apache.mina.common.IoService;



Mime
View raw message