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.Field;
import java.lang.reflect.Method;
import java.lang.annotation.Annotation;

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

import ars.util.Strings;
import ars.database.service.Service;
import ars.database.service.Services;
import ars.database.service.ServiceFactory;
import ars.database.service.WorkflowService;
import ars.database.service.event.ServiceEvent;
import ars.database.service.event.ServiceListener;
import ars.database.repository.Transfer;
import ars.database.repository.Transform;
import ars.database.repository.Repository;
import ars.database.repository.Repositories;
import ars.database.repository.RepositoryFactory;
import ars.database.repository.StandardTransferManager;
import ars.database.repository.DataConstraintException;
import ars.invoke.convert.ThrowableResolver;

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

	private String transfer; // 数据转换加载路径(模型全路径名.属性名)
	private Map, Service> services = Collections.emptyMap();
	private Map, Repository> repositories = Collections.emptyMap();

	public String getTransfer() {
		return transfer;
	}

	public void setTransfer(String transfer) {
		this.transfer = transfer;
	}

	@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) {
			if (service instanceof WorkflowService) {
				ProcessEngine processEngine = applicationContext.getBean(ProcessEngine.class);
				((WorkflowService) service).setProcessEngine(processEngine);
			}
			this.services.put(service.getModel(), service);

			// 加载数据查询转换配置
			Class model = service.getModel();
			while (model != Object.class) {
				for (Field field : model.getDeclaredFields()) {
					String path = model.getName() + "." + field.getName();
					if (this.transfer == null || Strings.matches(path, this.transfer)) {
						for (Annotation annotation : field.getAnnotations()) {
							if (annotation.annotationType() == Transfer.class) {
								Transfer transfer = (Transfer) annotation;
								Transform transform = new Transform(transfer.key(), transfer.target(),
										transfer.resource(), transfer.lazy());
								this.register(model, field.getName(), transform);
								break;
							}
						}
					}
				}
				model = model.getSuperclass();
			}
		}

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

	@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) {
				service = (Service) this.services.get(model);
				if (service == 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) {
				repository = (Repository) this.repositories.get(model);
				if (repository == 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