/*
* Copyright 2012 astamuse company,Ltd.
*
* 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 com.astamuse.asta4d.interceptor.base;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.astamuse.asta4d.util.GroupedException;
public class InterceptorUtil {
private final static Logger logger = LoggerFactory.getLogger(InterceptorUtil.class);
private final static class ExecutorWrapping<H> implements GenericInterceptor<H> {
private Executor<H> executor;
public ExecutorWrapping(Executor<H> executor) {
this.executor = executor;
}
@Override
public boolean beforeProcess(H executionHolder) throws Exception {
executor.execute(executionHolder);
return true;
}
@Override
public void afterProcess(H exectionHolder, ExceptionHandler ex) {
}
}
public final static <H> void executeWithConvertableInterceptors(H executionHolder,
List<GenericInterceptorConvertable<H>> interceptorList, Executor<H> executor) throws Exception {
List<GenericInterceptor<H>> runList = new ArrayList<>();
if (interceptorList != null) {
for (GenericInterceptorConvertable<H> interceptor : interceptorList) {
runList.add(interceptor.asGenericInterceptor());
}
}
}
public final static <H> void executeWithInterceptors(H executionHolder, List<? extends GenericInterceptor<H>> interceptorList,
Executor<H> executor) throws Exception {
List<GenericInterceptor<H>> runList = new ArrayList<>();
if (interceptorList != null) {
runList.addAll(interceptorList);
}
runList.add(new ExecutorWrapping<>(executor));
ExceptionHandler eh = new ExceptionHandler();
GenericInterceptor<H> lastInterceptor = beforeProcess(executionHolder, runList, eh);
afterProcess(lastInterceptor, executionHolder, runList, eh);
// if the passed exception has not been cleared, we will throw it
// anyway.
if (eh.getException() != null) {
throw eh.getException();
}
}
private final static <H> GenericInterceptor<H> beforeProcess(H execution, List<GenericInterceptor<H>> interceptorList,
ExceptionHandler eh) throws Exception {
GenericInterceptor<H> lastInterceptor = null;
for (GenericInterceptor<H> interceptor : interceptorList) {
try {
if (!interceptor.beforeProcess(execution)) {
break;
}
lastInterceptor = interceptor;
} catch (Exception ex) {
eh.setException(ex);
return lastInterceptor;
}
}
return lastInterceptor;
}
private final static <H> void afterProcess(GenericInterceptor<H> lastInterceptor, H execution,
List<GenericInterceptor<H>> interceptorList, ExceptionHandler eh) {
GenericInterceptor<H> interceptor = null;
boolean foundStoppedPoint = false;
List<Exception> exList = new LinkedList<>();
for (int i = interceptorList.size() - 1; i >= 0; i--) {
interceptor = interceptorList.get(i);
if (!foundStoppedPoint) {
foundStoppedPoint = interceptor == lastInterceptor;
}
if (foundStoppedPoint) {
try {
interceptor.afterProcess(execution, eh);
} catch (Exception afterEx) {
logger.warn("There is an exception occured in after process of interceptors.", afterEx);
exList.add(afterEx);
}
}
}
// if there are exceptions in after process, we should throw them.
if (!exList.isEmpty()) {
GroupedException ge = new GroupedException();
ge.setExceptionList(exList);
logger.error("There are exception(s) orrcured on after interceptor process", ge);
throw ge;
}
}
}