de.itsvs.cwtrpc.controller.PreparedRemoteServiceConfigBuilder.java Source code

Java tutorial

Introduction

Here is the source code for de.itsvs.cwtrpc.controller.PreparedRemoteServiceConfigBuilder.java

Source

/*
 *  Copyright 2011 IT Services VS GmbH
 *
 *  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 de.itsvs.cwtrpc.controller;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

import de.itsvs.cwtrpc.controller.token.RpcTokenValidator;
import de.itsvs.cwtrpc.core.CwtRpcException;

/**
 * @author Volker Schmidt
 * @since 0.9
 */
public class PreparedRemoteServiceConfigBuilder implements BeanFactoryAware {
    private final Log log = LogFactory.getLog(PreparedRemoteServiceConfigBuilder.class);

    private BeanFactory beanFactory;

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }

    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public Map<String, PreparedRemoteServiceConfig> build(RemoteServiceControllerConfig config)
            throws CwtRpcException {
        if (getBeanFactory() == null) {
            throw new IllegalStateException("Bean factory must be specified");
        }

        return createRemoteServiceConfigsByUri(config, config.getServiceModuleConfigs());
    }

    protected Map<String, PreparedRemoteServiceConfig> createRemoteServiceConfigsByUri(
            BaseServiceConfig baseServiceConfig, Collection<RemoteServiceModuleConfig> moduleConfigs)
            throws CwtRpcException {
        final Map<String, PreparedRemoteServiceConfig> serviceConfigsByUri;

        serviceConfigsByUri = new HashMap<String, PreparedRemoteServiceConfig>();
        for (RemoteServiceModuleConfig moduleConfig : moduleConfigs) {
            merge(serviceConfigsByUri,
                    createRemoteServiceConfigsByUri(baseServiceConfig.createMergedBaseServiceConfig(moduleConfig),
                            moduleConfig, moduleConfig.getServiceGroupConfig()));
        }

        return serviceConfigsByUri;
    }

    protected Map<String, PreparedRemoteServiceConfig> createRemoteServiceConfigsByUri(
            BaseServiceConfig baseServiceConfig, RemoteServiceModuleConfig moduleConfig,
            RemoteServiceGroupConfig groupConfig) throws CwtRpcException {
        final BaseServiceConfig groupBaseServiceConfig;
        final Map<String, PreparedRemoteServiceConfig> serviceConfigsByUri;

        groupBaseServiceConfig = baseServiceConfig.createMergedBaseServiceConfig(groupConfig);
        serviceConfigsByUri = new HashMap<String, PreparedRemoteServiceConfig>();
        if (groupConfig.getServiceConfigs() != null) {
            for (RemoteServiceConfig serviceConfig : groupConfig.getServiceConfigs()) {
                merge(serviceConfigsByUri,
                        createRemoteServiceConfigsByUri(groupBaseServiceConfig, moduleConfig, serviceConfig));
            }
        }
        if (groupConfig.getChildGroupConfigs() != null) {
            for (RemoteServiceGroupConfig childGroupConfig : groupConfig.getChildGroupConfigs()) {
                merge(serviceConfigsByUri,
                        createRemoteServiceConfigsByUri(groupBaseServiceConfig, moduleConfig, childGroupConfig));
            }
        }

        return serviceConfigsByUri;
    }

    protected Map<String, PreparedRemoteServiceConfig> createRemoteServiceConfigsByUri(
            BaseServiceConfig baseServiceConfig, RemoteServiceModuleConfig moduleConfig,
            RemoteServiceConfig serviceConfig) throws CwtRpcException {
        final Map<String, PreparedRemoteServiceConfig> serviceConfigsByUri;
        final BaseServiceConfig resultingBaseServiceConfig;
        final String serviceName;
        final PreparedRemoteServiceConfig preparedServiceConfig;
        final String uri;
        final RpcTokenValidator rpcTokenValidator;
        Class<?> serviceInterface;

        resultingBaseServiceConfig = baseServiceConfig.createMergedBaseServiceConfig(serviceConfig);

        serviceName = serviceConfig.getServiceName();
        if (!getBeanFactory().containsBean(serviceName)) {
            throw new CwtRpcException("Bean factory does not contain service with name '" + serviceName + "'");
        }

        serviceInterface = serviceConfig.getServiceInterface();
        if (serviceInterface == null) {
            serviceInterface = getRemoteServiceInterface(serviceName);
        }
        if (!getBeanFactory().isTypeMatch(serviceName, serviceInterface)) {
            throw new CwtRpcException("Service '" + serviceName + "' does not implement specified service "
                    + "interface " + serviceInterface.getName());
        }

        if (resultingBaseServiceConfig.getRpcTokenProtectionEnabled().booleanValue()) {
            rpcTokenValidator = getBeanFactory().getBean(resultingBaseServiceConfig.getRpcTokenValidatorName(),
                    RpcTokenValidator.class);
        } else {
            rpcTokenValidator = null;
        }

        uri = getRemoteServiceUri(moduleConfig.getName(), serviceConfig, serviceInterface);
        preparedServiceConfig = new PreparedRemoteServiceConfig(serviceName, serviceInterface,
                resultingBaseServiceConfig.getResponseCompressionEnabled().booleanValue(), rpcTokenValidator);

        if (log.isDebugEnabled()) {
            log.debug("Registering service " + preparedServiceConfig + " for URI '" + uri + "'");
        }
        serviceConfigsByUri = new HashMap<String, PreparedRemoteServiceConfig>(1);
        serviceConfigsByUri.put(uri, preparedServiceConfig);

        return serviceConfigsByUri;
    }

    protected Class<?> getRemoteServiceInterface(String serviceName) throws CwtRpcException {
        final Class<?> serviceClass;
        Class<?> foundInterface = null;

        serviceClass = getBeanFactory().getType(serviceName);
        for (Class<?> c : serviceClass.getInterfaces()) {
            if (RemoteService.class.isAssignableFrom(c)) {
                if (foundInterface != null) {
                    throw new CwtRpcException("Service class " + serviceClass.getName() + " of service '"
                            + serviceName + "' implements multiple " + "remote service interfaces (specify service "
                            + "interface explicitly)");
                }
                foundInterface = c;
            }
        }

        return foundInterface;
    }

    protected String getRemoteServiceUri(String moduleName, RemoteServiceConfig serviceConfig,
            Class<?> serviceInterface) throws CwtRpcException {
        final String relativePathValue;
        final StringBuilder uri;

        if (serviceConfig.getRelativePath() != null) {
            relativePathValue = serviceConfig.getRelativePath();
        } else {
            final RemoteServiceRelativePath relativePath;

            relativePath = serviceInterface.getAnnotation(RemoteServiceRelativePath.class);
            if (relativePath == null) {
                throw new CwtRpcException("Service interface " + serviceInterface.getName() + " does not specify "
                        + "the remote service relative path annotation. " + "Specify relative path explicitly!");
            }

            relativePathValue = relativePath.value();
            if (relativePathValue == null) {
                throw new CwtRpcException("Service interface " + serviceInterface.getName() + " must specify "
                        + "a valid remote service relative path");
            }
            if (relativePathValue.startsWith("/")) {
                throw new CwtRpcException("Service interface " + serviceInterface.getName() + " must not specify "
                        + "an absolute path as remote service relative path");
            }
        }

        uri = new StringBuilder();
        uri.append(moduleName);
        uri.append('/');
        uri.append(relativePathValue);

        return uri.toString();
    }

    protected void merge(Map<String, PreparedRemoteServiceConfig> destMap,
            Map<String, PreparedRemoteServiceConfig> srcMap) throws CwtRpcException {
        for (Map.Entry<String, PreparedRemoteServiceConfig> entry : srcMap.entrySet()) {
            PreparedRemoteServiceConfig duplicate;

            duplicate = destMap.put(entry.getKey(), entry.getValue());
            if (duplicate != null) {
                throw new CwtRpcException("Service '" + entry.getValue().getServiceName()
                        + "' is either include twice or uses same URI (" + entry.getKey() + ") as service '"
                        + duplicate.getServiceName() + "'");
            }
        }
    }
}