use of io.undertow.servlet.api.InstanceFactory in project undertow by undertow-io.
the class EncodingFactory method createFactory.
public static EncodingFactory createFactory(final ClassIntrospecter classIntrospecter, final List<Class<? extends Decoder>> decoders, final List<Class<? extends Encoder>> encoders) throws DeploymentException {
final Map<Class<?>, List<InstanceFactory<? extends Encoder>>> binaryEncoders = new HashMap<>();
final Map<Class<?>, List<InstanceFactory<? extends Decoder>>> binaryDecoders = new HashMap<>();
final Map<Class<?>, List<InstanceFactory<? extends Encoder>>> textEncoders = new HashMap<>();
final Map<Class<?>, List<InstanceFactory<? extends Decoder>>> textDecoders = new HashMap<>();
for (Class<? extends Decoder> decoder : decoders) {
if (Decoder.Binary.class.isAssignableFrom(decoder)) {
try {
Method method = decoder.getMethod("decode", ByteBuffer.class);
final Class<?> type = resolveReturnType(method, decoder);
List<InstanceFactory<? extends Decoder>> list = binaryDecoders.get(type);
if (list == null) {
binaryDecoders.put(type, list = new ArrayList<>());
}
list.add(classIntrospecter.createInstanceFactory(decoder));
} catch (NoSuchMethodException e) {
throw JsrWebSocketMessages.MESSAGES.couldNotDetermineTypeOfDecodeMethodForClass(decoder, e);
}
} else if (Decoder.BinaryStream.class.isAssignableFrom(decoder)) {
try {
Method method = decoder.getMethod("decode", InputStream.class);
final Class<?> type = resolveReturnType(method, decoder);
List<InstanceFactory<? extends Decoder>> list = binaryDecoders.get(type);
if (list == null) {
binaryDecoders.put(type, list = new ArrayList<>());
}
list.add(classIntrospecter.createInstanceFactory(decoder));
} catch (NoSuchMethodException e) {
throw JsrWebSocketMessages.MESSAGES.couldNotDetermineTypeOfDecodeMethodForClass(decoder, e);
}
} else if (Decoder.Text.class.isAssignableFrom(decoder)) {
try {
Method method = decoder.getMethod("decode", String.class);
final Class<?> type = resolveReturnType(method, decoder);
List<InstanceFactory<? extends Decoder>> list = textDecoders.get(type);
if (list == null) {
textDecoders.put(type, list = new ArrayList<>());
}
list.add(classIntrospecter.createInstanceFactory(decoder));
} catch (NoSuchMethodException e) {
throw JsrWebSocketMessages.MESSAGES.couldNotDetermineTypeOfDecodeMethodForClass(decoder, e);
}
} else if (Decoder.TextStream.class.isAssignableFrom(decoder)) {
try {
Method method = decoder.getMethod("decode", Reader.class);
final Class<?> type = resolveReturnType(method, decoder);
List<InstanceFactory<? extends Decoder>> list = textDecoders.get(type);
if (list == null) {
textDecoders.put(type, list = new ArrayList<>());
}
list.add(createInstanceFactory(classIntrospecter, decoder));
} catch (NoSuchMethodException e) {
throw JsrWebSocketMessages.MESSAGES.couldNotDetermineTypeOfDecodeMethodForClass(decoder, e);
}
} else {
throw JsrWebSocketMessages.MESSAGES.didNotImplementKnownDecoderSubclass(decoder);
}
}
for (Class<? extends Encoder> encoder : encoders) {
if (Encoder.Binary.class.isAssignableFrom(encoder)) {
final Class<?> type = findEncodeMethod(encoder, ByteBuffer.class);
List<InstanceFactory<? extends Encoder>> list = binaryEncoders.get(type);
if (list == null) {
binaryEncoders.put(type, list = new ArrayList<>());
}
list.add(createInstanceFactory(classIntrospecter, encoder));
} else if (Encoder.BinaryStream.class.isAssignableFrom(encoder)) {
final Class<?> type = findEncodeMethod(encoder, void.class, OutputStream.class);
List<InstanceFactory<? extends Encoder>> list = binaryEncoders.get(type);
if (list == null) {
binaryEncoders.put(type, list = new ArrayList<>());
}
list.add(createInstanceFactory(classIntrospecter, encoder));
} else if (Encoder.Text.class.isAssignableFrom(encoder)) {
final Class<?> type = findEncodeMethod(encoder, String.class);
List<InstanceFactory<? extends Encoder>> list = textEncoders.get(type);
if (list == null) {
textEncoders.put(type, list = new ArrayList<>());
}
list.add(createInstanceFactory(classIntrospecter, encoder));
} else if (Encoder.TextStream.class.isAssignableFrom(encoder)) {
final Class<?> type = findEncodeMethod(encoder, void.class, Writer.class);
List<InstanceFactory<? extends Encoder>> list = textEncoders.get(type);
if (list == null) {
textEncoders.put(type, list = new ArrayList<>());
}
list.add(createInstanceFactory(classIntrospecter, encoder));
}
}
return new EncodingFactory(binaryEncoders, binaryDecoders, textEncoders, textDecoders);
}
use of io.undertow.servlet.api.InstanceFactory in project undertow by undertow-io.
the class ServerWebSocketContainer method addEndpointInternal.
private synchronized void addEndpointInternal(final Class<?> endpoint, boolean requiresCreation) throws DeploymentException {
ServerEndpoint serverEndpoint = endpoint.getAnnotation(ServerEndpoint.class);
ClientEndpoint clientEndpoint = endpoint.getAnnotation(ClientEndpoint.class);
if (serverEndpoint != null) {
JsrWebSocketLogger.ROOT_LOGGER.addingAnnotatedServerEndpoint(endpoint, serverEndpoint.value());
final PathTemplate template = PathTemplate.create(serverEndpoint.value());
if (seenPaths.contains(template)) {
PathTemplate existing = null;
for (PathTemplate p : seenPaths) {
if (p.compareTo(template) == 0) {
existing = p;
break;
}
}
throw JsrWebSocketMessages.MESSAGES.multipleEndpointsWithOverlappingPaths(template, existing);
}
seenPaths.add(template);
Class<? extends ServerEndpointConfig.Configurator> configuratorClass = serverEndpoint.configurator();
EncodingFactory encodingFactory = EncodingFactory.createFactory(classIntrospecter, serverEndpoint.decoders(), serverEndpoint.encoders());
AnnotatedEndpointFactory annotatedEndpointFactory = AnnotatedEndpointFactory.create(endpoint, encodingFactory, template.getParameterNames());
InstanceFactory<?> instanceFactory = null;
try {
instanceFactory = classIntrospecter.createInstanceFactory(endpoint);
} catch (Exception e) {
//so it is possible that this is still valid if a custom configurator is in use
if (configuratorClass == ServerEndpointConfig.Configurator.class) {
throw JsrWebSocketMessages.MESSAGES.couldNotDeploy(e);
} else {
instanceFactory = new InstanceFactory<Object>() {
@Override
public InstanceHandle<Object> createInstance() throws InstantiationException {
throw JsrWebSocketMessages.MESSAGES.endpointDoesNotHaveAppropriateConstructor(endpoint);
}
};
}
}
ServerEndpointConfig.Configurator configurator;
if (configuratorClass != ServerEndpointConfig.Configurator.class) {
try {
configurator = classIntrospecter.createInstanceFactory(configuratorClass).createInstance().getInstance();
} catch (InstantiationException | NoSuchMethodException e) {
throw JsrWebSocketMessages.MESSAGES.couldNotDeploy(e);
}
} else {
configurator = DefaultContainerConfigurator.INSTANCE;
}
ServerEndpointConfig config = ServerEndpointConfig.Builder.create(endpoint, serverEndpoint.value()).decoders(Arrays.asList(serverEndpoint.decoders())).encoders(Arrays.asList(serverEndpoint.encoders())).subprotocols(Arrays.asList(serverEndpoint.subprotocols())).extensions(Collections.<Extension>emptyList()).configurator(configurator).build();
ConfiguredServerEndpoint confguredServerEndpoint = new ConfiguredServerEndpoint(config, instanceFactory, template, encodingFactory, annotatedEndpointFactory, installedExtensions);
configuredServerEndpoints.add(confguredServerEndpoint);
handleAddingFilterMapping();
} else if (clientEndpoint != null) {
JsrWebSocketLogger.ROOT_LOGGER.addingAnnotatedClientEndpoint(endpoint);
EncodingFactory encodingFactory = EncodingFactory.createFactory(classIntrospecter, clientEndpoint.decoders(), clientEndpoint.encoders());
InstanceFactory<?> instanceFactory;
try {
instanceFactory = classIntrospecter.createInstanceFactory(endpoint);
} catch (Exception e) {
try {
//this endpoint cannot be created by the container, the user will instantiate it
instanceFactory = new ConstructorInstanceFactory<>(endpoint.getConstructor());
} catch (NoSuchMethodException e1) {
if (requiresCreation) {
throw JsrWebSocketMessages.MESSAGES.couldNotDeploy(e);
} else {
instanceFactory = new InstanceFactory<Object>() {
@Override
public InstanceHandle<Object> createInstance() throws InstantiationException {
throw new InstantiationException();
}
};
}
}
}
AnnotatedEndpointFactory factory = AnnotatedEndpointFactory.create(endpoint, encodingFactory, Collections.<String>emptySet());
ClientEndpointConfig.Configurator configurator = null;
try {
configurator = classIntrospecter.createInstanceFactory(clientEndpoint.configurator()).createInstance().getInstance();
} catch (InstantiationException | NoSuchMethodException e) {
throw JsrWebSocketMessages.MESSAGES.couldNotDeploy(e);
}
ClientEndpointConfig config = ClientEndpointConfig.Builder.create().decoders(Arrays.asList(clientEndpoint.decoders())).encoders(Arrays.asList(clientEndpoint.encoders())).preferredSubprotocols(Arrays.asList(clientEndpoint.subprotocols())).configurator(configurator).build();
ConfiguredClientEndpoint configuredClientEndpoint = new ConfiguredClientEndpoint(config, factory, encodingFactory, instanceFactory);
clientEndpoints.put(endpoint, configuredClientEndpoint);
} else {
throw JsrWebSocketMessages.MESSAGES.classWasNotAnnotated(endpoint);
}
}
use of io.undertow.servlet.api.InstanceFactory in project undertow by undertow-io.
the class ServerWebSocketContainer method doUpgrade.
public void doUpgrade(HttpServletRequest request, HttpServletResponse response, final ServerEndpointConfig sec, Map<String, String> pathParams) throws ServletException, IOException {
ServerEndpointConfig.Configurator configurator = sec.getConfigurator();
try {
EncodingFactory encodingFactory = EncodingFactory.createFactory(classIntrospecter, sec.getDecoders(), sec.getEncoders());
PathTemplate pt = PathTemplate.create(sec.getPath());
InstanceFactory<?> instanceFactory = null;
try {
instanceFactory = classIntrospecter.createInstanceFactory(sec.getEndpointClass());
} catch (Exception e) {
//so it is possible that this is still valid if a custom configurator is in use
if (configurator == null || configurator.getClass() == ServerEndpointConfig.Configurator.class) {
throw JsrWebSocketMessages.MESSAGES.couldNotDeploy(e);
} else {
instanceFactory = new InstanceFactory<Object>() {
@Override
public InstanceHandle<Object> createInstance() throws InstantiationException {
throw JsrWebSocketMessages.MESSAGES.endpointDoesNotHaveAppropriateConstructor(sec.getEndpointClass());
}
};
}
}
if (configurator == null) {
configurator = DefaultContainerConfigurator.INSTANCE;
}
ServerEndpointConfig config = ServerEndpointConfig.Builder.create(sec.getEndpointClass(), sec.getPath()).decoders(sec.getDecoders()).encoders(sec.getEncoders()).subprotocols(sec.getSubprotocols()).extensions(sec.getExtensions()).configurator(configurator).build();
AnnotatedEndpointFactory annotatedEndpointFactory = null;
if (!Endpoint.class.isAssignableFrom(sec.getEndpointClass())) {
annotatedEndpointFactory = AnnotatedEndpointFactory.create(sec.getEndpointClass(), encodingFactory, pt.getParameterNames());
}
ConfiguredServerEndpoint confguredServerEndpoint;
if (annotatedEndpointFactory == null) {
confguredServerEndpoint = new ConfiguredServerEndpoint(config, instanceFactory, null, encodingFactory);
} else {
confguredServerEndpoint = new ConfiguredServerEndpoint(config, instanceFactory, null, encodingFactory, annotatedEndpointFactory, installedExtensions);
}
WebSocketHandshakeHolder hand;
WebSocketDeploymentInfo info = (WebSocketDeploymentInfo) request.getServletContext().getAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME);
if (info == null || info.getExtensions() == null) {
hand = ServerWebSocketContainer.handshakes(confguredServerEndpoint);
} else {
hand = ServerWebSocketContainer.handshakes(confguredServerEndpoint, info.getExtensions());
}
final ServletWebSocketHttpExchange facade = new ServletWebSocketHttpExchange(request, response, new HashSet<WebSocketChannel>());
Handshake handshaker = null;
for (Handshake method : hand.handshakes) {
if (method.matches(facade)) {
handshaker = method;
break;
}
}
if (handshaker != null) {
if (isClosed()) {
response.sendError(StatusCodes.SERVICE_UNAVAILABLE);
return;
}
facade.putAttachment(HandshakeUtil.PATH_PARAMS, pathParams);
final Handshake selected = handshaker;
facade.upgradeChannel(new HttpUpgradeListener() {
@Override
public void handleUpgrade(StreamConnection streamConnection, HttpServerExchange exchange) {
WebSocketChannel channel = selected.createChannel(facade, streamConnection, facade.getBufferPool());
new EndpointSessionHandler(ServerWebSocketContainer.this).onConnect(facade, channel);
}
});
handshaker.handshake(facade);
return;
}
} catch (Exception e) {
throw new ServletException(e);
}
}
Aggregations