init
This commit is contained in:
32
java/org/apache/tomcat/websocket/pojo/Constants.java
Normal file
32
java/org/apache/tomcat/websocket/pojo/Constants.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
/**
|
||||
* Internal implementation constants.
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
public static final String POJO_PATH_PARAM_KEY =
|
||||
"org.apache.tomcat.websocket.pojo.PojoEndpoint.pathParams";
|
||||
public static final String POJO_METHOD_MAPPING_KEY =
|
||||
"org.apache.tomcat.websocket.pojo.PojoEndpoint.methodMapping";
|
||||
|
||||
private Constants() {
|
||||
// Hide default constructor
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# 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.
|
||||
|
||||
pojoEndpointBase.closeSessionFail=Failed to close WebSocket session during error handling
|
||||
pojoEndpointBase.onCloseFail=Failed to call onClose method of POJO end point for POJO of type [{0}]
|
||||
pojoEndpointBase.onError=No error handling configured for [{0}] and the following error occurred
|
||||
pojoEndpointBase.onErrorFail=Failed to call onError method of POJO end point for POJO of type [{0}]
|
||||
pojoEndpointBase.onOpenFail=Failed to call onOpen method of POJO end point for POJO of type [{0}]
|
||||
|
||||
pojoEndpointServer.getPojoInstanceFail=Failed to create instance of POJO of type [{0}]
|
||||
|
||||
pojoMessageHandlerWhole.decodeIoFail=IO error while decoding message
|
||||
pojoMessageHandlerWhole.maxBufferSize=The maximum supported message size for this implementation is Integer.MAX_VALUE
|
||||
|
||||
pojoMethodMapping.decodePathParamFail=Failed to decode path parameter value [{0}] to expected type [{1}]
|
||||
pojoMethodMapping.duplicateAnnotation=Duplicate annotations [{0}] present on class [{1}]
|
||||
pojoMethodMapping.duplicateLastParam=Multiple boolean (last) parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.duplicateMessageParam=Multiple message parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.duplicatePongMessageParam=Multiple PongMessage parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.duplicateSessionParam=Multiple session parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.invalidDecoder=The specified decoder of type [{0}] could not be instantiated
|
||||
pojoMethodMapping.methodNotPublic=The annotated method [{0}] is not public
|
||||
pojoMethodMapping.noDecoder=No decoder was found for message parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.noPayload=No payload parameter present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.onErrorNoThrowable=No Throwable parameter was present on the method [{0}] of class [{1}] that was annotated with OnError
|
||||
pojoMethodMapping.paramWithoutAnnotation=A parameter of type [{0}] was found on method[{1}] of class [{2}] that did not have a @PathParam annotation
|
||||
pojoMethodMapping.partialInputStream=Invalid InputStream and boolean parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.partialObject=Invalid Object and boolean parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.partialPong=Invalid PongMessage and boolean parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.partialReader=Invalid Reader and boolean parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
pojoMethodMapping.pongWithPayload=Invalid PongMessage and Message parameters present on the method [{0}] of class [{1}] that was annotated with OnMessage
|
||||
|
||||
pojoPathParam.wrongType=The type [{0}] is not permitted as a path parameter. Parameters annotated with @PathParam may only be Strings, Java primitives or a boxed version thereof.
|
||||
@@ -0,0 +1,22 @@
|
||||
# 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.
|
||||
|
||||
pojoEndpointServer.getPojoInstanceFail=Es konnte keine POJO Instanz des Typs [{0}] erzeugt werden
|
||||
|
||||
pojoMethodMapping.duplicateAnnotation=Doppelte Annotation [{0}] an Klasse [{1}] gefunden
|
||||
pojoMethodMapping.duplicateLastParam=Es sind mehrere Boolean (letzte) Parameter für die Methode [{0}] der Klasse [{1}], die mit OnMessage annotiert ist, vorhanden.
|
||||
pojoMethodMapping.invalidDecoder=Der angegeben Dekoder vom Typ [{0}] konnte nicht instanziiert werden
|
||||
pojoMethodMapping.methodNotPublic=Die annotierite Methode [{0}] ist nicht öffentlich
|
||||
pojoMethodMapping.paramWithoutAnnotation=Es wurde ein Parameter des Typs [{0}] an der Methode [{1}] der Klasse [{2}] gefunden der nicht die Annotation @PathParam hat
|
||||
@@ -0,0 +1,24 @@
|
||||
# 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.
|
||||
|
||||
pojoEndpointBase.onCloseFail=Fallo al llamar el método onClose del endpoint POJO para el tipo POJO [{0}]
|
||||
pojoEndpointBase.onOpenFail=Fallo al llamar el método onOpen del end point POJO para el tipo POJO [{0}]\n
|
||||
|
||||
pojoEndpointServer.getPojoInstanceFail=Fallo al crear la instancia POJO de tipo [{0}]\n
|
||||
|
||||
pojoMethodMapping.duplicateAnnotation=Anotaciones duplicadas [{0}] presente en la clase [{1}]\n
|
||||
pojoMethodMapping.duplicatePongMessageParam=Varios parámetros de PongMessage estan presentes en el método [{0}] de la clase [{1}] que fue anotado con OnMessage
|
||||
pojoMethodMapping.invalidDecoder=El decodificador especificado de tipo [{0}] no puede ser instanciado\n
|
||||
pojoMethodMapping.onErrorNoThrowable=Parámetro no descartable estaba presente en el método [{0}] de clase [{1}] que fue apuntado con OnError
|
||||
@@ -0,0 +1,45 @@
|
||||
# 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.
|
||||
|
||||
pojoEndpointBase.closeSessionFail=Echec de fermeture de la session WebSocket pendant le traitement d'erreur
|
||||
pojoEndpointBase.onCloseFail=Echec lors de l''appel de la méthode onClose du point de terminaison POJO de type [{0}]
|
||||
pojoEndpointBase.onError=Aucun gestionnaire d''erreur n''est configuré pour [{0}] et l''erreur suivante s''est produite
|
||||
pojoEndpointBase.onErrorFail=Echec de l''appel de la méthode onError du point de terminaison POJO pour le type [{0}]
|
||||
pojoEndpointBase.onOpenFail=Impossible d’appeler la méthode onOpen du point de terminaison POJO de type [{0}]
|
||||
|
||||
pojoEndpointServer.getPojoInstanceFail=Échec de création d''une instance de POJO de type [{0}]
|
||||
|
||||
pojoMessageHandlerWhole.decodeIoFail=Erreur d'IO lors du décodage du message
|
||||
pojoMessageHandlerWhole.maxBufferSize=La taille maximale de message supportée par cette implémentation est Integer.MAX_VALUE
|
||||
|
||||
pojoMethodMapping.decodePathParamFail=Echec de décodage de la valeur de paramètre de chemin [{0}] vers le type attendu [{1}]
|
||||
pojoMethodMapping.duplicateAnnotation=Annotations dupliquées [{0}] présentes pour la classe [{1}]
|
||||
pojoMethodMapping.duplicateLastParam=Multiple (derniers) paramètres booléens présents sur la méthode [{0}] de classe [{1}], qui était annotée par OnMessage
|
||||
pojoMethodMapping.duplicateMessageParam=De multiples paramètres de message sont présents sur la méthode [{0}] de la classe [{1}] qui a été annotée avec OnMessage
|
||||
pojoMethodMapping.duplicatePongMessageParam=De multiples paramètres PongMessage sont présents sur la méthode [{0}] de la classe [{1}] qui a été annotée avec OnMessage
|
||||
pojoMethodMapping.duplicateSessionParam=De multiples paramètres de session sont présents sur la méthode [{0}] de la classe [{1}] qui a été annotée avec OnMessage
|
||||
pojoMethodMapping.invalidDecoder=Le décodeur de type [{0}] spécifié n''a pas pu être instantié
|
||||
pojoMethodMapping.methodNotPublic=La méthode [{0}] annotée n''est pas publique
|
||||
pojoMethodMapping.noDecoder=Aucun décodeur n''a été trouvé pour les paramètres de message présents sur la méthode [{0}] de la classe [{1}] qui a été annotée avec OnMessage
|
||||
pojoMethodMapping.noPayload=Pas de paramètre de données présent sur la méthode [{0}] de la classe [{1}] qui a été annotée par OnMessage
|
||||
pojoMethodMapping.onErrorNoThrowable=Aucun paramètre Throwable n''est présent sur la méthode [{0}] de la classe [{1}] qui est annotée par OnError
|
||||
pojoMethodMapping.paramWithoutAnnotation=Un paramètre de type [{0}] a été trouvé sur la méthode [{1}] de la classe [{2}] qui n''avait pas d''annotation @PathParam
|
||||
pojoMethodMapping.partialInputStream=L''InputStream et les paramètres booléens présents sur la méthode [{0}] de la classe [{1}] qui a été annotée par OnMessage sont invalides
|
||||
pojoMethodMapping.partialObject=L''objet et la paramètres booléens présents sur la méthode [{0}] de la classe [{1}] qui a été annotée par OnMessage sont invalides
|
||||
pojoMethodMapping.partialPong=Le PongMessage et les paramètres booléens présents sur la méthode [{0}] de la classe [{1}] qui a été annotée par OnMessage sont invalides
|
||||
pojoMethodMapping.partialReader=Le Reader et les paramètres booléens présents sur la méthode [{0}] de la classe [{1}] qui a été annotée par OnMessage sont invalides
|
||||
pojoMethodMapping.pongWithPayload=Le PongMessage et les paramètres de message présents sur la méthode [{0}] de la classe [{1}] qui a été annotée par OnMessage sont invalides
|
||||
|
||||
pojoPathParam.wrongType=Le type [{0}] n''est pas autorisé en tant que paramètre de chemin, les paramètres annotés avec @PathParm doivent être uniquement des String, des primitives Java ou des versions encapsulées de celles ci
|
||||
@@ -0,0 +1,45 @@
|
||||
# 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.
|
||||
|
||||
pojoEndpointBase.closeSessionFail=エラー処理中に WebSocket セッションを切断できませんでした。
|
||||
pojoEndpointBase.onCloseFail=タイプ[{0}]のPOJOのPOJOエンドポイントのonCloseメソッドの呼び出しに失敗しました
|
||||
pojoEndpointBase.onError=[{0}]に対してエラー処理が構成されておらず、次のエラーが発生しました。
|
||||
pojoEndpointBase.onErrorFail=タイプ[{0}]のPOJOのPOJOエンドポイントのonErrorメソッドの呼び出しに失敗しました
|
||||
pojoEndpointBase.onOpenFail=タイプ[{0}]のPOJOのPOJOエンドポイントのonOpenメソッドの呼び出しに失敗しました。
|
||||
|
||||
pojoEndpointServer.getPojoInstanceFail=POJO クラス [{0}] をインスタンス化できませんでした。
|
||||
|
||||
pojoMessageHandlerWhole.decodeIoFail=メッセージの復号中に入出力エラーが発生しました。
|
||||
pojoMessageHandlerWhole.maxBufferSize=この実装で対応可能なメッセージサイズの上限値は Integer.MAX_VALUE です。
|
||||
|
||||
pojoMethodMapping.decodePathParamFail=パスパラメータの値 [{0}] を [{1}] 型として解釈できません。
|
||||
pojoMethodMapping.duplicateAnnotation=クラス [{1}] にアノテーション [{0}] が重複しています。
|
||||
pojoMethodMapping.duplicateLastParam=OnMessageでアノテーション付けされたクラス[{1}]のメソッド[{0}]に複数のbooleanパラメータが存在します。
|
||||
pojoMethodMapping.duplicateMessageParam=OnMessage アノテーションで修飾されたクラス [{1}] のメソッド [{0}] に複数のメッセージパラメーターが存在します。
|
||||
pojoMethodMapping.duplicatePongMessageParam=OnMessageでアノテーションされたクラス[{1}]のメソッド[{0}]に複数のPongMessageパラメータが存在します。
|
||||
pojoMethodMapping.duplicateSessionParam=OnMessage アノテーションで修飾したクラス [{1}] のメソッド [{0}] に複数のセッションパラメーターが存在します。
|
||||
pojoMethodMapping.invalidDecoder=指定されたデコーダークラス [{0}] をインスタンス化できませんでした。
|
||||
pojoMethodMapping.methodNotPublic=アノテーション付きめそっぢがpublicではありません。
|
||||
pojoMethodMapping.noDecoder=OnMessageでアノテーションが付けられたクラス[{1}]のメソッド[{0}]に存在するメッセージパラメータのデコーダが見つかりませんでした。
|
||||
pojoMethodMapping.noPayload=OnMessage アノテーションで修飾されたクラス [{1}] のメソッド [{0}] にはペイロードに対応するパラメーターがありません。
|
||||
pojoMethodMapping.onErrorNoThrowable=OnErrorでアノテーション付けされたクラス[{1}]のメソッド[{0}]に、Throwableパラメータがありませんでした。
|
||||
pojoMethodMapping.paramWithoutAnnotation=@PathParamアノテーションを持たなかったクラス[{2}]のメソッド[{1}]に[{0}]型のパラメータが見つかりました
|
||||
pojoMethodMapping.partialInputStream=OnMessage アノテーションで修飾されたクラス [{1}] のメソッド [{0}] に入力ストリームと boolean の不正なパラメーターが存在します。
|
||||
pojoMethodMapping.partialObject=OnMessageでアノテーションされたクラス[{1}]のメソッド[{0}]に無効なオブジェクトおよびboolean パラメータがあります
|
||||
pojoMethodMapping.partialPong=OnMessageでアノテーション付けされたクラス[{1}]のメソッド[{0}]に存在するPongMessageパラメータおよびbooleanパラメータが無効です。
|
||||
pojoMethodMapping.partialReader=OnMessage アノテーションで修飾したクラス [{1}] のメソッド [{0}] に Reader および boolean の不正なパラメーターがあります。
|
||||
pojoMethodMapping.pongWithPayload=OnMessageでアノテーションが付けられたクラス[{1}]のメソッド[{0}]に、無効なPongMessageおよびMessageパラメータがあります。
|
||||
|
||||
pojoPathParam.wrongType=タイプ[{0}]はパスパラメータとして許可されていません。 @PathParamでアノテーションが付けられたパラメータは、文字列、Javaプリミティブ、またはそれらのボックス版のみです。
|
||||
@@ -0,0 +1,45 @@
|
||||
# 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.
|
||||
|
||||
pojoEndpointBase.closeSessionFail=오류 처리 중 웹소켓 세션을 닫지 못했습니다.
|
||||
pojoEndpointBase.onCloseFail=타입이 [{0}]인 POJO를 위한 POJO 엔드포인트의 onClose 메소드를 호출하지 못했습니다.
|
||||
pojoEndpointBase.onError=[{0}]을(를) 위한 오류 핸들링이 설정되지 않았으며, 다음과 같은 오류가 발생했습니다.
|
||||
pojoEndpointBase.onErrorFail=타입이 [{0}]인 POJO를 위한 POJO 엔드포인트의 onError를 호출하지 못했습니다.
|
||||
pojoEndpointBase.onOpenFail=타입이 [{0}]인 POJO를 위한, POJO 엔드포인트의 onOpen 메소드를 호출하지 못했습니다.
|
||||
|
||||
pojoEndpointServer.getPojoInstanceFail=타입이 [{0}]인 POJO 인스턴스를 생성하지 못했습니다.
|
||||
|
||||
pojoMessageHandlerWhole.decodeIoFail=메시지를 디코딩하는 중 IO 오류 발생
|
||||
pojoMessageHandlerWhole.maxBufferSize=이 구현을 위해 지원되는 최대 메시지 크기는 Integer.MAX_VALUE입니다.
|
||||
|
||||
pojoMethodMapping.decodePathParamFail=경로 파라미터 값 [{0}]을(를), 요구되는 타입 [{1}](으)로 디코드하지 못했습니다.
|
||||
pojoMethodMapping.duplicateAnnotation=중복된 [{0}] annotation들이 클래스 [{1}]에 존재합니다.
|
||||
pojoMethodMapping.duplicateLastParam=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에, 여러 개의 boolean 타입의 (마지막) 파라미터들이 존재합니다.
|
||||
pojoMethodMapping.duplicateMessageParam=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에 여러 개의 메시지 파라미터들이 존재합니다.
|
||||
pojoMethodMapping.duplicatePongMessageParam=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에 여러 개의 PongMessage 파라미터들이 존재합니다.
|
||||
pojoMethodMapping.duplicateSessionParam=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에 여러 개의 세션 파라미터들이 존재합니다.
|
||||
pojoMethodMapping.invalidDecoder=지정된 타입 [{0}]의 디코더를 생성할 수 없었습니다.
|
||||
pojoMethodMapping.methodNotPublic=Annotate된 메소드 [{0}]이(가) public 메소드가 아닙니다.
|
||||
pojoMethodMapping.noDecoder=클래스 [{1}]에서, OnMessage로 annotate된 메소드 [{0}]에 존재하는 메시지 파라미터들을 위한 디코더를 찾을 수 없습니다.
|
||||
pojoMethodMapping.noPayload=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에, payload 파라미터가 존재하지 않습니다.
|
||||
pojoMethodMapping.onErrorNoThrowable=OnError로 annotate된 클래스 [{1}]의 메소드 [{0}]에 Throwable 파라미터가 없습니다.
|
||||
pojoMethodMapping.paramWithoutAnnotation=@PathParam으로 annotate 되지 않은 클래스 [{2}]의 메소드 [{1}]에서, 타입이 [{0}]인 파라미터가 발견되었습니다.
|
||||
pojoMethodMapping.partialInputStream=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에 유효하지 않은 InputStream과 boolean 파라미터들이 존재합니다.
|
||||
pojoMethodMapping.partialObject=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에 유효하지 않은 Object와 boolean 파라미터들이 존재합니다.
|
||||
pojoMethodMapping.partialPong=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에 존재하는 PongMessage와 boolean 파라미터들은 유효하지 않습니다.
|
||||
pojoMethodMapping.partialReader=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에, 유효하지 않은 Reader와 boolean 파라미터들이 존재합니다.
|
||||
pojoMethodMapping.pongWithPayload=OnMessage로 annotate된 클래스 [{1}]의 메소드 [{0}]에 존재하는 PongMessage와 Message 파라미터들은 유효하지 않습니다.
|
||||
|
||||
pojoPathParam.wrongType=타입 [{0}]은(는) 경로 파라미터로서 허용되지 않습니다. @PathParam으로 annotate된 파라미터들은 오직 문자열들, 또는 자바 원시타입들 또는 그것들의 박싱된 버전들이어야 합니다.
|
||||
@@ -0,0 +1,16 @@
|
||||
# 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.
|
||||
|
||||
pojoMethodMapping.duplicateAnnotation=Аналогичная аннотация [{0}] существует в классе [{1}]
|
||||
@@ -0,0 +1,35 @@
|
||||
# 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.
|
||||
|
||||
pojoEndpointBase.onCloseFail=):无法为类型为[{0}]的POJO调用POJO端点的onClose方法
|
||||
pojoEndpointBase.onError=在错误发生后,没有为[{0}]配置错误处理
|
||||
pojoEndpointBase.onOpenFail=无法为类型为[{0}]的POJO调用POJO端点的onOpen方法
|
||||
|
||||
pojoEndpointServer.getPojoInstanceFail=创建类型为 [{0}] 的 POJO 实例失败
|
||||
|
||||
pojoMessageHandlerWhole.decodeIoFail=解码消息时出现IO错误
|
||||
|
||||
pojoMethodMapping.duplicateAnnotation=类[{1}]上存在的重复注释[{0}]
|
||||
pojoMethodMapping.duplicateLastParam=用OnMessage注释的类[{1}]的方法[{0}]上存在多个布尔参数(最后的)
|
||||
pojoMethodMapping.duplicatePongMessageParam=使用OnMessage注释的类[{1}]的方法[{0}]上存在多个PongMessage参数
|
||||
pojoMethodMapping.invalidDecoder=这个特定类型的解码器[{0}]无法被实例化
|
||||
pojoMethodMapping.methodNotPublic=注解方法[{0}]不为公共方法
|
||||
pojoMethodMapping.noDecoder=在用onMessage注释的类[{1}]的方法[{0}]上找不到消息参数的解码器。
|
||||
pojoMethodMapping.onErrorNoThrowable=):类[{1}]的方法[{0}]上不存在用OnError注释的抛出参数
|
||||
pojoMethodMapping.paramWithoutAnnotation=在类[{2}]的方法[{1}]上找到了类型为[{0}]的参数,该方法没有@PathParam 注释
|
||||
pojoMethodMapping.partialObject=用onMessage注释的类[{1}]的方法[{0}]中存在无效的对象和布尔参数
|
||||
pojoMethodMapping.pongWithPayload=类[{1}]的方法[{0}]中存在无效的PongMessage 和消息参数,该方法是用onMessage注释的
|
||||
|
||||
pojoPathParam.wrongType=不允许将类型[{0}]作为路径参数。用@PathParam注释的参数只能是字符串、Java原语或盒装版本。
|
||||
156
java/org/apache/tomcat/websocket/pojo/PojoEndpointBase.java
Normal file
156
java/org/apache/tomcat/websocket/pojo/PojoEndpointBase.java
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.MessageHandler;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
import org.apache.tomcat.util.ExceptionUtils;
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
/**
|
||||
* Base implementation (client and server have different concrete
|
||||
* implementations) of the wrapper that converts a POJO instance into a
|
||||
* WebSocket endpoint instance.
|
||||
*/
|
||||
public abstract class PojoEndpointBase extends Endpoint {
|
||||
|
||||
private final Log log = LogFactory.getLog(PojoEndpointBase.class); // must not be static
|
||||
private static final StringManager sm = StringManager.getManager(PojoEndpointBase.class);
|
||||
|
||||
private Object pojo;
|
||||
private Map<String,String> pathParameters;
|
||||
private PojoMethodMapping methodMapping;
|
||||
|
||||
|
||||
protected final void doOnOpen(Session session, EndpointConfig config) {
|
||||
PojoMethodMapping methodMapping = getMethodMapping();
|
||||
Object pojo = getPojo();
|
||||
Map<String,String> pathParameters = getPathParameters();
|
||||
|
||||
// Add message handlers before calling onOpen since that may trigger a
|
||||
// message which in turn could trigger a response and/or close the
|
||||
// session
|
||||
for (MessageHandler mh : methodMapping.getMessageHandlers(pojo,
|
||||
pathParameters, session, config)) {
|
||||
session.addMessageHandler(mh);
|
||||
}
|
||||
|
||||
if (methodMapping.getOnOpen() != null) {
|
||||
try {
|
||||
methodMapping.getOnOpen().invoke(pojo,
|
||||
methodMapping.getOnOpenArgs(
|
||||
pathParameters, session, config));
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
// Reflection related problems
|
||||
log.error(sm.getString(
|
||||
"pojoEndpointBase.onOpenFail",
|
||||
pojo.getClass().getName()), e);
|
||||
handleOnOpenOrCloseError(session, e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
handleOnOpenOrCloseError(session, cause);
|
||||
} catch (Throwable t) {
|
||||
handleOnOpenOrCloseError(session, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void handleOnOpenOrCloseError(Session session, Throwable t) {
|
||||
// If really fatal - re-throw
|
||||
ExceptionUtils.handleThrowable(t);
|
||||
|
||||
// Trigger the error handler and close the session
|
||||
onError(session, t);
|
||||
try {
|
||||
session.close();
|
||||
} catch (IOException ioe) {
|
||||
log.warn(sm.getString("pojoEndpointBase.closeSessionFail"), ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onClose(Session session, CloseReason closeReason) {
|
||||
|
||||
if (methodMapping.getOnClose() != null) {
|
||||
try {
|
||||
methodMapping.getOnClose().invoke(pojo,
|
||||
methodMapping.getOnCloseArgs(pathParameters, session, closeReason));
|
||||
} catch (Throwable t) {
|
||||
log.error(sm.getString("pojoEndpointBase.onCloseFail",
|
||||
pojo.getClass().getName()), t);
|
||||
handleOnOpenOrCloseError(session, t);
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger the destroy method for any associated decoders
|
||||
Set<MessageHandler> messageHandlers = session.getMessageHandlers();
|
||||
for (MessageHandler messageHandler : messageHandlers) {
|
||||
if (messageHandler instanceof PojoMessageHandlerWholeBase<?>) {
|
||||
((PojoMessageHandlerWholeBase<?>) messageHandler).onClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void onError(Session session, Throwable throwable) {
|
||||
|
||||
if (methodMapping.getOnError() == null) {
|
||||
log.error(sm.getString("pojoEndpointBase.onError",
|
||||
pojo.getClass().getName()), throwable);
|
||||
} else {
|
||||
try {
|
||||
methodMapping.getOnError().invoke(
|
||||
pojo,
|
||||
methodMapping.getOnErrorArgs(pathParameters, session,
|
||||
throwable));
|
||||
} catch (Throwable t) {
|
||||
ExceptionUtils.handleThrowable(t);
|
||||
log.error(sm.getString("pojoEndpointBase.onErrorFail",
|
||||
pojo.getClass().getName()), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Object getPojo() { return pojo; }
|
||||
protected void setPojo(Object pojo) { this.pojo = pojo; }
|
||||
|
||||
|
||||
protected Map<String,String> getPathParameters() { return pathParameters; }
|
||||
protected void setPathParameters(Map<String,String> pathParameters) {
|
||||
this.pathParameters = pathParameters;
|
||||
}
|
||||
|
||||
|
||||
protected PojoMethodMapping getMethodMapping() { return methodMapping; }
|
||||
protected void setMethodMapping(PojoMethodMapping methodMapping) {
|
||||
this.methodMapping = methodMapping;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.Session;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper class for instances of POJOs annotated with
|
||||
* {@link javax.websocket.ClientEndpoint} so they appear as standard
|
||||
* {@link javax.websocket.Endpoint} instances.
|
||||
*/
|
||||
public class PojoEndpointClient extends PojoEndpointBase {
|
||||
|
||||
public PojoEndpointClient(Object pojo,
|
||||
List<Class<? extends Decoder>> decoders) throws DeploymentException {
|
||||
setPojo(pojo);
|
||||
setMethodMapping(
|
||||
new PojoMethodMapping(pojo.getClass(), decoders, null));
|
||||
setPathParameters(Collections.<String,String>emptyMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
doOnOpen(session, config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.server.ServerEndpointConfig;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
/**
|
||||
* Wrapper class for instances of POJOs annotated with
|
||||
* {@link javax.websocket.server.ServerEndpoint} so they appear as standard
|
||||
* {@link javax.websocket.Endpoint} instances.
|
||||
*/
|
||||
public class PojoEndpointServer extends PojoEndpointBase {
|
||||
|
||||
private static final StringManager sm =
|
||||
StringManager.getManager(PojoEndpointServer.class);
|
||||
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig endpointConfig) {
|
||||
|
||||
ServerEndpointConfig sec = (ServerEndpointConfig) endpointConfig;
|
||||
|
||||
Object pojo;
|
||||
try {
|
||||
pojo = sec.getConfigurator().getEndpointInstance(
|
||||
sec.getEndpointClass());
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalArgumentException(sm.getString(
|
||||
"pojoEndpointServer.getPojoInstanceFail",
|
||||
sec.getEndpointClass().getName()), e);
|
||||
}
|
||||
setPojo(pojo);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String,String> pathParameters =
|
||||
(Map<String, String>) sec.getUserProperties().get(
|
||||
Constants.POJO_PATH_PARAM_KEY);
|
||||
setPathParameters(pathParameters);
|
||||
|
||||
PojoMethodMapping methodMapping =
|
||||
(PojoMethodMapping) sec.getUserProperties().get(
|
||||
Constants.POJO_METHOD_MAPPING_KEY);
|
||||
setMethodMapping(methodMapping);
|
||||
|
||||
doOnOpen(session, endpointConfig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.websocket.EncodeException;
|
||||
import javax.websocket.MessageHandler;
|
||||
import javax.websocket.RemoteEndpoint;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.apache.tomcat.util.ExceptionUtils;
|
||||
import org.apache.tomcat.websocket.WrappedMessageHandler;
|
||||
|
||||
/**
|
||||
* Common implementation code for the POJO message handlers.
|
||||
*
|
||||
* @param <T> The type of message to handle
|
||||
*/
|
||||
public abstract class PojoMessageHandlerBase<T>
|
||||
implements WrappedMessageHandler {
|
||||
|
||||
protected final Object pojo;
|
||||
protected final Method method;
|
||||
protected final Session session;
|
||||
protected final Object[] params;
|
||||
protected final int indexPayload;
|
||||
protected final boolean convert;
|
||||
protected final int indexSession;
|
||||
protected final long maxMessageSize;
|
||||
|
||||
public PojoMessageHandlerBase(Object pojo, Method method,
|
||||
Session session, Object[] params, int indexPayload, boolean convert,
|
||||
int indexSession, long maxMessageSize) {
|
||||
this.pojo = pojo;
|
||||
this.method = method;
|
||||
// TODO: The method should already be accessible here but the following
|
||||
// code seems to be necessary in some as yet not fully understood cases.
|
||||
try {
|
||||
this.method.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
// It is better to make sure the method is accessible, but
|
||||
// ignore exceptions and hope for the best
|
||||
}
|
||||
this.session = session;
|
||||
this.params = params;
|
||||
this.indexPayload = indexPayload;
|
||||
this.convert = convert;
|
||||
this.indexSession = indexSession;
|
||||
this.maxMessageSize = maxMessageSize;
|
||||
}
|
||||
|
||||
|
||||
protected final void processResult(Object result) {
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RemoteEndpoint.Basic remoteEndpoint = session.getBasicRemote();
|
||||
try {
|
||||
if (result instanceof String) {
|
||||
remoteEndpoint.sendText((String) result);
|
||||
} else if (result instanceof ByteBuffer) {
|
||||
remoteEndpoint.sendBinary((ByteBuffer) result);
|
||||
} else if (result instanceof byte[]) {
|
||||
remoteEndpoint.sendBinary(ByteBuffer.wrap((byte[]) result));
|
||||
} else {
|
||||
remoteEndpoint.sendObject(result);
|
||||
}
|
||||
} catch (IOException | EncodeException ioe) {
|
||||
throw new IllegalStateException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expose the POJO if it is a message handler so the Session is able to
|
||||
* match requests to remove handlers if the original handler has been
|
||||
* wrapped.
|
||||
*/
|
||||
@Override
|
||||
public final MessageHandler getWrappedHandler() {
|
||||
if (pojo instanceof MessageHandler) {
|
||||
return (MessageHandler) pojo;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final long getMaxMessageSize() {
|
||||
return maxMessageSize;
|
||||
}
|
||||
|
||||
|
||||
protected final void handlePojoMethodException(Throwable t) {
|
||||
t = ExceptionUtils.unwrapInvocationTargetException(t);
|
||||
ExceptionUtils.handleThrowable(t);
|
||||
if (t instanceof RuntimeException) {
|
||||
throw (RuntimeException) t;
|
||||
} else {
|
||||
throw new RuntimeException(t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.MessageHandler;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.apache.tomcat.websocket.WsSession;
|
||||
|
||||
/**
|
||||
* Common implementation code for the POJO partial message handlers. All
|
||||
* the real work is done in this class and in the superclass.
|
||||
*
|
||||
* @param <T> The type of message to handle
|
||||
*/
|
||||
public abstract class PojoMessageHandlerPartialBase<T>
|
||||
extends PojoMessageHandlerBase<T> implements MessageHandler.Partial<T> {
|
||||
|
||||
private final int indexBoolean;
|
||||
|
||||
public PojoMessageHandlerPartialBase(Object pojo, Method method,
|
||||
Session session, Object[] params, int indexPayload,
|
||||
boolean convert, int indexBoolean, int indexSession,
|
||||
long maxMessageSize) {
|
||||
super(pojo, method, session, params, indexPayload, convert,
|
||||
indexSession, maxMessageSize);
|
||||
this.indexBoolean = indexBoolean;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void onMessage(T message, boolean last) {
|
||||
if (params.length == 1 && params[0] instanceof DecodeException) {
|
||||
((WsSession) session).getLocal().onError(session,
|
||||
(DecodeException) params[0]);
|
||||
return;
|
||||
}
|
||||
Object[] parameters = params.clone();
|
||||
if (indexBoolean != -1) {
|
||||
parameters[indexBoolean] = Boolean.valueOf(last);
|
||||
}
|
||||
if (indexSession != -1) {
|
||||
parameters[indexSession] = session;
|
||||
}
|
||||
if (convert) {
|
||||
parameters[indexPayload] = ((ByteBuffer) message).array();
|
||||
} else {
|
||||
parameters[indexPayload] = message;
|
||||
}
|
||||
Object result = null;
|
||||
try {
|
||||
result = method.invoke(pojo, parameters);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
handlePojoMethodException(e);
|
||||
}
|
||||
processResult(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.websocket.Session;
|
||||
|
||||
/**
|
||||
* ByteBuffer specific concrete implementation for handling partial messages.
|
||||
*/
|
||||
public class PojoMessageHandlerPartialBinary
|
||||
extends PojoMessageHandlerPartialBase<ByteBuffer> {
|
||||
|
||||
public PojoMessageHandlerPartialBinary(Object pojo, Method method,
|
||||
Session session, Object[] params, int indexPayload, boolean convert,
|
||||
int indexBoolean, int indexSession, long maxMessageSize) {
|
||||
super(pojo, method, session, params, indexPayload, convert, indexBoolean,
|
||||
indexSession, maxMessageSize);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.websocket.Session;
|
||||
|
||||
/**
|
||||
* Text specific concrete implementation for handling partial messages.
|
||||
*/
|
||||
public class PojoMessageHandlerPartialText
|
||||
extends PojoMessageHandlerPartialBase<String> {
|
||||
|
||||
public PojoMessageHandlerPartialText(Object pojo, Method method,
|
||||
Session session, Object[] params, int indexPayload, boolean convert,
|
||||
int indexBoolean, int indexSession, long maxMessageSize) {
|
||||
super(pojo, method, session, params, indexPayload, convert, indexBoolean,
|
||||
indexSession, maxMessageSize);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.MessageHandler;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.apache.tomcat.websocket.WsSession;
|
||||
|
||||
/**
|
||||
* Common implementation code for the POJO whole message handlers. All the real
|
||||
* work is done in this class and in the superclass.
|
||||
*
|
||||
* @param <T> The type of message to handle
|
||||
*/
|
||||
public abstract class PojoMessageHandlerWholeBase<T>
|
||||
extends PojoMessageHandlerBase<T> implements MessageHandler.Whole<T> {
|
||||
|
||||
public PojoMessageHandlerWholeBase(Object pojo, Method method,
|
||||
Session session, Object[] params, int indexPayload,
|
||||
boolean convert, int indexSession, long maxMessageSize) {
|
||||
super(pojo, method, session, params, indexPayload, convert,
|
||||
indexSession, maxMessageSize);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void onMessage(T message) {
|
||||
|
||||
if (params.length == 1 && params[0] instanceof DecodeException) {
|
||||
((WsSession) session).getLocal().onError(session,
|
||||
(DecodeException) params[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Can this message be decoded?
|
||||
Object payload;
|
||||
try {
|
||||
payload = decode(message);
|
||||
} catch (DecodeException de) {
|
||||
((WsSession) session).getLocal().onError(session, de);
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload == null) {
|
||||
// Not decoded. Convert if required.
|
||||
if (convert) {
|
||||
payload = convert(message);
|
||||
} else {
|
||||
payload = message;
|
||||
}
|
||||
}
|
||||
|
||||
Object[] parameters = params.clone();
|
||||
if (indexSession != -1) {
|
||||
parameters[indexSession] = session;
|
||||
}
|
||||
parameters[indexPayload] = payload;
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
result = method.invoke(pojo, parameters);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
handlePojoMethodException(e);
|
||||
}
|
||||
processResult(result);
|
||||
}
|
||||
|
||||
protected Object convert(T message) {
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
protected abstract Object decode(T message) throws DecodeException;
|
||||
protected abstract void onClose();
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.Decoder.Binary;
|
||||
import javax.websocket.Decoder.BinaryStream;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
/**
|
||||
* ByteBuffer specific concrete implementation for handling whole messages.
|
||||
*/
|
||||
public class PojoMessageHandlerWholeBinary
|
||||
extends PojoMessageHandlerWholeBase<ByteBuffer> {
|
||||
|
||||
private static final StringManager sm =
|
||||
StringManager.getManager(PojoMessageHandlerWholeBinary.class);
|
||||
|
||||
private final List<Decoder> decoders = new ArrayList<>();
|
||||
|
||||
private final boolean isForInputStream;
|
||||
|
||||
public PojoMessageHandlerWholeBinary(Object pojo, Method method,
|
||||
Session session, EndpointConfig config,
|
||||
List<Class<? extends Decoder>> decoderClazzes, Object[] params,
|
||||
int indexPayload, boolean convert, int indexSession,
|
||||
boolean isForInputStream, long maxMessageSize) {
|
||||
super(pojo, method, session, params, indexPayload, convert,
|
||||
indexSession, maxMessageSize);
|
||||
|
||||
// Update binary text size handled by session
|
||||
if (maxMessageSize > -1 && maxMessageSize > session.getMaxBinaryMessageBufferSize()) {
|
||||
if (maxMessageSize > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException(sm.getString(
|
||||
"pojoMessageHandlerWhole.maxBufferSize"));
|
||||
}
|
||||
session.setMaxBinaryMessageBufferSize((int) maxMessageSize);
|
||||
}
|
||||
|
||||
try {
|
||||
if (decoderClazzes != null) {
|
||||
for (Class<? extends Decoder> decoderClazz : decoderClazzes) {
|
||||
if (Binary.class.isAssignableFrom(decoderClazz)) {
|
||||
Binary<?> decoder = (Binary<?>) decoderClazz.getConstructor().newInstance();
|
||||
decoder.init(config);
|
||||
decoders.add(decoder);
|
||||
} else if (BinaryStream.class.isAssignableFrom(
|
||||
decoderClazz)) {
|
||||
BinaryStream<?> decoder = (BinaryStream<?>)
|
||||
decoderClazz.getConstructor().newInstance();
|
||||
decoder.init(config);
|
||||
decoders.add(decoder);
|
||||
} else {
|
||||
// Text decoder - ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
this.isForInputStream = isForInputStream;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object decode(ByteBuffer message) throws DecodeException {
|
||||
for (Decoder decoder : decoders) {
|
||||
if (decoder instanceof Binary) {
|
||||
if (((Binary<?>) decoder).willDecode(message)) {
|
||||
return ((Binary<?>) decoder).decode(message);
|
||||
}
|
||||
} else {
|
||||
byte[] array = new byte[message.limit() - message.position()];
|
||||
message.get(array);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(array);
|
||||
try {
|
||||
return ((BinaryStream<?>) decoder).decode(bais);
|
||||
} catch (IOException ioe) {
|
||||
throw new DecodeException(message, sm.getString(
|
||||
"pojoMessageHandlerWhole.decodeIoFail"), ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object convert(ByteBuffer message) {
|
||||
byte[] array = new byte[message.remaining()];
|
||||
message.get(array);
|
||||
if (isForInputStream) {
|
||||
return new ByteArrayInputStream(array);
|
||||
} else {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onClose() {
|
||||
for (Decoder decoder : decoders) {
|
||||
decoder.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.websocket.PongMessage;
|
||||
import javax.websocket.Session;
|
||||
|
||||
/**
|
||||
* PongMessage specific concrete implementation for handling whole messages.
|
||||
*/
|
||||
public class PojoMessageHandlerWholePong
|
||||
extends PojoMessageHandlerWholeBase<PongMessage> {
|
||||
|
||||
public PojoMessageHandlerWholePong(Object pojo, Method method,
|
||||
Session session, Object[] params, int indexPayload, boolean convert,
|
||||
int indexSession) {
|
||||
super(pojo, method, session, params, indexPayload, convert,
|
||||
indexSession, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object decode(PongMessage message) {
|
||||
// Never decoded
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onClose() {
|
||||
// NO-OP
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.Decoder.Text;
|
||||
import javax.websocket.Decoder.TextStream;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
import org.apache.tomcat.websocket.Util;
|
||||
|
||||
|
||||
/**
|
||||
* Text specific concrete implementation for handling whole messages.
|
||||
*/
|
||||
public class PojoMessageHandlerWholeText
|
||||
extends PojoMessageHandlerWholeBase<String> {
|
||||
|
||||
private static final StringManager sm =
|
||||
StringManager.getManager(PojoMessageHandlerWholeText.class);
|
||||
|
||||
private final List<Decoder> decoders = new ArrayList<>();
|
||||
private final Class<?> primitiveType;
|
||||
|
||||
public PojoMessageHandlerWholeText(Object pojo, Method method,
|
||||
Session session, EndpointConfig config,
|
||||
List<Class<? extends Decoder>> decoderClazzes, Object[] params,
|
||||
int indexPayload, boolean convert, int indexSession,
|
||||
long maxMessageSize) {
|
||||
super(pojo, method, session, params, indexPayload, convert,
|
||||
indexSession, maxMessageSize);
|
||||
|
||||
// Update max text size handled by session
|
||||
if (maxMessageSize > -1 && maxMessageSize > session.getMaxTextMessageBufferSize()) {
|
||||
if (maxMessageSize > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException(sm.getString(
|
||||
"pojoMessageHandlerWhole.maxBufferSize"));
|
||||
}
|
||||
session.setMaxTextMessageBufferSize((int) maxMessageSize);
|
||||
}
|
||||
|
||||
// Check for primitives
|
||||
Class<?> type = method.getParameterTypes()[indexPayload];
|
||||
if (Util.isPrimitive(type)) {
|
||||
primitiveType = type;
|
||||
return;
|
||||
} else {
|
||||
primitiveType = null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (decoderClazzes != null) {
|
||||
for (Class<? extends Decoder> decoderClazz : decoderClazzes) {
|
||||
if (Text.class.isAssignableFrom(decoderClazz)) {
|
||||
Text<?> decoder = (Text<?>) decoderClazz.getConstructor().newInstance();
|
||||
decoder.init(config);
|
||||
decoders.add(decoder);
|
||||
} else if (TextStream.class.isAssignableFrom(
|
||||
decoderClazz)) {
|
||||
TextStream<?> decoder =
|
||||
(TextStream<?>) decoderClazz.getConstructor().newInstance();
|
||||
decoder.init(config);
|
||||
decoders.add(decoder);
|
||||
} else {
|
||||
// Binary decoder - ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object decode(String message) throws DecodeException {
|
||||
// Handle primitives
|
||||
if (primitiveType != null) {
|
||||
return Util.coerceToType(primitiveType, message);
|
||||
}
|
||||
// Handle full decoders
|
||||
for (Decoder decoder : decoders) {
|
||||
if (decoder instanceof Text) {
|
||||
if (((Text<?>) decoder).willDecode(message)) {
|
||||
return ((Text<?>) decoder).decode(message);
|
||||
}
|
||||
} else {
|
||||
StringReader r = new StringReader(message);
|
||||
try {
|
||||
return ((TextStream<?>) decoder).decode(r);
|
||||
} catch (IOException ioe) {
|
||||
throw new DecodeException(message, sm.getString(
|
||||
"pojoMessageHandlerWhole.decodeIoFail"), ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object convert(String message) {
|
||||
return new StringReader(message);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onClose() {
|
||||
for (Decoder decoder : decoders) {
|
||||
decoder.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
725
java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java
Normal file
725
java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java
Normal file
@@ -0,0 +1,725 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.MessageHandler;
|
||||
import javax.websocket.OnClose;
|
||||
import javax.websocket.OnError;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.PongMessage;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.server.PathParam;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
import org.apache.tomcat.websocket.DecoderEntry;
|
||||
import org.apache.tomcat.websocket.Util;
|
||||
import org.apache.tomcat.websocket.Util.DecoderMatch;
|
||||
|
||||
/**
|
||||
* For a POJO class annotated with
|
||||
* {@link javax.websocket.server.ServerEndpoint}, an instance of this class
|
||||
* creates and caches the method handler, method information and parameter
|
||||
* information for the onXXX calls.
|
||||
*/
|
||||
public class PojoMethodMapping {
|
||||
|
||||
private static final StringManager sm =
|
||||
StringManager.getManager(PojoMethodMapping.class);
|
||||
|
||||
private final Method onOpen;
|
||||
private final Method onClose;
|
||||
private final Method onError;
|
||||
private final PojoPathParam[] onOpenParams;
|
||||
private final PojoPathParam[] onCloseParams;
|
||||
private final PojoPathParam[] onErrorParams;
|
||||
private final List<MessageHandlerInfo> onMessage = new ArrayList<>();
|
||||
private final String wsPath;
|
||||
|
||||
|
||||
public PojoMethodMapping(Class<?> clazzPojo,
|
||||
List<Class<? extends Decoder>> decoderClazzes, String wsPath)
|
||||
throws DeploymentException {
|
||||
|
||||
this.wsPath = wsPath;
|
||||
|
||||
List<DecoderEntry> decoders = Util.getDecoders(decoderClazzes);
|
||||
Method open = null;
|
||||
Method close = null;
|
||||
Method error = null;
|
||||
Method[] clazzPojoMethods = null;
|
||||
Class<?> currentClazz = clazzPojo;
|
||||
while (!currentClazz.equals(Object.class)) {
|
||||
Method[] currentClazzMethods = currentClazz.getDeclaredMethods();
|
||||
if (currentClazz == clazzPojo) {
|
||||
clazzPojoMethods = currentClazzMethods;
|
||||
}
|
||||
for (Method method : currentClazzMethods) {
|
||||
if (method.isSynthetic()) {
|
||||
// Skip all synthetic methods.
|
||||
// They may have copies of annotations from methods we are
|
||||
// interested in and they will use the wrong parameter type
|
||||
// (they always use Object) so we can't used them here.
|
||||
continue;
|
||||
}
|
||||
if (method.getAnnotation(OnOpen.class) != null) {
|
||||
checkPublic(method);
|
||||
if (open == null) {
|
||||
open = method;
|
||||
} else {
|
||||
if (currentClazz == clazzPojo ||
|
||||
!isMethodOverride(open, method)) {
|
||||
// Duplicate annotation
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateAnnotation",
|
||||
OnOpen.class, currentClazz));
|
||||
}
|
||||
}
|
||||
} else if (method.getAnnotation(OnClose.class) != null) {
|
||||
checkPublic(method);
|
||||
if (close == null) {
|
||||
close = method;
|
||||
} else {
|
||||
if (currentClazz == clazzPojo ||
|
||||
!isMethodOverride(close, method)) {
|
||||
// Duplicate annotation
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateAnnotation",
|
||||
OnClose.class, currentClazz));
|
||||
}
|
||||
}
|
||||
} else if (method.getAnnotation(OnError.class) != null) {
|
||||
checkPublic(method);
|
||||
if (error == null) {
|
||||
error = method;
|
||||
} else {
|
||||
if (currentClazz == clazzPojo ||
|
||||
!isMethodOverride(error, method)) {
|
||||
// Duplicate annotation
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateAnnotation",
|
||||
OnError.class, currentClazz));
|
||||
}
|
||||
}
|
||||
} else if (method.getAnnotation(OnMessage.class) != null) {
|
||||
checkPublic(method);
|
||||
MessageHandlerInfo messageHandler = new MessageHandlerInfo(method, decoders);
|
||||
boolean found = false;
|
||||
for (MessageHandlerInfo otherMessageHandler : onMessage) {
|
||||
if (messageHandler.targetsSameWebSocketMessageType(otherMessageHandler)) {
|
||||
found = true;
|
||||
if (currentClazz == clazzPojo ||
|
||||
!isMethodOverride(messageHandler.m, otherMessageHandler.m)) {
|
||||
// Duplicate annotation
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateAnnotation",
|
||||
OnMessage.class, currentClazz));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
onMessage.add(messageHandler);
|
||||
}
|
||||
} else {
|
||||
// Method not annotated
|
||||
}
|
||||
}
|
||||
currentClazz = currentClazz.getSuperclass();
|
||||
}
|
||||
// If the methods are not on clazzPojo and they are overridden
|
||||
// by a non annotated method in clazzPojo, they should be ignored
|
||||
if (open != null && open.getDeclaringClass() != clazzPojo) {
|
||||
if (isOverridenWithoutAnnotation(clazzPojoMethods, open, OnOpen.class)) {
|
||||
open = null;
|
||||
}
|
||||
}
|
||||
if (close != null && close.getDeclaringClass() != clazzPojo) {
|
||||
if (isOverridenWithoutAnnotation(clazzPojoMethods, close, OnClose.class)) {
|
||||
close = null;
|
||||
}
|
||||
}
|
||||
if (error != null && error.getDeclaringClass() != clazzPojo) {
|
||||
if (isOverridenWithoutAnnotation(clazzPojoMethods, error, OnError.class)) {
|
||||
error = null;
|
||||
}
|
||||
}
|
||||
List<MessageHandlerInfo> overriddenOnMessage = new ArrayList<>();
|
||||
for (MessageHandlerInfo messageHandler : onMessage) {
|
||||
if (messageHandler.m.getDeclaringClass() != clazzPojo
|
||||
&& isOverridenWithoutAnnotation(clazzPojoMethods, messageHandler.m, OnMessage.class)) {
|
||||
overriddenOnMessage.add(messageHandler);
|
||||
}
|
||||
}
|
||||
for (MessageHandlerInfo messageHandler : overriddenOnMessage) {
|
||||
onMessage.remove(messageHandler);
|
||||
}
|
||||
this.onOpen = open;
|
||||
this.onClose = close;
|
||||
this.onError = error;
|
||||
onOpenParams = getPathParams(onOpen, MethodType.ON_OPEN);
|
||||
onCloseParams = getPathParams(onClose, MethodType.ON_CLOSE);
|
||||
onErrorParams = getPathParams(onError, MethodType.ON_ERROR);
|
||||
}
|
||||
|
||||
|
||||
private void checkPublic(Method m) throws DeploymentException {
|
||||
if (!Modifier.isPublic(m.getModifiers())) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.methodNotPublic", m.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isMethodOverride(Method method1, Method method2) {
|
||||
return method1.getName().equals(method2.getName())
|
||||
&& method1.getReturnType().equals(method2.getReturnType())
|
||||
&& Arrays.equals(method1.getParameterTypes(), method2.getParameterTypes());
|
||||
}
|
||||
|
||||
|
||||
private boolean isOverridenWithoutAnnotation(Method[] methods,
|
||||
Method superclazzMethod, Class<? extends Annotation> annotation) {
|
||||
for (Method method : methods) {
|
||||
if (isMethodOverride(method, superclazzMethod)
|
||||
&& (method.getAnnotation(annotation) == null)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public String getWsPath() {
|
||||
return wsPath;
|
||||
}
|
||||
|
||||
|
||||
public Method getOnOpen() {
|
||||
return onOpen;
|
||||
}
|
||||
|
||||
|
||||
public Object[] getOnOpenArgs(Map<String,String> pathParameters,
|
||||
Session session, EndpointConfig config) throws DecodeException {
|
||||
return buildArgs(onOpenParams, pathParameters, session, config, null,
|
||||
null);
|
||||
}
|
||||
|
||||
|
||||
public Method getOnClose() {
|
||||
return onClose;
|
||||
}
|
||||
|
||||
|
||||
public Object[] getOnCloseArgs(Map<String,String> pathParameters,
|
||||
Session session, CloseReason closeReason) throws DecodeException {
|
||||
return buildArgs(onCloseParams, pathParameters, session, null, null,
|
||||
closeReason);
|
||||
}
|
||||
|
||||
|
||||
public Method getOnError() {
|
||||
return onError;
|
||||
}
|
||||
|
||||
|
||||
public Object[] getOnErrorArgs(Map<String,String> pathParameters,
|
||||
Session session, Throwable throwable) throws DecodeException {
|
||||
return buildArgs(onErrorParams, pathParameters, session, null,
|
||||
throwable, null);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasMessageHandlers() {
|
||||
return !onMessage.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
public Set<MessageHandler> getMessageHandlers(Object pojo,
|
||||
Map<String,String> pathParameters, Session session,
|
||||
EndpointConfig config) {
|
||||
Set<MessageHandler> result = new HashSet<>();
|
||||
for (MessageHandlerInfo messageMethod : onMessage) {
|
||||
result.addAll(messageMethod.getMessageHandlers(pojo, pathParameters,
|
||||
session, config));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static PojoPathParam[] getPathParams(Method m,
|
||||
MethodType methodType) throws DeploymentException {
|
||||
if (m == null) {
|
||||
return new PojoPathParam[0];
|
||||
}
|
||||
boolean foundThrowable = false;
|
||||
Class<?>[] types = m.getParameterTypes();
|
||||
Annotation[][] paramsAnnotations = m.getParameterAnnotations();
|
||||
PojoPathParam[] result = new PojoPathParam[types.length];
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
Class<?> type = types[i];
|
||||
if (type.equals(Session.class)) {
|
||||
result[i] = new PojoPathParam(type, null);
|
||||
} else if (methodType == MethodType.ON_OPEN &&
|
||||
type.equals(EndpointConfig.class)) {
|
||||
result[i] = new PojoPathParam(type, null);
|
||||
} else if (methodType == MethodType.ON_ERROR
|
||||
&& type.equals(Throwable.class)) {
|
||||
foundThrowable = true;
|
||||
result[i] = new PojoPathParam(type, null);
|
||||
} else if (methodType == MethodType.ON_CLOSE &&
|
||||
type.equals(CloseReason.class)) {
|
||||
result[i] = new PojoPathParam(type, null);
|
||||
} else {
|
||||
Annotation[] paramAnnotations = paramsAnnotations[i];
|
||||
for (Annotation paramAnnotation : paramAnnotations) {
|
||||
if (paramAnnotation.annotationType().equals(
|
||||
PathParam.class)) {
|
||||
result[i] = new PojoPathParam(type,
|
||||
((PathParam) paramAnnotation).value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Parameters without annotations are not permitted
|
||||
if (result[i] == null) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.paramWithoutAnnotation",
|
||||
type, m.getName(), m.getClass().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (methodType == MethodType.ON_ERROR && !foundThrowable) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.onErrorNoThrowable",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static Object[] buildArgs(PojoPathParam[] pathParams,
|
||||
Map<String,String> pathParameters, Session session,
|
||||
EndpointConfig config, Throwable throwable, CloseReason closeReason)
|
||||
throws DecodeException {
|
||||
Object[] result = new Object[pathParams.length];
|
||||
for (int i = 0; i < pathParams.length; i++) {
|
||||
Class<?> type = pathParams[i].getType();
|
||||
if (type.equals(Session.class)) {
|
||||
result[i] = session;
|
||||
} else if (type.equals(EndpointConfig.class)) {
|
||||
result[i] = config;
|
||||
} else if (type.equals(Throwable.class)) {
|
||||
result[i] = throwable;
|
||||
} else if (type.equals(CloseReason.class)) {
|
||||
result[i] = closeReason;
|
||||
} else {
|
||||
String name = pathParams[i].getName();
|
||||
String value = pathParameters.get(name);
|
||||
try {
|
||||
result[i] = Util.coerceToType(type, value);
|
||||
} catch (Exception e) {
|
||||
throw new DecodeException(value, sm.getString(
|
||||
"pojoMethodMapping.decodePathParamFail",
|
||||
value, type), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static class MessageHandlerInfo {
|
||||
|
||||
private final Method m;
|
||||
private int indexString = -1;
|
||||
private int indexByteArray = -1;
|
||||
private int indexByteBuffer = -1;
|
||||
private int indexPong = -1;
|
||||
private int indexBoolean = -1;
|
||||
private int indexSession = -1;
|
||||
private int indexInputStream = -1;
|
||||
private int indexReader = -1;
|
||||
private int indexPrimitive = -1;
|
||||
private Map<Integer,PojoPathParam> indexPathParams = new HashMap<>();
|
||||
private int indexPayload = -1;
|
||||
private DecoderMatch decoderMatch = null;
|
||||
private long maxMessageSize = -1;
|
||||
|
||||
public MessageHandlerInfo(Method m, List<DecoderEntry> decoderEntries)
|
||||
throws DeploymentException {
|
||||
|
||||
this.m = m;
|
||||
|
||||
Class<?>[] types = m.getParameterTypes();
|
||||
Annotation[][] paramsAnnotations = m.getParameterAnnotations();
|
||||
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
boolean paramFound = false;
|
||||
Annotation[] paramAnnotations = paramsAnnotations[i];
|
||||
for (Annotation paramAnnotation : paramAnnotations) {
|
||||
if (paramAnnotation.annotationType().equals(
|
||||
PathParam.class)) {
|
||||
indexPathParams.put(
|
||||
Integer.valueOf(i), new PojoPathParam(types[i],
|
||||
((PathParam) paramAnnotation).value()));
|
||||
paramFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (paramFound) {
|
||||
continue;
|
||||
}
|
||||
if (String.class.isAssignableFrom(types[i])) {
|
||||
if (indexString == -1) {
|
||||
indexString = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else if (Reader.class.isAssignableFrom(types[i])) {
|
||||
if (indexReader == -1) {
|
||||
indexReader = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else if (boolean.class == types[i]) {
|
||||
if (indexBoolean == -1) {
|
||||
indexBoolean = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateLastParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else if (ByteBuffer.class.isAssignableFrom(types[i])) {
|
||||
if (indexByteBuffer == -1) {
|
||||
indexByteBuffer = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else if (byte[].class == types[i]) {
|
||||
if (indexByteArray == -1) {
|
||||
indexByteArray = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else if (InputStream.class.isAssignableFrom(types[i])) {
|
||||
if (indexInputStream == -1) {
|
||||
indexInputStream = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else if (Util.isPrimitive(types[i])) {
|
||||
if (indexPrimitive == -1) {
|
||||
indexPrimitive = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else if (Session.class.isAssignableFrom(types[i])) {
|
||||
if (indexSession == -1) {
|
||||
indexSession = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateSessionParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else if (PongMessage.class.isAssignableFrom(types[i])) {
|
||||
if (indexPong == -1) {
|
||||
indexPong = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicatePongMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
} else {
|
||||
if (decoderMatch != null && decoderMatch.hasMatches()) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
decoderMatch = new DecoderMatch(types[i], decoderEntries);
|
||||
|
||||
if (decoderMatch.hasMatches()) {
|
||||
indexPayload = i;
|
||||
} else {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.noDecoder",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Additional checks required
|
||||
if (indexString != -1) {
|
||||
if (indexPayload != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
} else {
|
||||
indexPayload = indexString;
|
||||
}
|
||||
}
|
||||
if (indexReader != -1) {
|
||||
if (indexPayload != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
} else {
|
||||
indexPayload = indexReader;
|
||||
}
|
||||
}
|
||||
if (indexByteArray != -1) {
|
||||
if (indexPayload != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
} else {
|
||||
indexPayload = indexByteArray;
|
||||
}
|
||||
}
|
||||
if (indexByteBuffer != -1) {
|
||||
if (indexPayload != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
} else {
|
||||
indexPayload = indexByteBuffer;
|
||||
}
|
||||
}
|
||||
if (indexInputStream != -1) {
|
||||
if (indexPayload != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
} else {
|
||||
indexPayload = indexInputStream;
|
||||
}
|
||||
}
|
||||
if (indexPrimitive != -1) {
|
||||
if (indexPayload != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.duplicateMessageParam",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
} else {
|
||||
indexPayload = indexPrimitive;
|
||||
}
|
||||
}
|
||||
if (indexPong != -1) {
|
||||
if (indexPayload != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.pongWithPayload",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
} else {
|
||||
indexPayload = indexPong;
|
||||
}
|
||||
}
|
||||
if (indexPayload == -1 && indexPrimitive == -1 &&
|
||||
indexBoolean != -1) {
|
||||
// The boolean we found is a payload, not a last flag
|
||||
indexPayload = indexBoolean;
|
||||
indexPrimitive = indexBoolean;
|
||||
indexBoolean = -1;
|
||||
}
|
||||
if (indexPayload == -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.noPayload",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
if (indexPong != -1 && indexBoolean != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.partialPong",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
if(indexReader != -1 && indexBoolean != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.partialReader",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
if(indexInputStream != -1 && indexBoolean != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.partialInputStream",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
if (decoderMatch != null && decoderMatch.hasMatches() &&
|
||||
indexBoolean != -1) {
|
||||
throw new DeploymentException(sm.getString(
|
||||
"pojoMethodMapping.partialObject",
|
||||
m.getName(), m.getDeclaringClass().getName()));
|
||||
}
|
||||
|
||||
maxMessageSize = m.getAnnotation(OnMessage.class).maxMessageSize();
|
||||
}
|
||||
|
||||
|
||||
public boolean targetsSameWebSocketMessageType(MessageHandlerInfo otherHandler) {
|
||||
if (otherHandler == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isPong() && otherHandler.isPong() || isBinary() && otherHandler.isBinary() ||
|
||||
isText() && otherHandler.isText();
|
||||
}
|
||||
|
||||
|
||||
private boolean isPong() {
|
||||
return indexPong >= 0;
|
||||
}
|
||||
|
||||
|
||||
private boolean isText() {
|
||||
return indexString >= 0 || indexPrimitive >= 0 || indexReader >= 0 ||
|
||||
(decoderMatch != null && decoderMatch.getTextDecoders().size() > 0);
|
||||
}
|
||||
|
||||
|
||||
private boolean isBinary() {
|
||||
return indexByteArray >= 0 || indexByteBuffer >= 0 || indexInputStream >= 0 ||
|
||||
(decoderMatch != null && decoderMatch.getBinaryDecoders().size() > 0);
|
||||
}
|
||||
|
||||
|
||||
public Set<MessageHandler> getMessageHandlers(Object pojo,
|
||||
Map<String,String> pathParameters, Session session,
|
||||
EndpointConfig config) {
|
||||
Object[] params = new Object[m.getParameterTypes().length];
|
||||
|
||||
for (Map.Entry<Integer,PojoPathParam> entry :
|
||||
indexPathParams.entrySet()) {
|
||||
PojoPathParam pathParam = entry.getValue();
|
||||
String valueString = pathParameters.get(pathParam.getName());
|
||||
Object value = null;
|
||||
try {
|
||||
value = Util.coerceToType(pathParam.getType(), valueString);
|
||||
} catch (Exception e) {
|
||||
DecodeException de = new DecodeException(valueString,
|
||||
sm.getString(
|
||||
"pojoMethodMapping.decodePathParamFail",
|
||||
valueString, pathParam.getType()), e);
|
||||
params = new Object[] { de };
|
||||
break;
|
||||
}
|
||||
params[entry.getKey().intValue()] = value;
|
||||
}
|
||||
|
||||
Set<MessageHandler> results = new HashSet<>(2);
|
||||
if (indexBoolean == -1) {
|
||||
// Basic
|
||||
if (indexString != -1 || indexPrimitive != -1) {
|
||||
MessageHandler mh = new PojoMessageHandlerWholeText(pojo, m,
|
||||
session, config, null, params, indexPayload, false,
|
||||
indexSession, maxMessageSize);
|
||||
results.add(mh);
|
||||
} else if (indexReader != -1) {
|
||||
MessageHandler mh = new PojoMessageHandlerWholeText(pojo, m,
|
||||
session, config, null, params, indexReader, true,
|
||||
indexSession, maxMessageSize);
|
||||
results.add(mh);
|
||||
} else if (indexByteArray != -1) {
|
||||
MessageHandler mh = new PojoMessageHandlerWholeBinary(pojo,
|
||||
m, session, config, null, params, indexByteArray,
|
||||
true, indexSession, false, maxMessageSize);
|
||||
results.add(mh);
|
||||
} else if (indexByteBuffer != -1) {
|
||||
MessageHandler mh = new PojoMessageHandlerWholeBinary(pojo,
|
||||
m, session, config, null, params, indexByteBuffer,
|
||||
false, indexSession, false, maxMessageSize);
|
||||
results.add(mh);
|
||||
} else if (indexInputStream != -1) {
|
||||
MessageHandler mh = new PojoMessageHandlerWholeBinary(pojo,
|
||||
m, session, config, null, params, indexInputStream,
|
||||
true, indexSession, true, maxMessageSize);
|
||||
results.add(mh);
|
||||
} else if (decoderMatch != null && decoderMatch.hasMatches()) {
|
||||
if (decoderMatch.getBinaryDecoders().size() > 0) {
|
||||
MessageHandler mh = new PojoMessageHandlerWholeBinary(
|
||||
pojo, m, session, config,
|
||||
decoderMatch.getBinaryDecoders(), params,
|
||||
indexPayload, true, indexSession, true,
|
||||
maxMessageSize);
|
||||
results.add(mh);
|
||||
}
|
||||
if (decoderMatch.getTextDecoders().size() > 0) {
|
||||
MessageHandler mh = new PojoMessageHandlerWholeText(
|
||||
pojo, m, session, config,
|
||||
decoderMatch.getTextDecoders(), params,
|
||||
indexPayload, true, indexSession, maxMessageSize);
|
||||
results.add(mh);
|
||||
}
|
||||
} else {
|
||||
MessageHandler mh = new PojoMessageHandlerWholePong(pojo, m,
|
||||
session, params, indexPong, false, indexSession);
|
||||
results.add(mh);
|
||||
}
|
||||
} else {
|
||||
// ASync
|
||||
if (indexString != -1) {
|
||||
MessageHandler mh = new PojoMessageHandlerPartialText(pojo,
|
||||
m, session, params, indexString, false,
|
||||
indexBoolean, indexSession, maxMessageSize);
|
||||
results.add(mh);
|
||||
} else if (indexByteArray != -1) {
|
||||
MessageHandler mh = new PojoMessageHandlerPartialBinary(
|
||||
pojo, m, session, params, indexByteArray, true,
|
||||
indexBoolean, indexSession, maxMessageSize);
|
||||
results.add(mh);
|
||||
} else {
|
||||
MessageHandler mh = new PojoMessageHandlerPartialBinary(
|
||||
pojo, m, session, params, indexByteBuffer, false,
|
||||
indexBoolean, indexSession, maxMessageSize);
|
||||
results.add(mh);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private enum MethodType {
|
||||
ON_OPEN,
|
||||
ON_CLOSE,
|
||||
ON_ERROR
|
||||
}
|
||||
}
|
||||
69
java/org/apache/tomcat/websocket/pojo/PojoPathParam.java
Normal file
69
java/org/apache/tomcat/websocket/pojo/PojoPathParam.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.tomcat.websocket.pojo;
|
||||
|
||||
import javax.websocket.DeploymentException;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
import org.apache.tomcat.websocket.Util;
|
||||
|
||||
/**
|
||||
* Stores the parameter type and name for a parameter that needs to be passed to
|
||||
* an onXxx method of {@link javax.websocket.Endpoint}. The name is only present
|
||||
* for parameters annotated with
|
||||
* {@link javax.websocket.server.PathParam}. For the
|
||||
* {@link javax.websocket.Session} and {@link java.lang.Throwable} parameters,
|
||||
* {@link #getName()} will always return <code>null</code>.
|
||||
*/
|
||||
public class PojoPathParam {
|
||||
|
||||
private static final StringManager sm = StringManager.getManager(PojoPathParam.class);
|
||||
|
||||
private final Class<?> type;
|
||||
private final String name;
|
||||
|
||||
|
||||
public PojoPathParam(Class<?> type, String name) throws DeploymentException {
|
||||
if (name != null) {
|
||||
// Annotated as @PathParam so validate type
|
||||
validateType(type);
|
||||
}
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
private static void validateType(Class<?> type) throws DeploymentException {
|
||||
if (String.class == type) {
|
||||
return;
|
||||
}
|
||||
if (Util.isPrimitive(type)) {
|
||||
return;
|
||||
}
|
||||
throw new DeploymentException(sm.getString("pojoPathParam.wrongType", type.getName()));
|
||||
}
|
||||
}
|
||||
21
java/org/apache/tomcat/websocket/pojo/package-info.java
Normal file
21
java/org/apache/tomcat/websocket/pojo/package-info.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* This package provides the necessary plumbing to convert an annotated POJO
|
||||
* into a WebSocket {@link javax.websocket.Endpoint}.
|
||||
*/
|
||||
package org.apache.tomcat.websocket.pojo;
|
||||
Reference in New Issue
Block a user