blob: 711ab6e2435dc7cc27b33280725bcd38282843e0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.cocoon.portal.spring;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.apache.cocoon.portal.services.aspects.AspectChain;
import org.apache.cocoon.portal.services.aspects.support.AspectChainImpl;
import org.apache.cocoon.spring.configurator.impl.AbstractElementParser;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
*
* @version $Id$
*/
public class AspectsBeanDefinitionParser extends AbstractElementParser {
protected final String baseClass;
protected final Class aspectChainClass;
public AspectsBeanDefinitionParser(final String className) {
this.baseClass = className;
this.aspectChainClass = AspectChainImpl.class;
}
public AspectsBeanDefinitionParser(final String className, Class aspectChainClass) {
this.baseClass = className;
this.aspectChainClass = aspectChainClass;
}
/**
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
*/
public BeanDefinition parse(Element element, ParserContext parserContext) {
// create a new bean definition for the aspect chain
RootBeanDefinition beanDef = this.createBeanDefinition(this.aspectChainClass, null, false);
final ManagedList aspectBeans = new ManagedList();
aspectBeans.setSource(parserContext.getReaderContext().extractSource(element));
final List aspectProperties = new ArrayList();
final Element[] aspects = this.getChildElements(element, "aspect");
for(int i=0; i<aspects.length; i++) {
final String ref = this.getAttributeValue(aspects[i], "ref", null);
final String type= this.getAttributeValue(aspects[i], "type", null);
if ( ref == null && type == null ) {
throw new BeanDefinitionStoreException("Element 'aspect' must have either a 'ref' or a 'type' attribute.");
}
if ( ref != null && type != null ) {
throw new BeanDefinitionStoreException("Element 'aspect' must have either a 'ref' or a 'type' attribute, but not both.");
}
final String beanName = (ref != null ? ref : this.baseClass + '.' + type);
aspectBeans.add(new RuntimeBeanReference(beanName));
// properties
final Properties props = new Properties();
final Element[] properties = this.getChildElements(aspects[i], "property");
for(int m=0; m<properties.length;m++) {
props.setProperty(this.getAttributeValue(properties[m], "name", null),
this.getAttributeValue(properties[m], "value", null));
}
if ( props.size() == 0 ) {
aspectProperties.add(AspectChain.EMPTY_PROPERTIES);
} else {
aspectProperties.add(props);
}
}
try {
beanDef.getConstructorArgumentValues().addIndexedArgumentValue(0, ClassUtils.forName(this.baseClass, getClass().getClassLoader()));
} catch (ClassNotFoundException e) {
throw new BeanDefinitionStoreException("Unable to load aspect class: " + this.baseClass, e);
}
beanDef.getConstructorArgumentValues().addIndexedArgumentValue(1, aspectBeans);
beanDef.getConstructorArgumentValues().addIndexedArgumentValue(2, aspectProperties);
if ( !parserContext.isNested() ) {
String id = element.getAttribute(BeanDefinitionParserDelegate.ID_ATTRIBUTE);
String nameAttr = element.getAttribute(BeanDefinitionParserDelegate.NAME_ATTRIBUTE);
List aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = (String) aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
final BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDef, beanName, StringUtils.toStringArray(aliases));
BeanDefinitionReaderUtils.registerBeanDefinition(holder, parserContext.getRegistry());
}
return beanDef;
}
}