/* * Copyright 2004-2012 the original author or authors. * * 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 org.springframework.webflow.definition.registry; import java.util.Map; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.style.ToStringCreator; import org.springframework.util.Assert; import org.springframework.webflow.definition.FlowDefinition; /** * A generic registry implementation for housing one or more flow definitions. * * @author Keith Donald * @author Scott Andrews */ public class FlowDefinitionRegistryImpl implements FlowDefinitionRegistry { private static final Log logger = LogFactory.getLog(FlowDefinitionRegistryImpl.class); /** * The map of loaded Flow definitions maintained in this registry. */ private Map<String, FlowDefinitionHolder> flowDefinitions; /** * An optional parent flow definition registry. */ private FlowDefinitionRegistry parent; public FlowDefinitionRegistryImpl() { flowDefinitions = new TreeMap<String, FlowDefinitionHolder>(); } // implementing FlowDefinitionLocator public FlowDefinition getFlowDefinition(String id) throws NoSuchFlowDefinitionException, FlowDefinitionConstructionException { Assert.hasText(id, "An id is required to lookup a FlowDefinition"); try { if (logger.isDebugEnabled()) { logger.debug("Getting FlowDefinition with id '" + id + "'"); } return getFlowDefinitionHolder(id).getFlowDefinition(); } catch (NoSuchFlowDefinitionException e) { if (parent != null) { // try parent return parent.getFlowDefinition(id); } throw e; } } // implementing FlowDefinitionRegistry public boolean containsFlowDefinition(String flowId) { boolean containsFlow = flowDefinitions.containsKey(flowId); if (!containsFlow && parent != null) { containsFlow = parent.containsFlowDefinition(flowId); } return containsFlow; } public int getFlowDefinitionCount() { return flowDefinitions.size(); } public String[] getFlowDefinitionIds() { return flowDefinitions.keySet().toArray(new String[flowDefinitions.size()]); } public FlowDefinitionRegistry getParent() { return parent; } public void setParent(FlowDefinitionRegistry parent) { this.parent = parent; } public void registerFlowDefinition(FlowDefinitionHolder definitionHolder) { Assert.notNull(definitionHolder, "The holder of the flow definition to register is required"); if (logger.isDebugEnabled()) { logger.debug("Registering flow definition '" + definitionHolder.getFlowDefinitionResourceString() + "' under id '" + definitionHolder.getFlowDefinitionId() + "'"); } flowDefinitions.put(definitionHolder.getFlowDefinitionId(), definitionHolder); } public void registerFlowDefinition(FlowDefinition definition) { registerFlowDefinition(new StaticFlowDefinitionHolder(definition)); } public void destroy() { for (FlowDefinitionHolder holder : flowDefinitions.values()) { holder.destroy(); } } // internal helpers /** * Returns the identified flow definition holder. Throws an exception if it cannot be found. */ private FlowDefinitionHolder getFlowDefinitionHolder(String id) throws NoSuchFlowDefinitionException { FlowDefinitionHolder holder = flowDefinitions.get(id); if (holder == null) { throw new NoSuchFlowDefinitionException(id); } return holder; } public String toString() { return new ToStringCreator(this).append("flowIds", getFlowDefinitionIds()).append("parent", parent).toString(); } }