All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.bristleback.server.bristle.BristlebackServerPlugin Maven / Gradle / Ivy

// Bristleback plugin - Copyright (c) 2010 bristleback.googlecode.com
// ---------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
// This library is distributed in the hope that it will be useful,
// but without any warranty; without even the implied warranty of merchantability
// or fitness for a particular purpose.
// You should have received a copy of the GNU Lesser General Public License along
// with this program; if not, see .
// ---------------------------------------------------------------------------
package pl.bristleback.server.bristle;

import org.apache.log4j.Logger;
import org.jwebsocket.api.PluginConfiguration;
import org.jwebsocket.api.WebSocketConnector;
import org.jwebsocket.api.WebSocketEngine;
import org.jwebsocket.api.WebSocketServer;
import org.jwebsocket.kit.CloseReason;
import org.jwebsocket.kit.PlugInResponse;
import org.jwebsocket.plugins.TokenPlugIn;
import org.jwebsocket.token.Token;
import org.jwebsocket.token.TokenFactory;
import pl.bristleback.server.bristle.actions.ActionsDispatcher;
import pl.bristleback.server.bristle.actions.ActionsInitializer;
import pl.bristleback.server.bristle.actions.ReservedActionName;
import pl.bristleback.server.bristle.config.BristleConstants;
import pl.bristleback.server.bristle.config.ExceptionHandlersInitializer;
import pl.bristleback.server.bristle.messages.MessageController;
import pl.bristleback.server.bristle.rights.ConnectorRightsUtil;
import pl.bristleback.server.bristle.states.ServerStateInspector;

/**
 * Bristleback Server plugin (also called Bristle plugin) is a helpful framework overlay,
 * which simplifies process of creating applications using jWebsocket library.
 * Bristleback plugin consists of five main elements:
 * 
    *
  • * Remote actions.
    * Remote actions are used to declare response for user actions. They consists of name, required user rights and action response. * Adding new action is very easy because of annotation usage. * Actions are closely integrated with connector rights, which are described below. * In addition, any exceptions while dispatching actions can be caught by implementing * {@link pl.bristleback.server.bristle.exceptions.handlers.ExceptionHandler} interface. *
  • *
  • * Message senders and message dispatcher
    * Senders and dispatchers provide way for sending messages to client in easy and thread safe way. * Senders allow avoiding low level mechanisms of jwebsocket. *
  • *
  • * Connector rights
    * After connector is connected, plugin creates empty rights set desired for that connector. * Connector rights are used to determine whether connector can execute action. * Rights using can be extended, eg. in sending messages. *
  • *
  • * Client side of Bristleback plugin
    * Client side plugin provides the same action dispatching mechanism as on server side. *
  • *
  • * Spring Framework integration
    * Spring Framework is used in thousands of projects. Bristle plugin provides a simple annotation, * which can be used in action classes to inject dependencies. Furthermore, * most classes loaded via configuration file, like message senders or server state listeners, may be Spring beans. * Still, the target is to make available for every element to be a Spring bean. * Check the documentation of Bristleback Plugin elements to see how can you make use of Spring beans. *
  • *
*

* If you need to perform some operations before server is up or after server is down, * you might be interested in using server state listeners chain. The only thing to do is to add your own * {@link pl.bristleback.server.bristle.states.ServerStateListener} implementation. * You can add as many {@link pl.bristleback.server.bristle.states.ServerStateListener} as you want. *

* Almost every element of plugin is configurable, user can specify how actions or message will be looked. * Yet, default implementation of those elements allow user to create "Hello world" application in just five minutes. * Plugin settings in jwebsocket.xml file are used to configure Bristle plugin. * Please note that this is early version of plugin, so nothing is tested as good as we would like it to be. *

* {@link pl.bristleback.server.bristle.config.BristleConstants} class * has fields which can be helpful in creating your first application. *

* Current version of Bristle plugin contains two default message senders and one message dispatcher. * To make use of message senders, users must add them into their jwebsocket configuration file. * Example configuration is shown in this project, in "xml/jwebsocket.xml" file. * Additional "How to make your first jWebsocket application with Bristleback plugin" web page can be found HERE. * Created on: 2010-09-03 16:01:30
* * @author Wojciech Niemiec * @version 0.0.1 */ public class BristlebackServerPlugin extends TokenPlugIn { private static Logger log = Logger.getLogger(BristlebackServerPlugin.class.getName()); private ActionsDispatcher actionsDispatcher; private MessageController messageController; private ServerStateInspector serverStateInspector; /** * Creates a new Bristleback plugin instance and instantiating core elements of plugin. */ public BristlebackServerPlugin() { setCoreElements(); } /** * Constructor required by TokenPlugIn class. * * @param configuration plugin configuration. */ public BristlebackServerPlugin(PluginConfiguration configuration) { super(configuration); setCoreElements(); } private void setCoreElements() { actionsDispatcher = new ActionsDispatcher(); messageController = new MessageController(); serverStateInspector = new ServerStateInspector(); } /** * Loading of all core elements from configuration and annotations. * Firstly, plugin loads actions and exception handlers. * Next step is to load message controller (dispatcher and senders) and to export senders. * After that, server state inspector is loaded and invokes server state listeners chain. * As soon as every element is ready, message controller starts dispatching messages to connectors. * * @param engine websocket engine. */ public void engineStarted(WebSocketEngine engine) { WebSocketServer server = getServer(); loadActions(); loadExceptionsHandlers(); loadMessageHandler(server); notifyServerStateInspector(); messageController.startDispatcher(); } private void loadActions() { ActionsInitializer actionsInitializer = new ActionsInitializer(); actionsInitializer.loadActionsContainer(getSettings()); actionsInitializer.injectActionsDependencies(); actionsDispatcher.setContainer(actionsInitializer.getContainer()); } private void loadExceptionsHandlers() { ExceptionHandlersInitializer exceptionHandlersInitializer = new ExceptionHandlersInitializer(); exceptionHandlersInitializer.loadExceptionsHandlers(getSettings()); actionsDispatcher.setExceptionHandlersContainer(exceptionHandlersInitializer.getExceptionHandlersContainer()); } private void loadMessageHandler(WebSocketServer server) { messageController.loadMessageContainer(getSettings()); messageController.assignServer(server); messageController.exportSenders(); } private void notifyServerStateInspector() { serverStateInspector.loadServerStateListeners(getSettings()); serverStateInspector.serverStart(); } /** * In this method closing operations are performed. Dispatcher is stopped, * server state inspector is notified about server shutdown. * * @param engine websocket engine. */ public void engineStopped(WebSocketEngine engine) { messageController.stopDispatcher(); serverStateInspector.serverShutdown(); //todo-wojtek - free resources [unbind actions, message senders, etc] } /** * When connector is started, new empty rights set is created and assigned to that connector. * Moreover, it's possible to have a special action class with reserved name * {@link pl.bristleback.server.bristle.actions.ReservedActionName#CONNECTION_STARTED_ACTION_NAME}. * * @param connector websocket connector. */ public void connectorStarted(WebSocketConnector connector) { ConnectorRightsUtil.createRightsSetForConnector(connector); Token token = TokenFactory.createToken(); actionsDispatcher.performReservedAction(connector, ReservedActionName.CONNECTION_STARTED_ACTION_NAME, token); } /** * Additional operations performed when connector is stopped. * It's possible to have a special action class with reserved name * {@link pl.bristleback.server.bristle.actions.ReservedActionName#CONNECTION_STOPPED_ACTION_NAME}. * Reason of closed connection is given in variable named {@code closeReason}. * * @param connector websocket connector. * @param closeReason connection close reason. */ public void connectorStopped(WebSocketConnector connector, CloseReason closeReason) { Token token = TokenFactory.createToken(); token.setString("closeReason", closeReason.toString()); actionsDispatcher.performReservedAction(connector, ReservedActionName.CONNECTION_STOPPED_ACTION_NAME, token); } /** * Process token sent by user. If token namespace is equals to * {@link pl.bristleback.server.bristle.config.BristleConstants#BRISTLE_PLUGIN_NAMESPACE}, then plugin chain is aborted * and dedicated dispatcher performs action. This is one of the core elements in Bristle plugin. * More about dispatching actions can be found in {@link pl.bristleback.server.bristle.actions.ActionsDispatcher} documentation. * * @param response wrapper object containing information about plugin chain state. * @param connector websocket connector. * @param token content of the message. */ public void processToken(PlugInResponse response, WebSocketConnector connector, Token token) { String namespace = token.getNS(); if (BristleConstants.BRISTLE_PLUGIN_NAMESPACE.equals(namespace)) { response.abortChain(); performAction(connector, token); } } private void performAction(WebSocketConnector connector, Token token) { actionsDispatcher.performAction(connector, token); } /** * Gets action dispatcher with actions and handlers inside. * * @return actions dispatcher. */ public ActionsDispatcher getActionsDispatcher() { return actionsDispatcher; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy