/* * Copyright 2015 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.social.config.xml; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.NamespaceHandler; import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * Base {@link NamespaceHandler} for Spring Social provider modules to create configuration namespaces. * Requires, at minimum, that the provider-specific namespace provider an AbstractProviderConfigBeanDefinition for parsing "config" elements. * @author Craig Walls */ public abstract class AbstractProviderConfigNamespaceHandler implements NamespaceHandler { public final void init() { loadParsers(); } public final BeanDefinition parse(Element element, ParserContext parserContext) { String name = parserContext.getDelegate().getLocalName(element); BeanDefinitionParser parser = parsers.get(name); if (parser == null) { loadParsers(); } if(parser == null) { reportUnsupportedNodeType(name, parserContext, element); return null; } return parser.parse(element, parserContext); } public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder beanDefinitionHolder, ParserContext parserContext) { return beanDefinitionHolder; } /** * Implemented by provider namespaces to provide an instance of the bean definition parser that will parse the "config" element. * This is the only configuration element required by a provider namespace. * If a provider namespace offers additional elements, then their bean definition parsers may be registered by overriding the loadParsers() method. * @return an instance of AbstractProviderConfigBeanDefinitionParser to register against the "config" element in the namespace. */ protected abstract AbstractProviderConfigBeanDefinitionParser getProviderConfigBeanDefinitionParser(); /** * Hook method to allow provider-specific implementation to register bean definition parsers for their namespace. * An overriding method will simply add one or more bean definition parsers to the given map where the key is the name of the element the parser handles. * Overriding this method is optional and there is no need to override it just to add the provider-specific implementation of AbstractProviderConfigBeanDefinitionParser. * That bean definition parser will always be registered, whether or not this method is overridden. * @param parsers a Map of parsers to be applied when parsing the namespace. */ protected void loadParsers(Map<String, BeanDefinitionParser> parsers) {} private void reportUnsupportedNodeType(String name, ParserContext parserContext, Node node) { parserContext.getReaderContext().fatal("Twitter namespace does not support " + (node instanceof Element ? "element" : "attribute") + " [" + name + "]", node); } private void loadParsers() { parsers.put("config", getProviderConfigBeanDefinitionParser()); loadParsers(parsers); } private final Map<String, BeanDefinitionParser> parsers = new HashMap<String, BeanDefinitionParser>(); }