// Path: action/src/main/java/io/cettia/asity/action/Action.java
// @FunctionalInterface
// public interface Action<T> {
// 
//   /**
//    * Some action is taken.
//    */
//   void on(T object);
// 
// }
// 
// Path: action/src/main/java/io/cettia/asity/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/io/cettia/asity/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 io.cettia.asity.action.Action;
import io.cettia.asity.action.Actions;
import io.cettia.asity.action.SimpleActions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.util.List;
/*
 * Copyright 2018 the original author or authors.
 *
 * 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 io.cettia.asity.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/io/cettia/asity/action/Action.java
// @FunctionalInterface
// public interface Action<T> {
// 
//   /**
//    * Some action is taken.
//    */
//   void on(T object);
// 
// }
// 
// Path: action/src/main/java/io/cettia/asity/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/io/cettia/asity/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/io/cettia/asity/websocket/AbstractServerWebSocket.java
import io.cettia.asity.action.Action;
import io.cettia.asity.action.Actions;
import io.cettia.asity.action.SimpleActions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.util.List;

/*
 * Copyright 2018 the original author or authors.
 *
 * 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 io.cettia.asity.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() {
    closeActions.add($ -> state = State.CLOSED);