/******************************************************************************* * Copyright (c) 2012 - 2013 GoPivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * GoPivotal, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.quickfix.validator.helper; import java.util.HashSet; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.ChildBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.core.io.Resource; import org.springframework.ide.eclipse.beans.core.internal.model.Bean; import org.springframework.ide.eclipse.beans.core.model.IBean; import org.springframework.ide.eclipse.beans.core.model.IBeanConstructorArgument; import org.springframework.ide.eclipse.beans.core.model.IBeanMethodOverride; import org.springframework.ide.eclipse.beans.core.model.IBeanProperty; import org.springframework.ide.eclipse.beans.core.model.IBeansModelElementTypes; import org.springframework.ide.eclipse.beans.ui.editor.util.BeansEditorUtils; import org.springframework.ide.eclipse.beans.ui.namespaces.NamespaceUtils; import org.springframework.ide.eclipse.config.core.schemas.BeansSchemaConstants; import org.springframework.ide.eclipse.core.SpringCore; import org.springframework.ide.eclipse.core.internal.model.SpringProject; import org.springframework.ide.eclipse.core.io.FileResource; import org.springframework.ide.eclipse.core.model.IModelElement; import org.springframework.ide.eclipse.core.model.IModelElementVisitor; import org.springframework.ide.eclipse.core.model.IModelSourceLocation; import org.springframework.ide.eclipse.core.model.IResourceModelElement; import org.springframework.util.StringUtils; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Terry Denney * @author Christian Dupuis * @author Leo Dos Santos * @author Martin Lippert */ public class BeanHelper extends Bean implements IBean { private final IDOMNode beanNode; private final IFile file; private final SpringProject springProject; public BeanHelper(IDOMNode beanNode, IFile file, IProject project) { super(new SpringProject(SpringCore.getModel(), project), new BeanDefinitionHolder(getBeanDefinition(beanNode), getElementName(beanNode))); this.beanNode = beanNode; this.file = file; this.springProject = new SpringProject(SpringCore.getModel(), project); AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) getBeanDefinition(); ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); Set<IBeanConstructorArgument> constructorArgs = getConstructorArguments(); int index = 0; for (IBeanConstructorArgument constructorArg : constructorArgs) { constructorArgumentValues.addIndexedArgumentValue(index, constructorArg.getValue()); index++; } beanDefinition.setConstructorArgumentValues(constructorArgumentValues); MutablePropertyValues propertyValues = new MutablePropertyValues(); Set<IBeanProperty> properties = getProperties(); for (IBeanProperty property : properties) { propertyValues.add(property.getElementName(), property.getValue()); } beanDefinition.setPropertyValues(propertyValues); setElementSourceLocation(new IModelSourceLocation() { public int getEndLine() { // TODO Auto-generated method stub return 0; } public Resource getResource() { return new FileResource(BeanHelper.this.file); } public int getStartLine() { // TODO Auto-generated method stub return 0; } }); } @Override public void accept(IModelElementVisitor visitor, IProgressMonitor monitor) { if (!monitor.isCanceled()) { visitor.visit(this, monitor); } } @SuppressWarnings("rawtypes") @Override public Object getAdapter(Class adapter) { // TODO Auto-generated method stub return null; } @Override public String[] getAliases() { // TODO Auto-generated method stub return null; } @Override public String getClassName() { return getClassName(beanNode); } @Override public Set<IBeanConstructorArgument> getConstructorArguments() { Set<IBeanConstructorArgument> arguments = new HashSet<IBeanConstructorArgument>(); NodeList childNodes = beanNode.getChildNodes(); NamedNodeMap attrs = beanNode.getAttributes(); int counter = 0; for (int i = 0; i < childNodes.getLength(); i++) { Node child = childNodes.item(i); String localName = child.getLocalName(); if (localName != null && localName.equals(BeansSchemaConstants.ELEM_CONSTRUCTOR_ARG)) { String name = null; NamedNodeMap attributes = child.getAttributes(); Node attribute = attributes.getNamedItem(BeansSchemaConstants.ATTR_NAME); if (attribute != null) { name = attribute.getNodeValue(); } arguments.add(new BeanConstructorArgumentHelper(counter, name, (IDOMNode) child, file, this)); counter++; } } // If no <constructor-arg> children found, look for c: prefixed // attributes on the <bean> if (counter == 0 && arguments.isEmpty() && attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { Node child = attrs.item(i); if (NamespaceUtils.C_NAMESPACE_URI.equals(child.getNamespaceURI())) { String localName = child.getLocalName(); if (localName != null) { String name = null; if (localName.endsWith("-ref")) { name = localName.substring(0, localName.length() - 4); } else { name = localName; } arguments.add(new BeanConstructorArgumentHelper(counter, name, (IDOMNode) child, file, this)); counter++; } } } } return arguments; } @Override public IModelElement[] getElementChildren() { return getConstructorArguments().toArray(new IModelElement[0]); } @Override public int getElementEndLine() { // TODO Auto-generated method stub return 0; } @Override public String getElementName() { return getElementName(beanNode); } @Override public IResource getElementResource() { return file; } @Override public IResourceModelElement getElementSourceElement() { return springProject; } @Override public int getElementStartLine() { // TODO Auto-generated method stub return 0; } @Override public int getElementType() { return IBeansModelElementTypes.BEAN_TYPE; } @Override public Set<IBeanMethodOverride> getMethodOverrides() { // TODO Auto-generated method stub return new HashSet<IBeanMethodOverride>(); } @Override public String getParentName() { return getBeanDefinition().getParentName(); } @Override public Set<IBeanProperty> getProperties() { Set<IBeanProperty> properties = new HashSet<IBeanProperty>(); NodeList childNodes = beanNode.getChildNodes(); int counter = 0; for (int i = 0; i < childNodes.getLength(); i++) { Node child = childNodes.item(i); String localName = child.getLocalName(); if (localName != null && localName.equals(BeansSchemaConstants.ELEM_PROPERTY)) { properties.add(new BeanPropertyHelper((IDOMNode) child, file, this)); counter++; } } return properties; } @Override public IBeanProperty getProperty(String name) { Set<IBeanProperty> properties = getProperties(); for (IBeanProperty property : properties) { if (name != null && name.equals(property.getElementName())) { return property; } } return null; } @Override public boolean isAbstract() { // TODO Auto-generated method stub return false; } @Override public boolean isChildBean() { return getParentName() != null; } @Override public boolean isElementArchived() { // TODO Auto-generated method stub return false; } @Override public boolean isExternal() { // TODO Auto-generated method stub return false; } @Override public boolean isFactory() { // TODO Auto-generated method stub return false; } @Override public boolean isGeneratedElementName() { // TODO Auto-generated method stub return false; } @Override public boolean isInfrastructure() { // TODO Auto-generated method stub return false; } @Override public boolean isInnerBean() { Node parentNode = beanNode.getParentNode(); if (parentNode != null) { String localName = parentNode.getLocalName(); if (localName != null && localName.equals(BeansSchemaConstants.ELEM_BEANS)) { return false; } } return true; } @Override public boolean isLazyInit() { // TODO Auto-generated method stub return false; } @Override public boolean isRootBean() { // TODO Auto-generated method stub return false; } @Override public boolean isSingleton() { // TODO Auto-generated method stub return false; } private static BeanDefinition getBeanDefinition(IDOMNode node) { AbstractBeanDefinition bd = null; if (BeansEditorUtils.getAttribute(node, "parent") != null) { bd = new ChildBeanDefinition(BeansEditorUtils.getAttribute(node, "parent")); bd.setBeanClassName(getClassName(node)); } else { bd = new RootBeanDefinition(getClassName(node)); } String factoryBean = BeansEditorUtils.getAttribute(node, "factory-bean"); String factoryMethod = BeansEditorUtils.getAttribute(node, "factory-method"); String autowireValue = BeansEditorUtils.getAttribute(node, "autowire"); if (StringUtils.hasText(factoryBean)) { bd.setFactoryBeanName(factoryBean); } if (StringUtils.hasText(factoryMethod)) { bd.setFactoryMethodName(factoryMethod); } if (StringUtils.hasText(autowireValue)) { bd.setAutowireMode(getAutowireMode(node, autowireValue)); } return bd; } private static int getAutowireMode(Node node, String autowireValue) { String att = autowireValue; if ("default".equals(att)) { Node parent = node.getParentNode(); if (parent != null) { String defaultAutowire = BeansEditorUtils.getAttribute(parent, "default-autowire"); if (StringUtils.hasText(defaultAutowire)) { att = defaultAutowire; } } } int autowire = AbstractBeanDefinition.AUTOWIRE_NO; if ("byName".equals(att)) { autowire = AbstractBeanDefinition.AUTOWIRE_BY_NAME; } else if ("byType".equals(att)) { autowire = AbstractBeanDefinition.AUTOWIRE_BY_TYPE; } else if ("constructor".equals(att)) { autowire = AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR; } else if ("autodetect".equals(att)) { autowire = AbstractBeanDefinition.AUTOWIRE_AUTODETECT; } // Else leave default value. return autowire; } private static String getClassName(IDOMNode node) { return BeansEditorUtils.getClassNameForBean(node); } protected static String getElementName(IDOMNode n) { NamedNodeMap attributes = n.getAttributes(); if (attributes != null) { Node id = attributes.getNamedItem(BeansSchemaConstants.ATTR_NAME); if (id != null) { return id.getNodeValue(); } else { id = attributes.getNamedItem(BeansSchemaConstants.ATTR_ID); if (id != null) { return id.getNodeValue(); } } } // TODO: figure out what to do when there's no name return "beanid"; } }