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

ars.database.spring.DatabaseConfiguration Maven / Gradle / Ivy

package ars.database.spring;

import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.LinkedList;
import java.util.Collection;
import java.util.Collections;
import java.lang.reflect.Method;

import org.springframework.beans.BeansException;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.framework.Advised;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import ars.database.service.Service;
import ars.database.service.Services;
import ars.database.service.ServiceFactory;
import ars.database.service.event.ServiceEvent;
import ars.database.service.event.ServiceListener;
import ars.database.repository.Repository;
import ars.database.repository.Repositories;
import ars.database.repository.RepositoryFactory;
import ars.database.repository.DataConstraintException;
import ars.invoke.convert.ThrowableResolver;

/**
 * 基于Spring数据操作配置
 * 
 * @author yongqiangwu
 * 
 */
public class DatabaseConfiguration implements ThrowableResolver, ServiceFactory, RepositoryFactory,
		ApplicationContextAware {
	/**
	 * 数据关联异常编码
	 */
	public static final int CODE_ERROR_DATA_CONSTRAINT = 52070;

	private Map, Service> services = Collections.emptyMap();
	private Map, Repository> repositories = Collections.emptyMap();

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		Services.setServiceFactory(this);
		Repositories.setRepositoryFactory(this);

		// 加载数据模型对应的持久化操作对象
		Collection repositories = applicationContext.getBeansOfType(Repository.class).values();
		this.repositories = new HashMap, Repository>(repositories.size());
		for (Repository repository : repositories) {
			this.repositories.put(repository.getModel(), repository);
		}

		// 加载数据模型对应业务操作对象
		Collection services = applicationContext.getBeansOfType(Service.class).values();
		this.services = new HashMap, Service>(services.size());
		for (Service service : services) {
			this.services.put(service.getModel(), service);
		}

		// 初始化业务操作事件监听器
		Map> listeners = new HashMap>();
		try {
			for (Entry entry : applicationContext.getBeansOfType(ServiceListener.class)
					.entrySet()) {
				ServiceListener target = null;
				ServiceListener listener = entry.getValue();
				if (AopUtils.isAopProxy(listener)) {
					target = (ServiceListener) ((Advised) listener).getTargetSource().getTarget();
				}
				Class type = null;
				for (Method method : (target == null ? listener : target).getClass().getMethods()) {
					if (method.getName().equals("onServiceEvent") && (type == null || type == ServiceEvent.class)) {
						type = method.getParameterTypes()[0];
					}
				}
				List groups = listeners.get(type);
				if (groups == null) {
					groups = new LinkedList();
					listeners.put(type, groups);
				}
				groups.add(listener);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		if (!listeners.isEmpty()) {
			for (Entry> entry : listeners.entrySet()) {
				Class type = entry.getKey();
				ServiceListener[] _listeners = entry.getValue().toArray(new ServiceListener[0]);
				for (Service service : services) {
					service.setListeners(type, _listeners);
				}
			}
		}
	}

	@Override
	public int getCode(Throwable throwable) {
		return CODE_ERROR_DATA_CONSTRAINT;
	}

	@Override
	public String getMessage(Throwable throwable) {
		return throwable.getMessage();
	}

	@Override
	public boolean isResolvable(Throwable throwable) {
		return throwable != null && throwable instanceof DataConstraintException;
	}

	@Override
	public Map, Service> getServices() {
		return Collections.unmodifiableMap(this.services);
	}

	@SuppressWarnings("unchecked")
	@Override
	public  Service getService(Class model) {
		if (model == null) {
			throw new IllegalArgumentException("Illegal model:" + model);
		}
		Service service = (Service) this.services.get(model);
		if (service == null) {
			synchronized (model) {
				if ((service = (Service) this.services.get(model)) == null) {
					for (Entry, Service> entry : this.services.entrySet()) {
						if (entry.getKey().isAssignableFrom(model)) {
							service = (Service) entry.getValue();
							this.services.put(model, service);
						}
					}
				}
			}
		}
		if (service == null) {
			throw new RuntimeException("Service not found:" + model);
		}
		return service;
	}

	@Override
	public Map, Repository> getRepositories() {
		return Collections.unmodifiableMap(this.repositories);
	}

	@SuppressWarnings("unchecked")
	@Override
	public  Repository getRepository(Class model) {
		if (model == null) {
			throw new IllegalArgumentException("Illegal model:" + model);
		}
		Repository repository = (Repository) this.repositories.get(model);
		if (repository == null) {
			synchronized (model) {
				if ((repository = (Repository) this.repositories.get(model)) == null) {
					for (Entry, Repository> entry : this.repositories.entrySet()) {
						if (entry.getKey().isAssignableFrom(model)) {
							repository = (Repository) entry.getValue();
							this.repositories.put(model, repository);
						}
					}
				}
			}
		}
		if (repository == null) {
			throw new RuntimeException("Repository not found:" + model);
		}
		return repository;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy