// Path: action/src/main/java/org/atmosphere/vibe/platform/action/Action.java
// public interface Action<T> {
// 
//     /**
//      * Some action is taken.
//      */
//     void on(T object);
// 
// }
// 
// Path: action/src/main/java/org/atmosphere/vibe/platform/action/Actions.java
// public interface Actions<T> {
// 
//     /**
//      * Adds an action.
//      */
//     Actions<T> add(Action<T> action);
// 
//     /**
//      * Disables any operation on the actions. This method is useful when
//      * multiple events are mutually exclusive.
//      */
//     Actions<T> disable();
// 
//     /**
//      * Determines if the actions has been disabled.
//      */
//     boolean disabled();
// 
//     /**
//      * Removes all of the actions.
//      */
//     Actions<T> empty();
// 
//     /**
//      * Fire all of the actions.
//      */
//     Actions<T> fire();
// 
//     /**
//      * Fire all of the actions with the given value.
//      */
//     Actions<T> fire(T data);
// 
//     /**
//      * Determines if the actions have been called at least once.
//      */
//     boolean fired();
// 
//     /**
//      * Determines if the actions contains an action.
//      */
//     boolean has();
// 
//     /**
//      * Determines whether the actions contains the specified action.
//      */
//     boolean has(Action<T> action);
// 
//     /**
//      * Removes an action.
//      */
//     Actions<T> remove(Action<T> action);
// 
//     /**
//      * Options to create an Actions. With the default options, an Action will
//      * work like a typical event manager.
//      *
//      * @author Donghwan Kim
//      */
//     class Options {
// 
//         private boolean once;
//         private boolean memory;
//         private boolean unique;
// 
//         public Options() {
//         }
// 
//         public Options(Options options) {
//             once = options.once;
//             memory = options.memory;
//             unique = options.unique;
//         }
// 
//         public boolean once() {
//             return once;
//         }
// 
//         /**
//          * Ensures the actions can only be fired once. The default value is
//          * false.
//          */
//         public Options once(boolean once) {
//             this.once = once;
//             return this;
//         }
// 
//         public boolean memory() {
//             return memory;
//         }
// 
//         /**
//          * Keeps track of previous values and will call any action added after
//          * the actions has been fired right away with the latest "memorized"
//          * values. The default value is false.
//          */
//         public Options memory(boolean memory) {
//             this.memory = memory;
//             return this;
//         }
// 
//         public boolean unique() {
//             return unique;
//         }
// 
//         /**
//          * Ensures an action can only be added once. The default value is false.
//          */
//         public Options unique(boolean unique) {
//             this.unique = unique;
//             return this;
//         }
// 
//     }
// 
// }
// 
// Path: action/src/main/java/org/atmosphere/vibe/platform/action/SimpleActions.java
// public class SimpleActions<T> extends AbstractActions<T> {
// 
//     private boolean disabled;
//     private boolean fired;
//     private T cached;
// 
//     public SimpleActions() {
//         super();
//     }
// 
//     public SimpleActions(Actions.Options o) {
//         super(o);
//     }
// 
//     @Override
//     protected List<Action<T>> createList() {
//         return new ArrayList<>();
//     }
// 
//     @Override
//     protected void setCache(T data) {
//         this.cached = data;
//     }
// 
//     @Override
//     protected T cached() {
//         return cached;
//     }
// 
//     @Override
//     protected boolean setDisabled() {
//         boolean answer = !disabled;
//         if (answer) {
//             disabled = true;
//         }
//         return answer;
//     }
// 
//     @Override
//     public boolean disabled() {
//         return disabled;
//     }
// 
//     @Override
//     protected void setFired() {
//         fired = true;
//     }
// 
//     @Override
//     public boolean fired() {
//         return fired;
//     }
// 
// }


import java.nio.ByteBuffer;
import org.atmosphere.vibe.platform.action.Action;
import org.atmosphere.vibe.platform.action.Actions;
import org.atmosphere.vibe.platform.action.SimpleActions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
 * Copyright 2014 The Vibe Project
 *
 * Licensed 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.atmosphere.vibe.platform.websocket;



/**
 * Abstract base class for {@link ServerWebSocket}.
 *
 * @author Donghwan Kim
 */
public abstract class AbstractServerWebSocket implements ServerWebSocket {

    protected final Actions<String> textActions = new SimpleActions<>();
    protected final Actions<ByteBuffer> binaryActions = new SimpleActions<>();
    protected final Actions<Throwable> errorActions = new SimpleActions<>();
    protected final Actions<Void> closeActions = new SimpleActions<>(new Actions.Options().once(true).memory(true));

    private final Logger logger = LoggerFactory.getLogger(AbstractServerWebSocket.class);
    private State state = State.OPEN;

    public AbstractServerWebSocket() {
// Path: action/src/main/java/org/atmosphere/vibe/platform/action/Action.java
// public interface Action<T> {
// 
//     /**
//      * Some action is taken.
//      */
//     void on(T object);
// 
// }
// 
// Path: action/src/main/java/org/atmosphere/vibe/platform/action/Actions.java
// public interface Actions<T> {
// 
//     /**
//      * Adds an action.
//      */
//     Actions<T> add(Action<T> action);
// 
//     /**
//      * Disables any operation on the actions. This method is useful when
//      * multiple events are mutually exclusive.
//      */
//     Actions<T> disable();
// 
//     /**
//      * Determines if the actions has been disabled.
//      */
//     boolean disabled();
// 
//     /**
//      * Removes all of the actions.
//      */
//     Actions<T> empty();
// 
//     /**
//      * Fire all of the actions.
//      */
//     Actions<T> fire();
// 
//     /**
//      * Fire all of the actions with the given value.
//      */
//     Actions<T> fire(T data);
// 
//     /**
//      * Determines if the actions have been called at least once.
//      */
//     boolean fired();
// 
//     /**
//      * Determines if the actions contains an action.
//      */
//     boolean has();
// 
//     /**
//      * Determines whether the actions contains the specified action.
//      */
//     boolean has(Action<T> action);
// 
//     /**
//      * Removes an action.
//      */
//     Actions<T> remove(Action<T> action);
// 
//     /**
//      * Options to create an Actions. With the default options, an Action will
//      * work like a typical event manager.
//      *
//      * @author Donghwan Kim
//      */
//     class Options {
// 
//         private boolean once;
//         private boolean memory;
//         private boolean unique;
// 
//         public Options() {
//         }
// 
//         public Options(Options options) {
//             once = options.once;
//             memory = options.memory;
//             unique = options.unique;
//         }
// 
//         public boolean once() {
//             return once;
//         }
// 
//         /**
//          * Ensures the actions can only be fired once. The default value is
//          * false.
//          */
//         public Options once(boolean once) {
//             this.once = once;
//             return this;
//         }
// 
//         public boolean memory() {
//             return memory;
//         }
// 
//         /**
//          * Keeps track of previous values and will call any action added after
//          * the actions has been fired right away with the latest "memorized"
//          * values. The default value is false.
//          */
//         public Options memory(boolean memory) {
//             this.memory = memory;
//             return this;
//         }
// 
//         public boolean unique() {
//             return unique;
//         }
// 
//         /**
//          * Ensures an action can only be added once. The default value is false.
//          */
//         public Options unique(boolean unique) {
//             this.unique = unique;
//             return this;
//         }
// 
//     }
// 
// }
// 
// Path: action/src/main/java/org/atmosphere/vibe/platform/action/SimpleActions.java
// public class SimpleActions<T> extends AbstractActions<T> {
// 
//     private boolean disabled;
//     private boolean fired;
//     private T cached;
// 
//     public SimpleActions() {
//         super();
//     }
// 
//     public SimpleActions(Actions.Options o) {
//         super(o);
//     }
// 
//     @Override
//     protected List<Action<T>> createList() {
//         return new ArrayList<>();
//     }
// 
//     @Override
//     protected void setCache(T data) {
//         this.cached = data;
//     }
// 
//     @Override
//     protected T cached() {
//         return cached;
//     }
// 
//     @Override
//     protected boolean setDisabled() {
//         boolean answer = !disabled;
//         if (answer) {
//             disabled = true;
//         }
//         return answer;
//     }
// 
//     @Override
//     public boolean disabled() {
//         return disabled;
//     }
// 
//     @Override
//     protected void setFired() {
//         fired = true;
//     }
// 
//     @Override
//     public boolean fired() {
//         return fired;
//     }
// 
// }


// Path: websocket/src/main/java/org/atmosphere/vibe/platform/websocket/AbstractServerWebSocket.java
import java.nio.ByteBuffer;
import org.atmosphere.vibe.platform.action.Action;
import org.atmosphere.vibe.platform.action.Actions;
import org.atmosphere.vibe.platform.action.SimpleActions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * Copyright 2014 The Vibe Project
 *
 * Licensed 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.atmosphere.vibe.platform.websocket;



/**
 * Abstract base class for {@link ServerWebSocket}.
 *
 * @author Donghwan Kim
 */
public abstract class AbstractServerWebSocket implements ServerWebSocket {

    protected final Actions<String> textActions = new SimpleActions<>();
    protected final Actions<ByteBuffer> binaryActions = new SimpleActions<>();
    protected final Actions<Throwable> errorActions = new SimpleActions<>();
    protected final Actions<Void> closeActions = new SimpleActions<>(new Actions.Options().once(true).memory(true));

    private final Logger logger = LoggerFactory.getLogger(AbstractServerWebSocket.class);
    private State state = State.OPEN;

    public AbstractServerWebSocket() {
        errorActions.add(new Action<Throwable>() {