/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.fmk.call; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.api.call.DSCall; import org.solmix.api.call.DSCallInterceptor; import org.solmix.api.call.DSCallManager; import org.solmix.api.call.InterceptorOrder; import org.solmix.api.call.InterceptorOrder.PRIORITY; import org.solmix.api.exception.SlxException; import org.solmix.api.types.Texception; import org.solmix.api.types.Tmodule; import org.solmix.commons.collections.DataTypeMap; import org.solmix.commons.util.DataUtils; import org.solmix.ds.context.Context; import org.solmix.fmk.datasource.BasicDataSource; import org.solmix.runtime.SystemContext; import org.solmix.runtime.cm.ConfigureUnit; import org.solmix.runtime.cm.ConfigureUnitManager; /** * * @author solmix.f@gmail.com * @version $Id$ 2013年12月25日 */ public class DSCallManagerImpl implements DSCallManager { private static final Logger log = LoggerFactory.getLogger(DSCallManagerImpl.class.getName()); private final SystemContext sc; private boolean executeFirstSet=false; private boolean inited; private DataTypeMap config; protected final LinkedList<DSCallInterceptor> interceptors = new LinkedList<DSCallInterceptor>(); public DSCallManagerImpl(final SystemContext sc) { this.sc = sc; } @Override public void addInterceptors(DSCallInterceptor... interceptors) { if(inited) new IllegalStateException("Cannot add Interceptor After the manager have been initialed"); for(DSCallInterceptor i:interceptors){ positionInterceptor( InterceptorOrder.class.isAssignableFrom(i.getClass())? InterceptorOrder.class.cast(i).priority():InterceptorOrder.AFTER_DEFAULT,i); } } public void init() throws SlxException{ if(!inited){ this.configInterceptor(); } } /** * @param priority * @param i */ protected void positionInterceptor(PRIORITY priority, DSCallInterceptor i) { switch(priority){ case AFTER_DEFAULT: interceptors.addLast(i); break; case BEFORE_DEFAULT: int pos = executeFirstSet ? 1 : 0; interceptors.add(pos, i); break; case FIRST_BEFORE_DEFAULT: if (executeFirstSet) throw new IllegalStateException("Cannot set more than one Interceptor to be executed first"); log.info("DSCallInterceptor {} will always be executed first", i); interceptors.addFirst(i); executeFirstSet = true; break; } } @SuppressWarnings("unchecked") protected void configInterceptor() throws SlxException{ ConfigureUnitManager cum = sc.getExtension(ConfigureUnitManager.class); ConfigureUnit cu = null; DataTypeMap frameworkConfig; try { cu = cum.getConfigureUnit(BasicDataSource.PID); } catch (IOException e) { throw new SlxException(Tmodule.SQL, Texception.IO_EXCEPTION, e); } if (cu != null) frameworkConfig= cu.getProperties(); else frameworkConfig= new DataTypeMap(); Map<Object,Object> merged= new HashMap<Object,Object>(); DataUtils.mapMerge(frameworkConfig, merged); DataUtils.mapMerge(config, merged); DataTypeMap interceptorConfig=new DataTypeMap(Collections.unmodifiableMap(merged)); for(DSCallInterceptor i:interceptors){ i.configure(interceptorConfig); } } DSCallInterceptor[] toArray(){ DSCallInterceptor[] array= new DSCallInterceptor[interceptors.size()]; return interceptors.toArray(array); } @Override public DSCall getDSCall() throws SlxException { init(); return new DSCallImpl(toArray()); } @Override public DSCall getDSCall(Context requestcontext) throws SlxException { DSCall call= getDSCall(); call.setRequestContext(requestcontext); return call; } /** * {@inheritDoc} * * @see org.solmix.api.call.DSCallManager#setConfig(org.solmix.commons.collections.DataTypeMap) */ @Override public void setConfig(DataTypeMap config) { this.config=config; } }