001: /*
002: * Copyright (c) 2002-2006 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.xwork.config.providers;
006:
007: import java.util.ArrayList;
008: import java.util.Iterator;
009: import java.util.LinkedHashMap;
010: import java.util.List;
011: import java.util.Map;
012:
013: import com.opensymphony.xwork.ObjectFactory;
014: import com.opensymphony.xwork.interceptor.Interceptor;
015: import com.opensymphony.xwork.config.ConfigurationException;
016: import com.opensymphony.xwork.config.entities.InterceptorConfig;
017: import com.opensymphony.xwork.config.entities.InterceptorStackConfig;
018: import com.opensymphony.xwork.config.entities.PackageConfig;
019: import com.opensymphony.xwork.config.entities.InterceptorMapping;
020: import org.apache.commons.logging.Log;
021: import org.apache.commons.logging.LogFactory;
022:
023: /**
024: * Builds a list of interceptors referenced by the refName in the supplied PackageConfig.
025: *
026: * @author Mike
027: * @author Rainer Hermanns
028: * @author tmjee
029: *
030: * @version $Date: 2007-06-02 10:59:27 +0200 (Sat, 02 Jun 2007) $ $Id: InterceptorBuilder.java 1532 2007-06-02 08:59:27Z tm_jee $
031: */
032: public class InterceptorBuilder {
033:
034: private static final Log LOG = LogFactory
035: .getLog(InterceptorBuilder.class);
036:
037: /**
038: * Builds a list of interceptors referenced by the refName in the supplied PackageConfig (InterceptorMapping object).
039: *
040: * @param packageConfig
041: * @param refName
042: * @param refParams
043: * @return list of interceptors referenced by the refName in the supplied PackageConfig (InterceptorMapping object).
044: * @throws ConfigurationException
045: */
046: public static List constructInterceptorReference(
047: PackageConfig packageConfig, String refName, Map refParams)
048: throws ConfigurationException {
049: Object referencedConfig = packageConfig
050: .getAllInterceptorConfigs().get(refName);
051: List result = new ArrayList();
052:
053: if (referencedConfig == null) {
054: LOG
055: .error("Unable to find interceptor class referenced by ref-name "
056: + refName);
057: } else {
058: if (referencedConfig instanceof InterceptorConfig) {
059: result
060: .add(new InterceptorMapping(
061: refName,
062: ObjectFactory
063: .getObjectFactory()
064: .buildInterceptor(
065: (InterceptorConfig) referencedConfig,
066: refParams)));
067: } else if (referencedConfig instanceof InterceptorStackConfig) {
068: InterceptorStackConfig stackConfig = (InterceptorStackConfig) referencedConfig;
069:
070: if ((refParams != null) && (refParams.size() > 0)) {
071: result = constructParameterizedInterceptorReferences(
072: packageConfig, stackConfig, refParams);
073: } else {
074: result.addAll(stackConfig.getInterceptors());
075: }
076:
077: } else {
078: LOG.error("Got unexpected type for interceptor "
079: + refName + ". Got " + referencedConfig);
080: }
081: }
082:
083: return result;
084: }
085:
086: /**
087: * Builds a list of interceptors referenced by the refName in the supplied PackageConfig overriding the properties
088: * of the referenced interceptor with refParams.
089: *
090: * @param packageConfig
091: * @param stackConfig
092: * @param refParams The overridden interceptor properies
093: * @return list of interceptors referenced by the refName in the supplied PackageConfig overridden with refParams.
094: */
095: private static List constructParameterizedInterceptorReferences(
096: PackageConfig packageConfig,
097: InterceptorStackConfig stackConfig, Map refParams) {
098: List result;
099: Map params = new LinkedHashMap();
100:
101: /*
102: * We strip
103: *
104: * <interceptor-ref name="someStack">
105: * <param name="interceptor1.param1">someValue</param>
106: * <param name="interceptor1.param2">anotherValue</param>
107: * </interceptor-ref>
108: *
109: * down to map
110: * interceptor1 -> [param1 -> someValue, param2 -> anotherValue]
111: *
112: * or
113: * <interceptor-ref name="someStack">
114: * <param name="interceptorStack1.interceptor1.param1">someValue</param>
115: * <param name="interceptorStack1.interceptor1.param2">anotherValue</param>
116: * </interceptor-ref>
117: *
118: * down to map
119: * interceptorStack1 -> [interceptor1.param1 -> someValue, interceptor1.param2 -> anotherValue]
120: *
121: */
122: for (Iterator iter = refParams.keySet().iterator(); iter
123: .hasNext();) {
124: String key = (String) iter.next();
125: String value = (String) refParams.get(key);
126:
127: try {
128: String name = key.substring(0, key.indexOf('.'));
129: key = key.substring(key.indexOf('.') + 1);
130:
131: Map map;
132: if (params.containsKey(name)) {
133: map = (Map) params.get(name);
134: } else {
135: map = new LinkedHashMap();
136: }
137:
138: map.put(key, value);
139: params.put(name, map);
140:
141: } catch (Exception e) {
142: LOG.warn("No interceptor found for name = " + key);
143: }
144: }
145:
146: result = new ArrayList(stackConfig.getInterceptors());
147:
148: for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
149: String key = (String) iter.next();
150: Map map = (Map) params.get(key);
151:
152: Object interceptorCfgObj = packageConfig
153: .getAllInterceptorConfigs().get(key);
154:
155: /*
156: * Now we attempt to separate out param that refers to Interceptor
157: * and Interceptor stack, eg.
158: *
159: * <interceptor-ref name="someStack">
160: * <param name="interceptor1.param1">someValue</param>
161: * ...
162: * </interceptor-ref>
163: *
164: * vs
165: *
166: * <interceptor-ref name="someStack">
167: * <param name="interceptorStack1.interceptor1.param1">someValue</param>
168: * ...
169: * </interceptor-ref>
170: */
171: if (interceptorCfgObj instanceof InterceptorConfig) { // interceptor-ref param refer to an interceptor
172: InterceptorConfig cfg = (InterceptorConfig) interceptorCfgObj;
173: Interceptor interceptor = ObjectFactory
174: .getObjectFactory().buildInterceptor(cfg, map);
175:
176: InterceptorMapping mapping = new InterceptorMapping(
177: key, interceptor);
178: if (result != null && result.contains(mapping)) {
179: // if an existing interceptor mapping exists,
180: // we remove from the result Set, just to make sure
181: // there's always one unique mapping.
182: int index = result.indexOf(mapping);
183: result.set(index, mapping);
184: } else {
185: result.add(mapping);
186: }
187: } else if (interceptorCfgObj instanceof InterceptorStackConfig) { // interceptor-ref param refer to an interceptor stack
188:
189: // If its an interceptor-stack, we call this method recursively untill,
190: // all the params (eg. interceptorStack1.interceptor1.param etc.)
191: // are resolved down to a specific interceptor.
192:
193: InterceptorStackConfig stackCfg = (InterceptorStackConfig) interceptorCfgObj;
194: List tmpResult = constructParameterizedInterceptorReferences(
195: packageConfig, stackCfg, map);
196: for (Iterator i = tmpResult.iterator(); i.hasNext();) {
197: InterceptorMapping tmpInterceptorMapping = (InterceptorMapping) i
198: .next();
199: if (result.contains(tmpInterceptorMapping)) {
200: int index = result
201: .indexOf(tmpInterceptorMapping);
202: result.set(index, tmpInterceptorMapping);
203: } else {
204: result.add(tmpInterceptorMapping);
205: }
206: }
207: }
208: }
209: return result;
210: }
211: }
|