<commit_before>/*
 * Copyright 2014 <NAME>
 *
 * The jawampa authors license 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 ws.wamp.jawampa;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class WampMessages {

    /**
     * Base class for all messages
     */
    public static abstract class WampMessage {

        public abstract JsonNode toObjectArray(ObjectMapper mapper)
                throws WampError;

        public static WampMessage fromObjectArray(ArrayNode messageNode)
                throws WampError {
            if (messageNode == null || messageNode.size() < 1
                    || !messageNode.get(0).canConvertToInt())
                throw new WampError(ApplicationError.INVALID_MESSAGE);

            int messageType = messageNode.get(0).asInt();
            WampMessageFactory factory = messageFactories.get(messageType);
            if (factory == null)
                return null; // We can't find the message type, so we skip it

            return factory.fromObjectArray(messageNode);
        }

        // Register all possible message types

        /**
         * A map which associates all message types which factories which can
         * recreate them from received data.
         */
        final static Map<Integer, WampMessageFactory> messageFactories;
        static {
            HashMap<Integer, WampMessageFactory> map = new HashMap<Integer, WampMessageFactory>();
            map.put(HelloMessage.ID, new HelloMessage.Factory());
            map.put(WelcomeMessage.ID, new WelcomeMessage.Factory());
            map.put(AbortMessage.ID, new AbortMessage.Factory());
            map.put(ChallengeMessage.ID, new ChallengeMessage.Factory());
            map.put(AuthenticateMessage.ID, new AuthenticateMessage.Factory());
            map.put(GoodbyeMessage.ID, new GoodbyeMessage.Factory());
            // map.put(MessageType.ID, new HeartbeatMessage.Factory());
            map.put(ErrorMessage.ID, new ErrorMessage.Factory());
            map.put(PublishMessage.ID, new PublishMessage.Factory());
            map.put(PublishedMessage.ID, new PublishedMessage.Factory());
            map.put(SubscribeMessage.ID, new SubscribeMessage.Factory());
            map.put(SubscribedMessage.ID, new SubscribedMessage.Factory());
            map.put(UnsubscribeMessage.ID, new UnsubscribeMessage.Factory());
            map.put(UnsubscribedMessage.ID, new UnsubscribedMessage.Factory());
            map.put(EventMessage.ID, new EventMessage.Factory());
            map.put(CallMessage.ID, new CallMessage.Factory());
            // map.put(CancelMessage.ID, new CancelMessage.Factory());
            map.put(ResultMessage.ID, new ResultMessage.Factory());
            map.put(RegisterMessage.ID, new RegisterMessage.Factory());
            map.put(RegisteredMessage.ID, new RegisteredMessage.Factory());
            map.put(UnregisterMessage.ID, new UnregisterMessage.Factory());
            map.put(UnregisteredMessage.ID, new UnregisteredMessage.Factory());
            map.put(InvocationMessage.ID, new InvocationMessage.Factory());
            // map.put(InterruptMessage.ID, new InterruptMessage.Factory());
            map.put(YieldMessage.ID, new YieldMessage.Factory());
            messageFactories = Collections.unmodifiableMap(map);
        }
    }

    interface WampMessageFactory {
        public WampMessage fromObjectArray(ArrayNode messageNode) throws WampError;
    }

    /**
     * Sent by a Client to initiate opening of a WAMP session to a Router
     * attaching to a Realm. Format: [HELLO, Realm|uri, Details|dict]
     */
    public static class HelloMessage extends WampMessage {
        public final static int ID = 1;
        public String realm;
        public ObjectNode details;

        public HelloMessage(String realm, ObjectNode details) {
            this.realm = realm;
            this.details = details;
        }

        public JsonNode toObjectArray(ObjectMapper mapper) throws WampError {
            ArrayNode messageNode = mapper.createArrayNode();
            messageNode.add(ID);
            messageNode.add(realm);
            if (details != null)
                messageNode.add(details);
            else
                messageNode.add(mapper.createObjectNode());
            return messageNode;
        }

        static class Factory implements WampMessageFactory {
            @Override
            public WampMessage fromObjectArray(ArrayNode messageNode) throws WampError {
                if (messageNode.size() != 3 || !messageNode.get(1).isTextual()
                        || !messageNode.get(2).isObject())
                    throw new WampError(ApplicationError.INVALID_MESSAGE);

                String realm = messageNode.get(1).asText();
                ObjectNode details = (ObjectNode) messageNode.get(2);
                return new HelloMessage(realm, details);
            }
        }
    }

    /**
     * Sent by a Router to accept a Client. The WAMP session is now open.
     * Format: [WELCOME, Session|id, Details|dict]
     */
    public static class WelcomeMessage extends WampMessage {
        public final static int ID = 2;
        public long sessionId;
        public ObjectNode details;

        public WelcomeMessage(long sessionId, ObjectNode details) {
            this.sessionId = sessionId;
            this.details = details;
        }

        public JsonNode toObjectArray(ObjectMapper mapper) throws WampError {
            ArrayNode messageNode = mapper.createArrayNode();
            messageNode.add(ID);
            messageNode.add(sessionId);
            if (details != null)
                messageNode.add(details);
            else
                messageNode.add(mapper.createObjectNode());
            return messageNode;
        }

        static class Factory implements WampMessageFactory {
            @Override
            public WampMessage fromObjectArray(ArrayNode messageNode) throws WampError {
                if (messageNode.size() != 3
                        || !messageNode.get(1).canConvertToLong()
                        || !messageNode.get(2).isObject())
                    throw new WampError(ApplicationError.INVALID_MESSAGE);

                long sessionId = messageNode.get(1).asLong();
                ObjectNode details = (ObjectNode) messageNode.get(2);
                return new WelcomeMessage(sessionId, details);
            }
        }
    }

    /**
     * Sent by a Peer to abort the opening of a WAMP session. No response is
     * expected. [ABORT, Details|dict, Reason|uri]
     */
    public static class AbortMessage extends WampMessage {
        public final static int ID = 3;
        public ObjectNode details;
        public String reason;

        public AbortMessage(ObjectNode details, String reason) {
            this.details = details;
            this.reason = reason;
        }

        public JsonNode toObjectArray(ObjectMapper mapper) throws WampError {
            ArrayNode messageNode = mapper.createArrayNode();
            if (details != null)
                messageNode.add(details);
            else
                messageNode.add(mapper.createObjectNode());
            messageNode.add(reason);
            return messageNode;
        }

        static class Factory implements WampMessageFactory {
            @Override
            public WampMessage fromObjectArray(ArrayNode messageNode)
                    throws WampError {
                if (messageNode.size() != 3 || !messageNode.get(1).isObject()<commit_msg>ID is missing in AbortMessage serialization<commit_after>/*
 * Copyright 2014 <NAME>
 *
 * The jawampa authors license 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 ws.wamp.jawampa;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class WampMessages {

    /**
     * Base class for all messages
     */
    public static abstract class WampMessage {

        public abstract JsonNode toObjectArray(ObjectMapper mapper)
                throws WampError;

        public static WampMessage fromObjectArray(ArrayNode messageNode)
                throws WampError {
            if (messageNode == null || messageNode.size() < 1
                    || !messageNode.get(0).canConvertToInt())
                throw new WampError(ApplicationError.INVALID_MESSAGE);

            int messageType = messageNode.get(0).asInt();
            WampMessageFactory factory = messageFactories.get(messageType);
            if (factory == null)
                return null; // We can't find the message type, so we skip it

            return factory.fromObjectArray(messageNode);
        }

        // Register all possible message types

        /**
         * A map which associates all message types which factories which can
         * recreate them from received data.
         */
        final static Map<Integer, WampMessageFactory> messageFactories;
        static {
            HashMap<Integer, WampMessageFactory> map = new HashMap<Integer, WampMessageFactory>();
            map.put(HelloMessage.ID, new HelloMessage.Factory());
            map.put(WelcomeMessage.ID, new WelcomeMessage.Factory());
            map.put(AbortMessage.ID, new AbortMessage.Factory());
            map.put(ChallengeMessage.ID, new ChallengeMessage.Factory());
            map.put(AuthenticateMessage.ID, new AuthenticateMessage.Factory());
            map.put(GoodbyeMessage.ID, new GoodbyeMessage.Factory());
            // map.put(MessageType.ID, new HeartbeatMessage.Factory());
            map.put(ErrorMessage.ID, new ErrorMessage.Factory());
            map.put(PublishMessage.ID, new PublishMessage.Factory());
            map.put(PublishedMessage.ID, new PublishedMessage.Factory());
            map.put(SubscribeMessage.ID, new SubscribeMessage.Factory());
            map.put(SubscribedMessage.ID, new SubscribedMessage.Factory());
            map.put(UnsubscribeMessage.ID, new UnsubscribeMessage.Factory());
            map.put(UnsubscribedMessage.ID, new UnsubscribedMessage.Factory());
            map.put(EventMessage.ID, new EventMessage.Factory());
            map.put(CallMessage.ID, new CallMessage.Factory());
            // map.put(CancelMessage.ID, new CancelMessage.Factory());
            map.put(ResultMessage.ID, new ResultMessage.Factory());
            map.put(RegisterMessage.ID, new RegisterMessage.Factory());
            map.put(RegisteredMessage.ID, new RegisteredMessage.Factory());
            map.put(UnregisterMessage.ID, new UnregisterMessage.Factory());
            map.put(UnregisteredMessage.ID, new UnregisteredMessage.Factory());
            map.put(InvocationMessage.ID, new InvocationMessage.Factory());
            // map.put(InterruptMessage.ID, new InterruptMessage.Factory());
            map.put(YieldMessage.ID, new YieldMessage.Factory());
            messageFactories = Collections.unmodifiableMap(map);
        }
    }

    interface WampMessageFactory {
        public WampMessage fromObjectArray(ArrayNode messageNode) throws WampError;
    }

    /**
     * Sent by a Client to initiate opening of a WAMP session to a Router
     * attaching to a Realm. Format: [HELLO, Realm|uri, Details|dict]
     */
    public static class HelloMessage extends WampMessage {
        public final static int ID = 1;
        public String realm;
        public ObjectNode details;

        public HelloMessage(String realm, ObjectNode details) {
            this.realm = realm;
            this.details = details;
        }

        public JsonNode toObjectArray(ObjectMapper mapper) throws WampError {
            ArrayNode messageNode = mapper.createArrayNode();
            messageNode.add(ID);
            messageNode.add(realm);
            if (details != null)
                messageNode.add(details);
            else
                messageNode.add(mapper.createObjectNode());
            return messageNode;
        }

        static class Factory implements WampMessageFactory {
            @Override
            public WampMessage fromObjectArray(ArrayNode messageNode) throws WampError {
                if (messageNode.size() != 3 || !messageNode.get(1).isTextual()
                        || !messageNode.get(2).isObject())
                    throw new WampError(ApplicationError.INVALID_MESSAGE);

                String realm = messageNode.get(1).asText();
                ObjectNode details = (ObjectNode) messageNode.get(2);
                return new HelloMessage(realm, details);
            }
        }
    }

    /**
     * Sent by a Router to accept a Client. The WAMP session is now open.
     * Format: [WELCOME, Session|id, Details|dict]
     */
    public static class WelcomeMessage extends WampMessage {
        public final static int ID = 2;
        public long sessionId;
        public ObjectNode details;

        public WelcomeMessage(long sessionId, ObjectNode details) {
            this.sessionId = sessionId;
            this.details = details;
        }

        public JsonNode toObjectArray(ObjectMapper mapper) throws WampError {
            ArrayNode messageNode = mapper.createArrayNode();
            messageNode.add(ID);
            messageNode.add(sessionId);
            if (details != null)
                messageNode.add(details);
            else
                messageNode.add(mapper.createObjectNode());
            return messageNode;
        }

        static class Factory implements WampMessageFactory {
            @Override
            public WampMessage fromObjectArray(ArrayNode messageNode) throws WampError {
                if (messageNode.size() != 3
                        || !messageNode.get(1).canConvertToLong()
                        || !messageNode.get(2).isObject())
                    throw new WampError(ApplicationError.INVALID_MESSAGE);

                long sessionId = messageNode.get(1).asLong();
                ObjectNode details = (ObjectNode) messageNode.get(2);
                return new WelcomeMessage(sessionId, details);
            }
        }
    }

    /**
     * Sent by a Peer to abort the opening of a WAMP session. No response is
     * expected. [ABORT, Details|dict, Reason|uri]
     */
    public static class AbortMessage extends WampMessage {
        public final static int ID = 3;
        public ObjectNode details;
        public String reason;

        public AbortMessage(ObjectNode details, String reason) {
            this.details = details;
            this.reason = reason;
        }

        public JsonNode toObjectArray(ObjectMapper mapper) throws WampError {
            ArrayNode messageNode = mapper.createArrayNode();
            messageNode.add(ID);
            if (details != null)
                messageNode.add(details);
            else
                messageNode.add(mapper.createObjectNode());
            messageNode.add(reason);
            return messageNode;
        }

        static class Factory implements WampMessageFactory {
            @Override
            public WampMessage fromObjectArray(ArrayNode messageNode)
                    throws WampError {
                if (messageNode.size() != 3 || !messageNode.get(1).isObject()
{'fraction_non_alphanumeric': 0.08833943467562864, 'fraction_numerical': 0.0031206865510412293, 'mean_word_length': 2.286785009861933, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6718595', 'n_tokens_mistral': 4242, 'n_tokens_neox': 4051, 'n_words': 1117}