Home | History | Annotate | Download | only in jbosh
      1 /*
      2  * Copyright 2009 Mike Cumings
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.kenai.jbosh;
     18 
     19 import java.util.HashMap;
     20 import java.util.Map;
     21 
     22 /**
     23  * Terminal binding conditions and their associated messages.
     24  */
     25 final class TerminalBindingCondition {
     26 
     27     /**
     28      * Map of condition names to condition instances.
     29      */
     30     private static final Map<String, TerminalBindingCondition>
     31             COND_TO_INSTANCE = new HashMap<String, TerminalBindingCondition>();
     32 
     33     /**
     34      * Map of HTTP response codes to condition instances.
     35      */
     36     private static final Map<Integer, TerminalBindingCondition>
     37             CODE_TO_INSTANCE = new HashMap<Integer, TerminalBindingCondition>();
     38 
     39     static final TerminalBindingCondition BAD_REQUEST =
     40             createWithCode("bad-request", "The format of an HTTP header or "
     41             + "binding element received from the client is unacceptable "
     42             + "(e.g., syntax error).", Integer.valueOf(400));
     43 
     44     static final TerminalBindingCondition HOST_GONE =
     45             create("host-gone", "The target domain specified in the 'to' "
     46             + "attribute or the target host or port specified in the 'route' "
     47             + "attribute is no longer serviced by the connection manager.");
     48 
     49     static final TerminalBindingCondition HOST_UNKNOWN =
     50             create("host-unknown", "The target domain specified in the 'to' "
     51             + "attribute or the target host or port specified in the 'route' "
     52             + "attribute is unknown to the connection manager.");
     53 
     54     static final TerminalBindingCondition IMPROPER_ADDRESSING =
     55             create("improper-addressing", "The initialization element lacks a "
     56             + "'to' or 'route' attribute (or the attribute has no value) but "
     57             + "the connection manager requires one.");
     58 
     59     static final TerminalBindingCondition INTERNAL_SERVER_ERROR =
     60             create("internal-server-error", "The connection manager has "
     61             + "experienced an internal error that prevents it from servicing "
     62             + "the request.");
     63 
     64     static final TerminalBindingCondition ITEM_NOT_FOUND =
     65             createWithCode("item-not-found", "(1) 'sid' is not valid, (2) "
     66             + "'stream' is not valid, (3) 'rid' is larger than the upper limit "
     67             + "of the expected window, (4) connection manager is unable to "
     68             + "resend response, (5) 'key' sequence is invalid.",
     69             Integer.valueOf(404));
     70 
     71     static final TerminalBindingCondition OTHER_REQUEST =
     72             create("other-request", "Another request being processed at the "
     73             + "same time as this request caused the session to terminate.");
     74 
     75     static final TerminalBindingCondition POLICY_VIOLATION =
     76             createWithCode("policy-violation", "The client has broken the "
     77             + "session rules (polling too frequently, requesting too "
     78             + "frequently, sending too many simultaneous requests).",
     79             Integer.valueOf(403));
     80 
     81     static final TerminalBindingCondition REMOTE_CONNECTION_FAILED =
     82             create("remote-connection-failed", "The connection manager was "
     83             + "unable to connect to, or unable to connect securely to, or has "
     84             + "lost its connection to, the server.");
     85 
     86     static final TerminalBindingCondition REMOTE_STREAM_ERROR =
     87             create("remote-stream-error", "Encapsulated transport protocol "
     88             + "error.");
     89 
     90     static final TerminalBindingCondition SEE_OTHER_URI =
     91             create("see-other-uri", "The connection manager does not operate "
     92             + "at this URI (e.g., the connection manager accepts only SSL or "
     93             + "TLS connections at some https: URI rather than the http: URI "
     94             + "requested by the client).");
     95 
     96     static final TerminalBindingCondition SYSTEM_SHUTDOWN =
     97             create("system-shutdown", "The connection manager is being shut "
     98             + "down. All active HTTP sessions are being terminated. No new "
     99             + "sessions can be created.");
    100 
    101     static final TerminalBindingCondition UNDEFINED_CONDITION =
    102             create("undefined-condition", "Unknown or undefined error "
    103             + "condition.");
    104 
    105     /**
    106      * Condition name.
    107      */
    108     private final String cond;
    109 
    110     /**
    111      * Descriptive message.
    112      */
    113     private final String msg;
    114 
    115     /**
    116      * Private constructor to pre
    117      */
    118     private TerminalBindingCondition(
    119             final String condition,
    120             final String message) {
    121         cond = condition;
    122         msg = message;
    123     }
    124 
    125     /**
    126      * Helper method to call the helper method to add entries.
    127      */
    128     private static TerminalBindingCondition create(
    129             final String condition,
    130             final String message) {
    131         return createWithCode(condition, message, null);
    132     }
    133 
    134     /**
    135      * Helper method to add entries.
    136      */
    137     private static TerminalBindingCondition createWithCode(
    138             final String condition,
    139             final String message,
    140             final Integer code) {
    141         if (condition == null) {
    142             throw(new IllegalArgumentException(
    143                     "condition may not be null"));
    144         }
    145         if (message == null) {
    146             throw(new IllegalArgumentException(
    147                     "message may not be null"));
    148         }
    149         if (COND_TO_INSTANCE.get(condition) != null) {
    150             throw(new IllegalStateException(
    151                     "Multiple definitions of condition: " + condition));
    152         }
    153         TerminalBindingCondition result =
    154                 new TerminalBindingCondition(condition, message);
    155         COND_TO_INSTANCE.put(condition, result);
    156         if (code != null) {
    157             if (CODE_TO_INSTANCE.get(code) != null) {
    158                 throw(new IllegalStateException(
    159                         "Multiple definitions of code: " + code));
    160             }
    161             CODE_TO_INSTANCE.put(code, result);
    162         }
    163         return result;
    164     }
    165 
    166     /**
    167      * Lookup the terminal binding condition instance with the condition
    168      * name specified.
    169      *
    170      * @param condStr condition name
    171      * @return terminal binding condition instance, or {@code null} if no
    172      *  instance is known by the name specified
    173      */
    174     static TerminalBindingCondition forString(final String condStr) {
    175         return COND_TO_INSTANCE.get(condStr);
    176     }
    177 
    178     /**
    179      * Lookup the terminal binding condition instance associated with the
    180      * HTTP response code specified.
    181      *
    182      * @param httpRespCode HTTP response code
    183      * @return terminal binding condition instance, or {@code null} if no
    184      *  instance is known by the response code specified
    185      */
    186     static TerminalBindingCondition forHTTPResponseCode(final int httpRespCode) {
    187         return CODE_TO_INSTANCE.get(Integer.valueOf(httpRespCode));
    188     }
    189 
    190     /**
    191      * Get the name of the condition.
    192      *
    193      * @return condition name
    194      */
    195     String getCondition() {
    196         return cond;
    197     }
    198 
    199     /**
    200      * Get the human readable error message associated with this condition.
    201      *
    202      * @return error message
    203      */
    204     String getMessage() {
    205         return msg;
    206     }
    207 
    208 }
    209