Package org.cruxframework.crux.core.server.dispatch

Source Code of org.cruxframework.crux.core.server.dispatch.RemoteServiceServlet

/*
* Copyright 2011 cruxframework.org.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.cruxframework.crux.core.server.dispatch;

import java.lang.reflect.Method;

import org.cruxframework.crux.core.i18n.LocaleResolver;
import org.cruxframework.crux.core.i18n.LocaleResolverInitializer;
import org.cruxframework.crux.core.server.dispatch.st.CruxSynchronizerTokenHandler;
import org.cruxframework.crux.core.server.dispatch.st.CruxSynchronizerTokenHandlerFactory;
import org.cruxframework.crux.core.server.dispatch.st.InvalidTokenException;
import org.cruxframework.crux.core.shared.rpc.st.UseSynchronizerToken;
import org.cruxframework.crux.core.utils.RegexpPatterns;

import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.google.gwt.user.server.rpc.RPCRequest;

/**
*
* @author Thiago Bustamante
*/
public class RemoteServiceServlet extends com.google.gwt.user.server.rpc.RemoteServiceServlet
{
  private static final long serialVersionUID = -5471459247489132091L;

  /**
   * @see com.google.gwt.user.server.rpc.RemoteServiceServlet#processCall(java.lang.String)
   */
  @Override
  public String processCall(String payload) throws SerializationException
  {
    boolean localeInitializedByServlet = false;
    try
    {
      localeInitializedByServlet = initUserLocaleResolver();
      Object service = getServiceForRequest(payload);
      RPCRequest rpcRequest = RPC.decodeRequest(payload, service.getClass(), this);
      onAfterRequestDeserialized(rpcRequest);

      //TODO: criar um ponto de injecao de comportamento aki.... para permitir que plugins sejam criados (ex: seguranca, logs, etc)
      CruxSynchronizerTokenHandler handler = CruxSynchronizerTokenHandlerFactory.getCruxSynchronizerTokenHandler(getThreadLocalRequest());

      boolean useToken = checkSynchonizerToken(rpcRequest, handler);
      try
      {
        return RPC.invokeAndEncodeResponse(service, rpcRequest.getMethod(),
            rpcRequest.getParameters(), rpcRequest.getSerializationPolicy());
      }
      finally
      {
        if (useToken)
        {
          String methodFullSignature = handler.getMethodDescription(rpcRequest.getMethod());
          handler.endMethod(methodFullSignature);
        }
      }
    }
    catch (IncompatibleRemoteServiceException ex)
    {
      log("An IncompatibleRemoteServiceException was thrown while processing this call.",ex);
      return RPC.encodeResponseForFailure(null, ex);
    }
    finally
    {
      if (localeInitializedByServlet)
      {
        clearUserLocaleResolver();
      }
    }
  }
 
  /**
   * @param rpcRequest
   * @param handler
   * @return
   * @throws IncompatibleRemoteServiceException
   */
  protected boolean checkSynchonizerToken(RPCRequest rpcRequest, CruxSynchronizerTokenHandler handler) throws IncompatibleRemoteServiceException
  {
    Method method = rpcRequest.getMethod();
    if (method.getAnnotation(UseSynchronizerToken.class) != null)
    {
      String methodFullSignature = handler.getMethodDescription(method);
      if (!handler.isMethodRunning(methodFullSignature))
      {
        try
        {
          handler.startMethod(methodFullSignature);
          return true;
        }
        catch (InvalidTokenException e)
        {
          throw new IncompatibleRemoteServiceException(e.getLocalizedMessage(), e);
        }
      }
      else
      {
        throw new IncompatibleRemoteServiceException("Invalid Synchronizer Token for method ["+methodFullSignature+"]. Possible CSRF attack.");
      }
    }
    return false;
  }
 
  /**
   *
   */
  protected boolean initUserLocaleResolver()
  {
    if (LocaleResolverInitializer.getLocaleResolver() == null)
    {
      LocaleResolverInitializer.createLocaleResolverThreadData();
      LocaleResolver resolver = LocaleResolverInitializer.getLocaleResolver();
      resolver.initializeUserLocale(getThreadLocalRequest());
      return true;
    }
    return false;
  }

  /**
   *
   */
  protected void clearUserLocaleResolver()
  {
    LocaleResolverInitializer.clearLocaleResolverThreadData();
  }

  /**
   * Return the service that will handle this request
   * @param encodedRequest
   * @return
   * @throws IncompatibleRemoteServiceException
   */
  protected Object getServiceForRequest(String encodedRequest) throws IncompatibleRemoteServiceException
  {
    try
    {
      if (!ServiceFactoryInitializer.isFactoryInitialized())
      {
        ServiceFactoryInitializer.initialize(getServletContext());
      }
     
      // We don't need to verify or parse the encodedRequest because it will be already done by
      // RPC.decodeRequest. So, just read the interface name directly
      String serviceIntfName = RegexpPatterns.REGEXP_PIPE.split(encodedRequest)[5];     
      Object service = ServiceFactoryInitializer.getServiceFactory().getService(serviceIntfName);
      if (service instanceof RequestAware)
      {
        ((RequestAware)service).setRequest(getThreadLocalRequest());
      }
      if (service instanceof ResponseAware)
      {
        ((ResponseAware)service).setResponse(getThreadLocalResponse());
      }
      if (service instanceof SessionAware)
      {
        ((SessionAware)service).setSession(getThreadLocalRequest().getSession());
      }
      return service;
    }
    catch (Throwable e)
    {
      throw new IncompatibleRemoteServiceException(e.getLocalizedMessage(), e);
    }
  }
}
TOP

Related Classes of org.cruxframework.crux.core.server.dispatch.RemoteServiceServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.