1 17 package org.apache.forrest.locationmap.lm; 18 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.Map ; 22 23 import org.apache.avalon.framework.component.WrapperComponentManager; 24 import org.apache.avalon.framework.configuration.Configuration; 25 import org.apache.avalon.framework.configuration.ConfigurationException; 26 import org.apache.avalon.framework.container.ContainerUtil; 27 import org.apache.avalon.framework.logger.AbstractLogEnabled; 28 import org.apache.avalon.framework.logger.Logger; 29 import org.apache.avalon.framework.service.DefaultServiceManager; 30 import org.apache.avalon.framework.service.DefaultServiceSelector; 31 import org.apache.avalon.framework.service.ServiceManager; 32 import org.apache.cocoon.components.treeprocessor.InvokeContext; 33 import org.apache.cocoon.matching.Matcher; 34 import org.apache.cocoon.selection.Selector; 35 36 56 public final class LocationMap extends AbstractLogEnabled { 57 58 62 public static final String URI = "http://apache.org/forrest/locationmap/1.0"; 63 64 79 public static final String ANCHOR_NAME = "lm"; 80 81 89 public static final String HINT_KEY = "hint"; 90 91 94 public static final String HINT_PARAM = "#" + ANCHOR_NAME + ":" + HINT_KEY; 95 96 97 private LocationMapServiceManager m_manager; 98 99 100 private String m_defaultMatcher; 101 102 103 private String m_defaultSelector; 104 105 106 private LocatorNode[] m_locatorNodes; 107 108 109 public LocationMap(ServiceManager manager) { 110 m_manager = new LocationMapServiceManager(manager); 111 } 112 113 117 public void build(final Configuration configuration) throws ConfigurationException { 118 119 final Configuration components = configuration.getChild("components"); 121 122 Configuration child = components.getChild("matchers",false); 124 if (child != null) { 125 final DefaultServiceSelector matcherSelector = new DefaultServiceSelector(); 126 m_defaultMatcher = child.getAttribute("default"); 127 final Configuration[] matchers = child.getChildren("matcher"); 128 for (int i = 0; i < matchers.length; i++) { 129 String name = matchers[i].getAttribute("name"); 130 String src = matchers[i].getAttribute("src"); 131 Matcher matcher = (Matcher) createComponent(src, matchers[i]); 132 matcherSelector.put(name, matcher); 133 } 134 matcherSelector.makeReadOnly(); 135 if (!matcherSelector.isSelectable(m_defaultMatcher)) { 136 throw new ConfigurationException("Default matcher is not defined."); 137 } 138 m_manager.put(Matcher.ROLE+"Selector", matcherSelector); 139 } 140 141 child = components.getChild("selectors",false); 143 if (child != null) { 144 final DefaultServiceSelector selectorSelector = new DefaultServiceSelector(); 145 m_defaultSelector = child.getAttribute("default"); 146 final Configuration[] selectors = child.getChildren("selector"); 147 for (int i = 0; i < selectors.length; i++) { 148 String name = selectors[i].getAttribute("name"); 149 String src = selectors[i].getAttribute("src"); 150 Selector selector = (Selector) createComponent(src,selectors[i]); 151 selectorSelector.put(name,selector); 152 } 153 selectorSelector.makeReadOnly(); 154 if (!selectorSelector.isSelectable(m_defaultSelector)) { 155 throw new ConfigurationException("Default selector is not defined."); 156 } 157 m_manager.put(Selector.ROLE+"Selector",selectorSelector); 158 } 159 160 m_manager.makeReadOnly(); 161 162 final Configuration[] children = configuration.getChildren("locator"); 164 m_locatorNodes = new LocatorNode[children.length]; 165 for (int i = 0; i < children.length; i++) { 166 m_locatorNodes[i] = new LocatorNode(this, m_manager); 167 m_locatorNodes[i].enableLogging(getLogger()); 168 m_locatorNodes[i].build(children[i]); 169 } 170 } 171 172 181 private Object createComponent(String src, Configuration config) throws ConfigurationException { 182 Object component = null; 183 try { 184 component = Class.forName(src).newInstance(); 185 ContainerUtil.enableLogging(component,getLogger()); 186 if (config != null) { 187 ContainerUtil.configure(component, config); 188 } 189 ContainerUtil.initialize(component); 190 } catch (Exception e) { 191 throw new ConfigurationException("Couldn't create object of type " + src,e); 192 } 193 return component; 194 } 195 196 public void dispose() { 197 final Iterator components = m_manager.getObjects(); 198 while(components.hasNext()) { 199 ContainerUtil.dispose(components.next()); 200 } 201 m_manager = null; 202 m_locatorNodes = null; 203 } 204 205 210 public String locate(String hint, Map om) throws Exception { 211 212 String location = null; 213 214 final InvokeContext context = new InvokeContext(); 215 final Logger contextLogger = getLogger().getChildLogger("ctx"); 216 217 ContainerUtil.enableLogging(context, contextLogger); 218 ContainerUtil.compose(context, new WrapperComponentManager(m_manager)); 219 ContainerUtil.service(context, m_manager); 220 221 final Map anchorMap = new HashMap (2); 222 anchorMap.put(HINT_KEY,hint); 223 context.pushMap(ANCHOR_NAME,anchorMap); 224 225 for (int i = 0; i < m_locatorNodes.length; i++) { 226 location = m_locatorNodes[i].locate(om,context); 227 if (location != null) { 228 break; 229 } 230 } 231 232 ContainerUtil.dispose(context); 233 234 if (getLogger().isDebugEnabled() && location == null) { 235 getLogger().debug("No location matched request with hint " + hint); 236 } 237 238 return location; 239 } 240 241 244 String getDefaultMatcher() { 245 return m_defaultMatcher; 246 } 247 248 251 String getDefaultSelector() { 252 return m_defaultSelector; 253 } 254 255 259 private static class LocationMapServiceManager extends DefaultServiceManager { 260 261 LocationMapServiceManager(ServiceManager parent) { 262 super(parent); 263 } 264 265 Iterator getObjects() { 266 return super.getObjectMap().values().iterator(); 267 } 268 269 } 270 271 } 272 | Popular Tags |