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

org.butor.json.service.DefaultServiceManager Maven / Gradle / Ivy

Go to download

This module enables fast and easy creation of sync., async., req./resp., req./resp. stream HTTP/json services.

There is a newer version: 1.0.29
Show newest version
/*******************************************************************************
 * Copyright 2013 butor.com
 * 
 * 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.butor.json.service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.butor.json.CommonRequestArgs;
import org.butor.json.JsonHelper;
import org.butor.json.JsonServiceRequest;
import org.butor.utils.ApplicationException;
import org.butor.utils.CommonMessageID;
import org.butor.utils.Message;
import org.butor.utils.Message.MessageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.google.common.base.Preconditions;

public class DefaultServiceManager implements ServiceManager,InitializingBean,BeanFactoryAware {
	protected Logger _logger = LoggerFactory.getLogger(getClass());
	private JsonHelper _jsh = new JsonHelper();
	
	private PlatformTransactionManager transactionManager;
	private BeanFactory beanFactory;
	
	
	private ConcurrentMap _cmps = 
			new ConcurrentHashMap();

	private List _components;

	@Override
	public void registerServices(List components_) {
		for (ServiceComponent ser : components_)
			registerService(ser);
	}

	@Override
	public void registerService(ServiceComponent serviceCmp_) {
		String ns = serviceCmp_.getNamespace();
		if (_cmps.containsKey(ns)) {
			_logger.error(String.format("Namespace %s has been used by component %s", 
					ns, _cmps.get(ns).toString()));
			return;
		}
		_cmps.put(ns, serviceCmp_);
	}

	@Override
	public void unregisterService(ServiceComponent cmp_) {
		_cmps.remove(cmp_.getNamespace());
	}

	@Override
	public boolean isBinary(JsonServiceRequest req) {
		final ServiceComponent cmp = _cmps.get(req.getNamespace());
		if (cmp == null) {
			String msg = String.format("No service component found with ns=%s", req.getNamespace());
			_logger.info(msg);
			return false;
		}
		return cmp.isBinary();
	}
	@Override
	public void invoke(final Context ctx_) {
		JsonServiceRequest req = (JsonServiceRequest)ctx_.getRequest();
		final String namespace = req.getNamespace();
		final ServiceComponent cmp = _cmps.get(namespace);
		if (cmp == null) {
			String msg = String.format("No service component found with ns=%s", namespace);
			_logger.info(msg);
			return;
		}


		List params = _jsh.deserialize(req.getServiceArgsJson(), List.class);
		int nbArgs = params.size() +1; // +1 for context arg

		final String serviceName = req.getService();
		final Method serviceMethod = cmp.getService(serviceName, nbArgs);

		if (serviceMethod == null) {
			String msg = String.format("No service=%s found with ns=%s", 
					serviceName, namespace);
			_logger.info(msg);
			ctx_.getResponseHandler().addMessage(new Message(0, MessageType.ERROR, msg));
			return;
		}

		try {
			final CommonRequestArgs cr = new CommonRequestArgs();
			cr.setLang(req.getLang());
			cr.setReqId(req.getReqId());
			cr.setSessionId(req.getSessionId());
			cr.setUserId(req.getUserId());
			Context ctx = new Context() {
				@Override
				public ResponseHandler getResponseHandler() {
					return ctx_.getResponseHandler();
				}
				@Override
				public CommonRequestArgs getRequest() {
					return cr;
				}
			};
			
			Class[] pts = serviceMethod.getParameterTypes();
			final Object[] serviceParameters = new Object[pts.length];
			serviceParameters[0] = ctx;
			for (int ii=1; ii getComponents() {
		return _components;
	}

	public void setComponents(List components_) {
		_components = components_;
		registerServices(components_);
	}


	@Override
	public void afterPropertiesSet() throws Exception {
		try {
			transactionManager = beanFactory.getBean(PlatformTransactionManager.class);
		} catch (NoSuchBeanDefinitionException e) {
			_logger.warn("No (or more than one) TransactionManager defined in your Spring context. Will not set transaction manager.",e);
		}
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
		
	}

}