From 3ae3de19a91d65b81c02bad302843e4803fc2959 Mon Sep 17 00:00:00 2001 From: Chris Beams Date: Sat, 21 Mar 2009 19:00:57 +0000 Subject: [PATCH] + Updated all projects to use the re-introduced org.springframework.asm instead of org.objectweb.asm (.java, template.mf, ivy.xml, and .classpath files have been updated) + Finished support for @Import, including detection of circular imports --- org.springframework.aop/.classpath | 7 +- org.springframework.aop/ivy.xml | 3 +- .../xml/BeanDefinitionParserDelegate.java | 15 +- org.springframework.config.java/.classpath | 4 +- org.springframework.config.java/.project | 11 + org.springframework.config.java/ivy.xml | 3 +- .../springframework/config/java/Import.java | 46 +++ .../java/support/AddAnnotationAdapter.java | 10 +- .../java/support/AnnotationAdapter.java | 12 +- .../config/java/support/AsmUtils.java | 4 +- .../java/support/CircularImportException.java | 40 +++ .../java/support/ConfigurationClass.java | 41 ++- .../ConfigurationClassMethodVisitor.java | 10 +- .../support/ConfigurationClassVisitor.java | 32 +- .../java/support/ConfigurationEnhancer.java | 6 +- .../java/support/ConfigurationParser.java | 2 +- .../java/support/ImportAnnotationVisitor.java | 85 +++++ .../config/java/support/ImportStack.java | 84 +++++ .../java/support/ImportStackHolder.java | 48 +++ .../MutableAnnotationArrayVisitor.java | 2 +- .../support/MutableAnnotationVisitor.java | 4 +- .../AbstractCircularImportDetectionTests.java | 124 ++++++++ .../AsmCircularImportDetectionTests.java | 43 +++ .../ConfigurationPostProcessorTests.java | 4 +- ...alidConfigurationClassDefinitionTests.java | 54 ++++ .../test/feature/atimport/ImportTests.java | 275 ++++++++++++++++ org.springframework.config.java/template.mf | 3 +- org.springframework.context/.classpath | 3 +- org.springframework.context/ivy.xml | 3 +- ...athScanningCandidateComponentProvider.java | 2 +- org.springframework.core/.classpath | 3 +- org.springframework.core/ivy.xml | 11 +- ...lVariableTableParameterNameDiscoverer.java | 15 +- .../core/annotation/AnnotationUtils.java | 2 +- .../AnnotationMetadataReadingVisitor.java | 24 +- .../CachingMetadataReaderFactory.java | 2 +- .../ClassMetadataReadingVisitor.java | 9 +- .../type/classreading/MetadataReader.java | 2 +- .../MethodMetadataReadingVisitor.java | 293 +++++++++--------- .../classreading/SimpleMetadataReader.java | 7 +- .../SimpleMetadataReaderFactory.java | 7 +- .../core/type/classreading/package-info.java | 20 ++ .../core/type/classreading/package.html | 7 - org.springframework.core/template.mf | 2 +- .../.classpath | 3 +- org.springframework.integration-tests/ivy.xml | 3 +- org.springframework.samples.petclinic/ivy.xml | 3 +- org.springframework.web.portlet/.classpath | 3 +- org.springframework.web.portlet/ivy.xml | 3 +- org.springframework.web.servlet/ivy.xml | 8 +- 50 files changed, 1108 insertions(+), 299 deletions(-) create mode 100644 org.springframework.config.java/src/main/java/org/springframework/config/java/Import.java create mode 100644 org.springframework.config.java/src/main/java/org/springframework/config/java/support/CircularImportException.java create mode 100644 org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportAnnotationVisitor.java create mode 100644 org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportStack.java create mode 100644 org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportStackHolder.java create mode 100644 org.springframework.config.java/src/test/java/org/springframework/config/java/support/AbstractCircularImportDetectionTests.java create mode 100644 org.springframework.config.java/src/test/java/org/springframework/config/java/support/AsmCircularImportDetectionTests.java create mode 100644 org.springframework.config.java/src/test/java/org/springframework/config/java/support/InvalidConfigurationClassDefinitionTests.java create mode 100644 org.springframework.config.java/src/test/java/test/feature/atimport/ImportTests.java create mode 100644 org.springframework.core/src/main/java/org/springframework/core/type/classreading/package-info.java delete mode 100644 org.springframework.core/src/main/java/org/springframework/core/type/classreading/package.html diff --git a/org.springframework.aop/.classpath b/org.springframework.aop/.classpath index 51e4092d72..ec24fbadaf 100644 --- a/org.springframework.aop/.classpath +++ b/org.springframework.aop/.classpath @@ -12,11 +12,10 @@ - - - - + + + diff --git a/org.springframework.aop/ivy.xml b/org.springframework.aop/ivy.xml index 53297d90bf..def2d0b1f5 100644 --- a/org.springframework.aop/ivy.xml +++ b/org.springframework.aop/ivy.xml @@ -35,8 +35,7 @@ - - + diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java index 95fa690ea7..057b36a2c8 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java @@ -26,11 +26,6 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - import org.springframework.beans.BeanMetadataAttribute; import org.springframework.beans.BeanMetadataAttributeAccessor; import org.springframework.beans.PropertyValue; @@ -63,6 +58,10 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.PatternMatchUtils; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * Stateful delegate class used to parse XML bean definitions. @@ -374,7 +373,7 @@ public class BeanDefinitionParserDelegate { String beanName = id; if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { - beanName = (String) aliases.remove(0); + beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); @@ -1054,7 +1053,7 @@ public class BeanDefinitionParserDelegate { typedValue = new TypedStringValue(value); } else if (classLoader != null) { - Class targetType = ClassUtils.forName(targetTypeName, classLoader); + Class targetType = ClassUtils.forName(targetTypeName, classLoader); typedValue = new TypedStringValue(value, targetType); } else { @@ -1067,7 +1066,7 @@ public class BeanDefinitionParserDelegate { /** * Parse a list element. */ - public List parseListElement(Element collectionEle, BeanDefinition bd) { + public List parseListElement(Element collectionEle, BeanDefinition bd) { String defaultTypeClassName = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE); NodeList nl = collectionEle.getChildNodes(); ManagedList list = new ManagedList(nl.getLength()); diff --git a/org.springframework.config.java/.classpath b/org.springframework.config.java/.classpath index cf6f2251f7..793e1828ee 100644 --- a/org.springframework.config.java/.classpath +++ b/org.springframework.config.java/.classpath @@ -1,5 +1,6 @@ + @@ -7,11 +8,10 @@ - - + diff --git a/org.springframework.config.java/.project b/org.springframework.config.java/.project index d73d5ca3e5..4607e560c8 100644 --- a/org.springframework.config.java/.project +++ b/org.springframework.config.java/.project @@ -10,11 +10,21 @@ + + com.cenqua.clover.core.prejavabuilder + + + org.eclipse.jdt.core.javabuilder + + com.cenqua.clover.core.postjavabuilder + + + org.eclipse.wst.validation.validationbuilder @@ -32,5 +42,6 @@ org.eclipse.wst.common.project.facet.core.nature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.jem.workbench.JavaEMFNature + com.cenqua.clover.core.clovernature diff --git a/org.springframework.config.java/ivy.xml b/org.springframework.config.java/ivy.xml index eabf8136d9..89b64e883f 100644 --- a/org.springframework.config.java/ivy.xml +++ b/org.springframework.config.java/ivy.xml @@ -23,8 +23,7 @@ - - + diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/Import.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/Import.java new file mode 100644 index 0000000000..d74153cae6 --- /dev/null +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/Import.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2009 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.config.java; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Annotation that allows one {@link Configuration} class to import another Configuration, + * and thereby all its {@link Bean} definitions. + * + *

Provides functionality equivalent to the {@literal } element in Spring XML. + * + * @author Chris Beams + * @since 3.0 + * @see Configuration + */ +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +public @interface Import { + + /** + * The {@link Configuration} class or classes to import. + */ + Class[] value(); +} diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AddAnnotationAdapter.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AddAnnotationAdapter.java index bea701f5b1..6c333969a1 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AddAnnotationAdapter.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AddAnnotationAdapter.java @@ -17,11 +17,11 @@ package org.springframework.config.java.support; import net.sf.cglib.asm.Constants; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.ClassAdapter; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.MethodVisitor; +import org.springframework.asm.AnnotationVisitor; +import org.springframework.asm.ClassAdapter; +import org.springframework.asm.ClassVisitor; +import org.springframework.asm.FieldVisitor; +import org.springframework.asm.MethodVisitor; /** diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AnnotationAdapter.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AnnotationAdapter.java index 2722ba9806..6fd9f365a7 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AnnotationAdapter.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AnnotationAdapter.java @@ -15,15 +15,15 @@ */ package org.springframework.config.java.support; -import org.objectweb.asm.AnnotationVisitor; +import org.springframework.asm.AnnotationVisitor; /** - * An empty AnnotationVisitor that delegates to another AnnotationVisitor. This class can be - * used as a super class to quickly implement useful annotation adapter classes, just by - * overriding the necessary methods. Note that for some reason, ASM doesn't provide this - * class (it does provide MethodAdapter and ClassAdapter), thus we're following the general - * pattern and adding our own here. + * An empty {@link AnnotationVisitor} that delegates to another AnnotationVisitor. This + * class can be used as a super class to quickly implement useful annotation adapter + * classes, just by overriding the necessary methods. Note that for some reason, ASM + * doesn't provide this class (it does provide MethodAdapter and ClassAdapter), thus + * we're following the general pattern and adding our own here. * * @author Chris Beams */ diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AsmUtils.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AsmUtils.java index e161a5b266..909a5f30df 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AsmUtils.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/AsmUtils.java @@ -20,8 +20,8 @@ import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.commons.EmptyVisitor; +import org.springframework.asm.ClassReader; +import org.springframework.asm.commons.EmptyVisitor; /** diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/CircularImportException.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/CircularImportException.java new file mode 100644 index 0000000000..7a6dae2f16 --- /dev/null +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/CircularImportException.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002-2009 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.config.java.support; + +import static java.lang.String.*; + +import java.util.Stack; + + +/** + * Thrown by {@link ConfigurationParser} upon detecting circular use of the {@link Import} annotation. + * + * @author Chris Beams + * @see Import + * @see ImportStack + * @see ImportStackHolder + */ +@SuppressWarnings("serial") +class CircularImportException extends IllegalStateException { + public CircularImportException(ConfigurationClass attemptedImport, Stack currentImportStack) { + super(format("A circular @Import has been detected: " + + "Illegal attempt by @Configuration class '%s' to import class '%s' as '%s' is " + + "already present in the current import stack [%s]", + currentImportStack.peek().getSimpleName(), attemptedImport.getSimpleName(), + attemptedImport.getSimpleName(), currentImportStack)); + } +} diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClass.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClass.java index 39c99872b0..d6f974da2a 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClass.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClass.java @@ -25,6 +25,7 @@ import java.util.Set; import org.springframework.beans.factory.parsing.Location; import org.springframework.beans.factory.parsing.Problem; import org.springframework.beans.factory.parsing.ProblemReporter; +import org.springframework.config.java.Bean; import org.springframework.config.java.Configuration; import org.springframework.core.io.FileSystemResource; import org.springframework.util.Assert; @@ -34,17 +35,10 @@ import sun.security.x509.Extension; /** * Abstract representation of a user-defined {@link Configuration @Configuration} class. - * Includes a set of Bean methods, AutoBean methods, ExternalBean methods, ExternalValue - * methods, etc. Includes all such methods defined in the ancestry of the class, in a - * 'flattened-out' manner. Note that each BeanMethod representation does still contain - * source information about where it was originally detected (for the purpose of tooling - * with Spring IDE). - * - *

- * Like the rest of the {@link org.springframework.config.java.model model} package, this - * class follows the fluent interface / builder pattern such that a model can be built up - * easily by method chaining. - *

+ * Includes a set of {@link Bean} methods, including all such methods defined in the + * ancestry of the class, in a 'flattened-out' manner. Note that each {@link BeanMethod} + * representation contains source information about where it was originally detected + * (for the purpose of tooling with Spring IDE). * * @author Chris Beams */ @@ -178,11 +172,11 @@ final class ConfigurationClass extends ModelClass { // configuration classes must be annotated with @Configuration if (metadata == null) - problemReporter.error(new NonAnnotatedConfigurationError()); + problemReporter.error(new NonAnnotatedConfigurationProblem()); // a configuration class may not be final (CGLIB limitation) if (Modifier.isFinal(modifiers)) - problemReporter.error(new FinalConfigurationError()); + problemReporter.error(new FinalConfigurationProblem()); for (BeanMethod method : methods) method.validate(problemReporter); @@ -247,11 +241,12 @@ final class ConfigurationClass extends ModelClass { /** Configuration classes must be annotated with {@link Configuration @Configuration}. */ - public class NonAnnotatedConfigurationError extends Problem { - public NonAnnotatedConfigurationError() { - super(format("%s was provided as a Java Configuration class but was not annotated with @%s. " - + "Update the class definition to continue.", - getSimpleName(), Configuration.class.getSimpleName()), + public class NonAnnotatedConfigurationProblem extends Problem { + + public NonAnnotatedConfigurationProblem() { + super(format("%s was specified as a @Configuration class but was not actually annotated " + + "with @Configuration. Annotate the class or do not attempt to process it.", + getSimpleName()), new Location(new FileSystemResource("/dev/null")) ); } @@ -260,13 +255,15 @@ final class ConfigurationClass extends ModelClass { /** Configuration classes must be non-final to accommodate CGLIB subclassing. */ - public class FinalConfigurationError extends Problem { - public FinalConfigurationError() { - super(format("@%s class may not be final. Remove the final modifier to continue.", - Configuration.class.getSimpleName()), + public class FinalConfigurationProblem extends Problem { + + public FinalConfigurationProblem() { + super(format("@Configuration class [%s] may not be final. Remove the final modifier to continue.", + ConfigurationClass.this.getSimpleName()), new Location(new FileSystemResource("/dev/null")) ); } + } } diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClassMethodVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClassMethodVisitor.java index 94616ecb70..f33ec10b3a 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClassMethodVisitor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClassMethodVisitor.java @@ -23,11 +23,11 @@ import static org.springframework.util.ClassUtils.*; import java.lang.annotation.Annotation; import java.util.ArrayList; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.ClassAdapter; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodAdapter; -import org.objectweb.asm.Opcodes; +import org.springframework.asm.AnnotationVisitor; +import org.springframework.asm.ClassAdapter; +import org.springframework.asm.Label; +import org.springframework.asm.MethodAdapter; +import org.springframework.asm.Opcodes; import org.springframework.config.java.Bean; import org.springframework.config.java.Configuration; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClassVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClassVisitor.java index 6830c67cd4..e15a9e863f 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClassVisitor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationClassVisitor.java @@ -22,12 +22,13 @@ import static org.springframework.util.ClassUtils.*; import java.lang.annotation.Annotation; import java.util.HashMap; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.ClassAdapter; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; +import org.springframework.asm.AnnotationVisitor; +import org.springframework.asm.ClassAdapter; +import org.springframework.asm.ClassReader; +import org.springframework.asm.MethodVisitor; +import org.springframework.asm.Opcodes; import org.springframework.config.java.Configuration; +import org.springframework.config.java.Import; /** @@ -112,17 +113,16 @@ class ConfigurationClassVisitor extends ClassAdapter { return new MutableAnnotationVisitor(mutableConfiguration, classLoader); } - // TODO: re-enable for @Import support - // if (Import.class.getName().equals(annoTypeName)) { - // ImportStack importStack = ImportStackHolder.getImportStack(); - // - // if(importStack.contains(configClass)) - // throw new CircularImportException(configClass, importStack); - // - // importStack.push(configClass); - // - // return new ImportAnnotationVisitor(model); - // } + if (Import.class.getName().equals(annoTypeName)) { + ImportStack importStack = ImportStackHolder.getImportStack(); + + if (importStack.contains(configClass)) + throw new CircularImportException(configClass, importStack); + + importStack.push(configClass); + + return new ImportAnnotationVisitor(model, classLoader); + } /* ------------------------------------- // Detect @Extension annotations diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationEnhancer.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationEnhancer.java index 8c5c8a5e7a..97046c80d1 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationEnhancer.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationEnhancer.java @@ -34,9 +34,9 @@ import net.sf.cglib.proxy.MethodProxy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.objectweb.asm.ClassAdapter; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; +import org.springframework.asm.ClassAdapter; +import org.springframework.asm.ClassReader; +import org.springframework.asm.ClassWriter; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.config.java.Configuration; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationParser.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationParser.java index a71cc99515..af5abb6ecf 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationParser.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ConfigurationParser.java @@ -15,7 +15,7 @@ */ package org.springframework.config.java.support; -import org.objectweb.asm.ClassReader; +import org.springframework.asm.ClassReader; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.config.java.Configuration; import org.springframework.util.ClassUtils; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportAnnotationVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportAnnotationVisitor.java new file mode 100644 index 0000000000..54ffa60830 --- /dev/null +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportAnnotationVisitor.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2009 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.config.java.support; + +import static java.lang.String.*; +import static org.springframework.config.java.support.AsmUtils.*; +import static org.springframework.util.ClassUtils.*; + +import java.util.ArrayList; + +import org.springframework.asm.AnnotationVisitor; +import org.springframework.asm.ClassReader; +import org.springframework.asm.Type; +import org.springframework.config.java.Import; +import org.springframework.util.Assert; + + +/** + * ASM {@link AnnotationVisitor} implementation that reads an {@link Import} annotation + * for all its specified classes and then one by one processes each class with a new + * {@link ConfigurationClassVisitor}. + * + * @author Chris Beams + * @see Import + * @see ImportStack + * @see ImportStackHolder + * @see ConfigurationClassVisitor + */ +class ImportAnnotationVisitor extends AnnotationAdapter { + private final ArrayList classesToImport = new ArrayList(); + private final ConfigurationModel model; + private final ClassLoader classLoader; + + public ImportAnnotationVisitor(ConfigurationModel model, ClassLoader classLoader) { + super(AsmUtils.EMPTY_VISITOR); + this.model = model; + this.classLoader = classLoader; + } + + @Override + public AnnotationVisitor visitArray(String attribName) { + Assert.isTrue("value".equals(attribName), + format("expected 'value' attribute, got unknown '%s' attribute", attribName)); + + return new AnnotationAdapter(AsmUtils.EMPTY_VISITOR) { + @Override + public void visit(String na, Object type) { + Assert.isInstanceOf(Type.class, type); + classesToImport.add(((Type) type).getClassName()); + } + }; + } + + @Override + public void visitEnd() { + for (String classToImport : classesToImport) + processClassToImport(classToImport); + + ImportStackHolder.getImportStack().pop(); + } + + private void processClassToImport(String classToImport) { + ConfigurationClass configClass = new ConfigurationClass(); + + ClassReader reader = newClassReader(convertClassNameToResourcePath(classToImport), classLoader); + + reader.accept(new ConfigurationClassVisitor(configClass, model, classLoader), false); + + model.add(configClass); + } + +} diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportStack.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportStack.java new file mode 100644 index 0000000000..60e42cbf87 --- /dev/null +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportStack.java @@ -0,0 +1,84 @@ +/* + * Copyright 2002-2009 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.config.java.support; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Stack; + +import org.springframework.config.java.Import; +import org.springframework.util.Assert; + + +/** + * Stack used for detecting circular use of the {@link Import} annotation. + * + * @author Chris Beams + * @see Import + * @see ImportStackHolder + * @see CircularImportException + */ +@SuppressWarnings("serial") +class ImportStack extends Stack { + + /** + * Simplified contains() implementation that tests to see if any {@link ConfigurationClass} + * exists within this stack that has the same name as elem. Elem must be of + * type ConfigurationClass. + */ + @Override + public boolean contains(Object elem) { + Assert.isInstanceOf(ConfigurationClass.class, elem); + + ConfigurationClass configClass = (ConfigurationClass) elem; + + Comparator comparator = new Comparator() { + public int compare(ConfigurationClass first, ConfigurationClass second) { + return first.getName().equals(second.getName()) ? 0 : 1; + } + }; + + int index = Collections.binarySearch(this, configClass, comparator); + + return index >= 0 ? true : false; + } + + /** + * Given a stack containing (in order) + *
    + *
  1. com.acme.Foo
  2. + *
  3. com.acme.Bar
  4. + *
  5. com.acme.Baz
  6. + *
+ * Returns "Foo->Bar->Baz". In the case of an empty stack, returns empty string. + */ + @Override + public synchronized String toString() { + StringBuilder builder = new StringBuilder(); + + Iterator iterator = this.iterator(); + + while (iterator.hasNext()) { + builder.append(iterator.next().getSimpleName()); + if (iterator.hasNext()) + builder.append("->"); + } + + return builder.toString(); + } + +} diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportStackHolder.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportStackHolder.java new file mode 100644 index 0000000000..06bad1290d --- /dev/null +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/ImportStackHolder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2009 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.config.java.support; + +import org.springframework.config.java.Import; + + +/** + * Holder class to expose a thread-bound {@link ImportStack}, used while detecting circular + * declarations of the {@link Import} annotation. + * + * @author Chris Beams + * @see Import + * @see ImportStack + * @see CircularImportException + */ +class ImportStackHolder { + + private static ThreadLocal stackHolder = new ThreadLocal() { + @Override + protected ImportStack initialValue() { + return new ImportStack(); + } + }; + + public static ImportStack getImportStack() { + return stackHolder.get(); + } + + @Override + public String toString() { + return "Holder for circular @Import detection stack"; + } + +} diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/MutableAnnotationArrayVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/MutableAnnotationArrayVisitor.java index 93d2e3ec69..2c89c7f4ae 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/MutableAnnotationArrayVisitor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/MutableAnnotationArrayVisitor.java @@ -22,7 +22,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.util.ArrayList; -import org.objectweb.asm.AnnotationVisitor; +import org.springframework.asm.AnnotationVisitor; class MutableAnnotationArrayVisitor extends AnnotationAdapter { diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/MutableAnnotationVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/MutableAnnotationVisitor.java index 384e605921..3e4aa1143b 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/support/MutableAnnotationVisitor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/support/MutableAnnotationVisitor.java @@ -21,8 +21,8 @@ import static org.springframework.config.java.support.Util.*; import java.lang.annotation.Annotation; import java.lang.reflect.Field; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.Type; +import org.springframework.asm.AnnotationVisitor; +import org.springframework.asm.Type; import org.springframework.util.Assert; diff --git a/org.springframework.config.java/src/test/java/org/springframework/config/java/support/AbstractCircularImportDetectionTests.java b/org.springframework.config.java/src/test/java/org/springframework/config/java/support/AbstractCircularImportDetectionTests.java new file mode 100644 index 0000000000..b68ba7dd34 --- /dev/null +++ b/org.springframework.config.java/src/test/java/org/springframework/config/java/support/AbstractCircularImportDetectionTests.java @@ -0,0 +1,124 @@ +/* + * Copyright 2002-2009 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.config.java.support; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.springframework.config.java.Bean; +import org.springframework.config.java.Import; + +import test.beans.TestBean; + + +/** + * TCK-style unit tests for handling circular use of the {@link Import} annotation. Explore + * subclass hierarchy for specific concrete implementations. + * + * @author Chris Beams + */ +public abstract class AbstractCircularImportDetectionTests { + protected abstract ConfigurationParser newParser(); + + protected abstract String loadAsConfigurationSource(Class clazz) throws Exception; + + @Test + public void simpleCircularImportIsDetected() throws Exception { + boolean threw = false; + try { + newParser().parse(loadAsConfigurationSource(A.class), null); + } catch (CircularImportException ex) { + assertTrue("Wrong message. Got: " + ex.getMessage(), + ex.getMessage().contains( + "Illegal attempt by @Configuration class 'AbstractCircularImportDetectionTests.B' " + + "to import class 'AbstractCircularImportDetectionTests.A'")); + threw = true; + } + + assertTrue(threw); + } + + + @Test + public void complexCircularImportIsDetected() throws Exception { + boolean threw = false; + try { + newParser().parse(loadAsConfigurationSource(X.class), null); + } catch (CircularImportException ex) { + assertTrue("Wrong message. Got: " + ex.getMessage(), + ex.getMessage().contains( + "Illegal attempt by @Configuration class 'AbstractCircularImportDetectionTests.Z2' " + + "to import class 'AbstractCircularImportDetectionTests.Z'")); + threw = true; + } + + assertTrue(threw); + } + + @Import(B.class) + static class A { + @Bean + TestBean b1() { + return new TestBean(); + } + } + + @Import(A.class) + static class B { + @Bean + TestBean b2() { + return new TestBean(); + } + } + + @Import( { Y.class, Z.class }) + class X { + @Bean + TestBean x() { + return new TestBean(); + } + } + + class Y { + @Bean + TestBean y() { + return new TestBean(); + } + } + + @Import( { Z1.class, Z2.class }) + class Z { + @Bean + TestBean z() { + return new TestBean(); + } + } + + class Z1 { + @Bean + TestBean z1() { + return new TestBean(); + } + } + + @Import(Z.class) + class Z2 { + @Bean + TestBean z2() { + return new TestBean(); + } + } +} diff --git a/org.springframework.config.java/src/test/java/org/springframework/config/java/support/AsmCircularImportDetectionTests.java b/org.springframework.config.java/src/test/java/org/springframework/config/java/support/AsmCircularImportDetectionTests.java new file mode 100644 index 0000000000..5b8e0bb0ba --- /dev/null +++ b/org.springframework.config.java/src/test/java/org/springframework/config/java/support/AsmCircularImportDetectionTests.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002-2009 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.config.java.support; + +import org.springframework.config.java.Import; +import org.springframework.util.ClassUtils; + + +/** + * Unit test proving that ASM-based {@link ConfigurationParser} correctly detects circular use of + * the {@link Import @Import} annotation. + * + *

While this test is the only subclass of {@link AbstractCircularImportDetectionTests}, the + * hierarchy remains in place in case a JDT-based ConfigurationParser implementation needs to be + * developed. + * + * @author Chris Beams + */ +public class AsmCircularImportDetectionTests extends AbstractCircularImportDetectionTests { + @Override + protected ConfigurationParser newParser() { + return new ConfigurationParser(ClassUtils.getDefaultClassLoader()); + } + + @Override + protected String loadAsConfigurationSource(Class clazz) throws Exception { + return clazz.getName(); + } + +} diff --git a/org.springframework.config.java/src/test/java/org/springframework/config/java/support/ConfigurationPostProcessorTests.java b/org.springframework.config.java/src/test/java/org/springframework/config/java/support/ConfigurationPostProcessorTests.java index 860ffff8f3..dd7df11adf 100644 --- a/org.springframework.config.java/src/test/java/org/springframework/config/java/support/ConfigurationPostProcessorTests.java +++ b/org.springframework.config.java/src/test/java/org/springframework/config/java/support/ConfigurationPostProcessorTests.java @@ -50,9 +50,7 @@ public class ConfigurationPostProcessorTests { @Configuration class Config { } DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); - - factory.registerBeanDefinition("config1", rootBeanDefinition(Config.class).getBeanDefinition()); - + factory.registerBeanDefinition("config", rootBeanDefinition(Config.class).getBeanDefinition()); ConfigurationClassPostProcessor cpp = new ConfigurationClassPostProcessor(); // temporarily set the cglib test class to something bogus diff --git a/org.springframework.config.java/src/test/java/org/springframework/config/java/support/InvalidConfigurationClassDefinitionTests.java b/org.springframework.config.java/src/test/java/org/springframework/config/java/support/InvalidConfigurationClassDefinitionTests.java new file mode 100644 index 0000000000..783a3a4908 --- /dev/null +++ b/org.springframework.config.java/src/test/java/org/springframework/config/java/support/InvalidConfigurationClassDefinitionTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002-2009 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.config.java.support; + +import static org.junit.Assert.*; +import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*; + +import org.junit.Test; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.config.java.Configuration; + + +/** + * Unit tests covering cases where a user defines an invalid Configuration + * class, e.g.: forgets to annotate with {@link Configuration} or declares + * a Configuration class as final. + * + * @author Chris Beams + */ +public class InvalidConfigurationClassDefinitionTests { + + @Test + public void configurationClassesMayNotBeFinal() { + @Configuration + final class Config { } + + BeanDefinition configBeanDef = rootBeanDefinition(Config.class).getBeanDefinition(); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerBeanDefinition("config", configBeanDef); + + try { + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + fail("expected exception"); + } catch (BeanDefinitionParsingException ex) { + assertTrue(ex.getMessage(), ex.getMessage().contains("Remove the final modifier")); + } + } + +} diff --git a/org.springframework.config.java/src/test/java/test/feature/atimport/ImportTests.java b/org.springframework.config.java/src/test/java/test/feature/atimport/ImportTests.java new file mode 100644 index 0000000000..0b3243e11f --- /dev/null +++ b/org.springframework.config.java/src/test/java/test/feature/atimport/ImportTests.java @@ -0,0 +1,275 @@ +/* + * Copyright 2002-2008 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 test.feature.atimport; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import org.junit.Test; +import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.config.java.Bean; +import org.springframework.config.java.Configuration; +import org.springframework.config.java.Import; +import org.springframework.config.java.support.ConfigurationClassPostProcessor; + +import test.beans.ITestBean; +import test.beans.TestBean; + + +/** + * System tests for {@link Import} annotation support. + * + * @author Chris Beams + */ +public class ImportTests { + + private DefaultListableBeanFactory processConfigurationClasses(Class... classes) { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + for (Class clazz : classes) + beanFactory.registerBeanDefinition(clazz.getSimpleName(), new RootBeanDefinition(clazz)); + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + return beanFactory; + } + + private void assertBeanDefinitionCount(int expectedCount, Class... classes) { + DefaultListableBeanFactory beanFactory = processConfigurationClasses(classes); + assertThat(beanFactory.getBeanDefinitionCount(), equalTo(expectedCount)); + } + + @Test + public void testProcessImports() { + int configClasses = 2; + int beansInClasses = 2; + + assertBeanDefinitionCount((configClasses + beansInClasses), ConfigurationWithImportAnnotation.class); + } + + @Configuration + @Import(OtherConfiguration.class) + static class ConfigurationWithImportAnnotation { + @Bean + public ITestBean one() { + return new TestBean(); + } + } + + @Configuration + static class OtherConfiguration { + @Bean + public ITestBean two() { + return new TestBean(); + } + } + + // ------------------------------------------------------------------------ + + @Test + public void testImportAnnotationWithTwoLevelRecursion() { + int configClasses = 2; + int beansInClasses = 3; + + assertBeanDefinitionCount((configClasses + beansInClasses), AppConfig.class); + } + + @Configuration + @Import(DataSourceConfig.class) + static class AppConfig { + + @Bean + public ITestBean transferService() { + return new TestBean(accountRepository()); + } + + @Bean + public ITestBean accountRepository() { + return new TestBean(); + } + } + + @Configuration + static class DataSourceConfig { + @Bean + public ITestBean dataSourceA() { + return new TestBean(); + } + } + + // ------------------------------------------------------------------------ + + @Test + public void testImportAnnotationWithThreeLevelRecursion() { + int configClasses = 3; + int beansInClasses = 5; + + assertBeanDefinitionCount((configClasses + beansInClasses), FirstLevel.class); + } + + // ------------------------------------------------------------------------ + + @Test + public void testImportAnnotationWithMultipleArguments() { + int configClasses = 3; + int beansInClasses = 3; + + assertBeanDefinitionCount((configClasses + beansInClasses), + WithMultipleArgumentsToImportAnnotation.class); + } + + + @Test + public void testImportAnnotationWithMultipleArgumentsResultingInOverriddenBeanDefinition() { + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerBeanDefinition("config", new RootBeanDefinition( + WithMultipleArgumentsThatWillCauseDuplication.class)); + new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory); + assertThat(beanFactory.getBeanDefinitionCount(), equalTo(4)); + assertThat(beanFactory.getBean("foo", ITestBean.class).getName(), equalTo("foo2")); + } + + @Configuration + @Import( { Foo1.class, Foo2.class }) + static class WithMultipleArgumentsThatWillCauseDuplication { + } + + @Configuration + static class Foo1 { + @Bean + public ITestBean foo() { + return new TestBean("foo1"); + } + } + + @Configuration + static class Foo2 { + @Bean + public ITestBean foo() { + return new TestBean("foo2"); + } + } + + // ------------------------------------------------------------------------ + + @Test + public void testImportAnnotationOnInnerClasses() { + int configClasses = 2; + int beansInClasses = 2; + + assertBeanDefinitionCount((configClasses + beansInClasses), OuterConfig.InnerConfig.class); + } + + @Configuration + static class OuterConfig { + @Bean + String whatev() { + return "whatev"; + } + + @Configuration + @Import(ExternalConfig.class) + static class InnerConfig { + @Bean + public ITestBean innerBean() { + return new TestBean(); + } + } + } + + @Configuration + static class ExternalConfig { + @Bean + public ITestBean extBean() { + return new TestBean(); + } + } + + // ------------------------------------------------------------------------ + + @Configuration + @Import(SecondLevel.class) + static class FirstLevel { + @Bean + public TestBean m() { + return new TestBean(); + } + } + + @Configuration + @Import(ThirdLevel.class) + static class SecondLevel { + @Bean + public TestBean n() { + return new TestBean(); + } + } + + @Configuration + static class ThirdLevel { + @Bean + public ITestBean thirdLevelA() { + return new TestBean(); + } + + @Bean + public ITestBean thirdLevelB() { + return new TestBean(); + } + + @Bean + public ITestBean thirdLevelC() { + return new TestBean(); + } + } + + @Configuration + @Import( { LeftConfig.class, RightConfig.class }) + static class WithMultipleArgumentsToImportAnnotation { + @Bean + public TestBean m() { + return new TestBean(); + } + } + + @Configuration + static class LeftConfig { + @Bean + public ITestBean left() { + return new TestBean(); + } + } + + @Configuration + static class RightConfig { + @Bean + public ITestBean right() { + return new TestBean(); + } + } + + // ------------------------------------------------------------------------ + + @Test(expected=BeanDefinitionParsingException.class) + public void testImportNonConfigurationAnnotationClassCausesError() { + processConfigurationClasses(ConfigAnnotated.class); + } + + @Configuration + @Import(NonConfigAnnotated.class) + static class ConfigAnnotated { } + + static class NonConfigAnnotated { } +} diff --git a/org.springframework.config.java/template.mf b/org.springframework.config.java/template.mf index 644379e85f..286809c680 100644 --- a/org.springframework.config.java/template.mf +++ b/org.springframework.config.java/template.mf @@ -6,8 +6,7 @@ Import-Template: org.springframework.core.*;version="[2.5.6, 3.0.0]", org.springframework.beans.*;version="[2.5.6, 3.0.0]", org.springframework.context.*;version="[2.5.6, 3.0.0]", - org.objectweb.asm.*;version="[2.2.3, 3.0.0)", - org.objectweb.asm.commons;version="[2.2.3, 3.0.0)", + org.springframework.asm.*;version="[2.5.6, 3.0.0]", org.springframework.aop.*;version="[2.5.6, 3.0.0]";resolution:=optional, org.springframework.stereotype.*;version="[2.5.6, 3.0.0]";resolution:=optional, org.springframework.util.*;version="[2.5.6, 3.0.0]";resolution:=optional, diff --git a/org.springframework.context/.classpath b/org.springframework.context/.classpath index 0ee47d25c8..547fd71819 100644 --- a/org.springframework.context/.classpath +++ b/org.springframework.context/.classpath @@ -13,8 +13,6 @@ - - @@ -34,5 +32,6 @@ + diff --git a/org.springframework.context/ivy.xml b/org.springframework.context/ivy.xml index 63af744c48..cd9e82c3d2 100644 --- a/org.springframework.context/ivy.xml +++ b/org.springframework.context/ivy.xml @@ -59,8 +59,7 @@ - - + diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java index e673a1da77..93927269cd 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java @@ -63,7 +63,7 @@ import org.springframework.util.SystemPropertyUtils; * *

This implementation is based on Spring's * {@link org.springframework.core.type.classreading.MetadataReader MetadataReader} - * facility, backed by an ASM {@link org.objectweb.asm.ClassReader ClassReader}. + * facility, backed by an ASM {@link org.springframework.asm.ClassReader ClassReader}. * * @author Mark Fisher * @author Juergen Hoeller diff --git a/org.springframework.core/.classpath b/org.springframework.core/.classpath index 12fc6a6ace..ced98cf41f 100644 --- a/org.springframework.core/.classpath +++ b/org.springframework.core/.classpath @@ -8,13 +8,12 @@ - - + diff --git a/org.springframework.core/ivy.xml b/org.springframework.core/ivy.xml index f1774c6a35..e92e751c3f 100644 --- a/org.springframework.core/ivy.xml +++ b/org.springframework.core/ivy.xml @@ -30,18 +30,15 @@ conf="optional, log4j->compile"/> - - - - - + - + diff --git a/org.springframework.core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java b/org.springframework.core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java index 11f4aeda6e..782cbee01b 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java +++ b/org.springframework.core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -29,13 +29,12 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.EmptyVisitor; - +import org.springframework.asm.ClassReader; +import org.springframework.asm.Label; +import org.springframework.asm.MethodVisitor; +import org.springframework.asm.Opcodes; +import org.springframework.asm.Type; +import org.springframework.asm.commons.EmptyVisitor; import org.springframework.util.ClassUtils; /** diff --git a/org.springframework.core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/org.springframework.core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index 356d6d9a13..9333f65700 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -137,7 +137,7 @@ public abstract class AnnotationUtils { return annotation; } } - Class superClass = clazz.getSuperclass(); + Class superClass = clazz.getSuperclass(); if (superClass == null || superClass == Object.class) { return null; } diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java index 58ddea4777..9f643ad225 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java @@ -26,14 +26,13 @@ import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.EmptyVisitor; - +import org.springframework.asm.AnnotationVisitor; +import org.springframework.asm.MethodVisitor; +import org.springframework.asm.Type; +import org.springframework.asm.commons.EmptyVisitor; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.ReflectionUtils; import org.springframework.core.type.MethodMetadata; +import org.springframework.util.ReflectionUtils; /** * ASM class visitor which looks for the class name and implemented types as @@ -49,9 +48,9 @@ class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor imple private final Map> attributesMap = new LinkedHashMap>(); private final Map> metaAnnotationMap = new LinkedHashMap>(); - + private final Set methodMetadataSet = new LinkedHashSet(); - + private final ClassLoader classLoader; @@ -59,7 +58,7 @@ class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor imple this.classLoader = classLoader; } - + @Override public MethodVisitor visitMethod(int access, String name, String desc, @@ -75,7 +74,6 @@ class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor imple public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { final String className = Type.getType(desc).getClassName(); final Map attributes = new LinkedHashMap(); - final Map metaAttributes = new LinkedHashMap(); return new EmptyVisitor() { @Override public void visit(String name, Object value) { @@ -95,7 +93,7 @@ class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor imple public void visitEnum(String name, String desc, String value) { Object valueToUse = value; try { - Class enumType = classLoader.loadClass(Type.getType(desc).getClassName()); + Class enumType = classLoader.loadClass(Type.getType(desc).getClassName()); Field enumConstant = ReflectionUtils.findField(enumType, value); if (enumConstant != null) { valueToUse = enumConstant.get(null); @@ -109,7 +107,7 @@ class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor imple @Override public void visitEnd() { try { - Class annotationClass = classLoader.loadClass(className); + Class annotationClass = classLoader.loadClass(className); // Check declared default values of attributes in the annotation type. Method[] annotationAttributes = annotationClass.getMethods(); for (Method annotationAttribute : annotationAttributes) { @@ -123,7 +121,7 @@ class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor imple Annotation[] metaAnnotations = annotationClass.getAnnotations(); Set metaAnnotationTypeNames = new HashSet(); for (Annotation metaAnnotation : metaAnnotations) { - metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName()); + metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName()); } metaAnnotationMap.put(className, metaAnnotationTypeNames); } diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/CachingMetadataReaderFactory.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/CachingMetadataReaderFactory.java index 0d71b43625..7744811ff0 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/CachingMetadataReaderFactory.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/CachingMetadataReaderFactory.java @@ -25,7 +25,7 @@ import org.springframework.core.io.ResourceLoader; /** * Caching implementation of the {@link MetadataReaderFactory} interface, - * caching an ASM {@link org.objectweb.asm.ClassReader} per Spring Resource handle + * caching an ASM {@link org.springframework.asm.ClassReader} per Spring Resource handle * (i.e. per ".class" file). * * @author Juergen Hoeller diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java index 68b3fe3d9a..f10786d4c4 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -16,10 +16,9 @@ package org.springframework.core.type.classreading; -import org.objectweb.asm.ClassAdapter; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.commons.EmptyVisitor; - +import org.springframework.asm.ClassAdapter; +import org.springframework.asm.Opcodes; +import org.springframework.asm.commons.EmptyVisitor; import org.springframework.core.type.ClassMetadata; import org.springframework.util.ClassUtils; diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MetadataReader.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MetadataReader.java index b63bb7e0c7..9c602489a7 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MetadataReader.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MetadataReader.java @@ -21,7 +21,7 @@ import org.springframework.core.type.ClassMetadata; /** * Simple facade for accessing class metadata, - * as read by an ASM {@link org.objectweb.asm.ClassReader}. + * as read by an ASM {@link org.springframework.asm.ClassReader}. * * @author Juergen Hoeller * @since 2.5 diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java index 532b54cf63..050c9dc8b2 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java @@ -1,139 +1,154 @@ -package org.springframework.core.type.classreading; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.MethodAdapter; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.EmptyVisitor; -import org.springframework.core.type.MethodMetadata; - -public class MethodMetadataReadingVisitor extends MethodAdapter implements MethodMetadata { - - private final Map> attributesMap = new LinkedHashMap>(); - - private final Map> metaAnnotationMap = new LinkedHashMap>(); - - private ClassLoader classLoader; - private String name; - private int access; - private boolean isStatic; - - public MethodMetadataReadingVisitor(ClassLoader classLoader, String name, int access) { - super(new EmptyVisitor()); - this.classLoader = classLoader; - this.name = name; - this.access = access; - this.isStatic = ((access & Opcodes.ACC_STATIC) != 0); - } - - public Map getAnnotationAttributes(String annotationType) { - return this.attributesMap.get(annotationType); - } - - public Set getAnnotationTypes() { - return this.attributesMap.keySet(); - } - - public String getMethodName() { - return name; - } - - public int getModifiers() { - return access; - } - - public boolean hasAnnotation(String annotationType) { - return this.attributesMap.containsKey(annotationType); - } - - public Set getMetaAnnotationTypes(String annotationType) { - return this.metaAnnotationMap.get(annotationType); - } - - public boolean hasMetaAnnotation(String metaAnnotationType) { - Collection> allMetaTypes = this.metaAnnotationMap.values(); - for (Set metaTypes : allMetaTypes) { - if (metaTypes.contains(metaAnnotationType)) { - return true; - } - } - return false; - } - - public boolean isStatic() { - return isStatic; - } - - - public Set getAnnotationTypesWithMetaAnnotation(String metaAnnotationType) { - - ///metaAnnotationMap.put(className, metaAnnotationTypeNames); - Set annotationTypes = new LinkedHashSet(); - Set< Map.Entry> > metaValues = metaAnnotationMap.entrySet(); - Iterator> > metaIterator = metaValues.iterator(); - while (metaIterator.hasNext()) - { - Map.Entry> entry = metaIterator.next(); - String attributeType = entry.getKey(); - Set metaAttributes = entry.getValue(); - if (metaAttributes.contains(metaAnnotationType)) - { - annotationTypes.add(attributeType); - } - } - return annotationTypes; - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { - final String className = Type.getType(desc).getClassName(); - final Map attributes = new LinkedHashMap(); - return new EmptyVisitor() { - @Override - public void visit(String name, Object value) { - // Explicitly defined annotation attribute value. - attributes.put(name, value); - } - @Override - public void visitEnd() { - try { - Class annotationClass = classLoader.loadClass(className); - // Check declared default values of attributes in the annotation type. - Method[] annotationAttributes = annotationClass.getMethods(); - for (int i = 0; i < annotationAttributes.length; i++) { - Method annotationAttribute = annotationAttributes[i]; - String attributeName = annotationAttribute.getName(); - Object defaultValue = annotationAttribute.getDefaultValue(); - if (defaultValue != null && !attributes.containsKey(attributeName)) { - attributes.put(attributeName, defaultValue); - } - } - // Register annotations that the annotation type is annotated with. - Annotation[] metaAnnotations = annotationClass.getAnnotations(); - Set metaAnnotationTypeNames = new HashSet(); - for (Annotation metaAnnotation : metaAnnotations) { - metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName()); - } - metaAnnotationMap.put(className, metaAnnotationTypeNames); - } - catch (ClassNotFoundException ex) { - // Class not found - } - attributesMap.put(className, attributes); - } - }; - } - - - -} +/* + * Copyright 2002-2009 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.core.type.classreading; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.springframework.asm.AnnotationVisitor; +import org.springframework.asm.MethodAdapter; +import org.springframework.asm.Opcodes; +import org.springframework.asm.Type; +import org.springframework.asm.commons.EmptyVisitor; +import org.springframework.core.type.MethodMetadata; + +public class MethodMetadataReadingVisitor extends MethodAdapter implements MethodMetadata { + + private final Map> attributesMap = new LinkedHashMap>(); + + private final Map> metaAnnotationMap = new LinkedHashMap>(); + + private ClassLoader classLoader; + private String name; + private int access; + private boolean isStatic; + + public MethodMetadataReadingVisitor(ClassLoader classLoader, String name, int access) { + super(new EmptyVisitor()); + this.classLoader = classLoader; + this.name = name; + this.access = access; + this.isStatic = ((access & Opcodes.ACC_STATIC) != 0); + } + + public Map getAnnotationAttributes(String annotationType) { + return this.attributesMap.get(annotationType); + } + + public Set getAnnotationTypes() { + return this.attributesMap.keySet(); + } + + public String getMethodName() { + return name; + } + + public int getModifiers() { + return access; + } + + public boolean hasAnnotation(String annotationType) { + return this.attributesMap.containsKey(annotationType); + } + + public Set getMetaAnnotationTypes(String annotationType) { + return this.metaAnnotationMap.get(annotationType); + } + + public boolean hasMetaAnnotation(String metaAnnotationType) { + Collection> allMetaTypes = this.metaAnnotationMap.values(); + for (Set metaTypes : allMetaTypes) { + if (metaTypes.contains(metaAnnotationType)) { + return true; + } + } + return false; + } + + public boolean isStatic() { + return isStatic; + } + + + public Set getAnnotationTypesWithMetaAnnotation(String metaAnnotationType) { + + ///metaAnnotationMap.put(className, metaAnnotationTypeNames); + Set annotationTypes = new LinkedHashSet(); + Set< Map.Entry> > metaValues = metaAnnotationMap.entrySet(); + Iterator> > metaIterator = metaValues.iterator(); + while (metaIterator.hasNext()) + { + Map.Entry> entry = metaIterator.next(); + String attributeType = entry.getKey(); + Set metaAttributes = entry.getValue(); + if (metaAttributes.contains(metaAnnotationType)) + { + annotationTypes.add(attributeType); + } + } + return annotationTypes; + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { + final String className = Type.getType(desc).getClassName(); + final Map attributes = new LinkedHashMap(); + return new EmptyVisitor() { + @Override + public void visit(String name, Object value) { + // Explicitly defined annotation attribute value. + attributes.put(name, value); + } + @Override + public void visitEnd() { + try { + Class annotationClass = classLoader.loadClass(className); + // Check declared default values of attributes in the annotation type. + Method[] annotationAttributes = annotationClass.getMethods(); + for (int i = 0; i < annotationAttributes.length; i++) { + Method annotationAttribute = annotationAttributes[i]; + String attributeName = annotationAttribute.getName(); + Object defaultValue = annotationAttribute.getDefaultValue(); + if (defaultValue != null && !attributes.containsKey(attributeName)) { + attributes.put(attributeName, defaultValue); + } + } + // Register annotations that the annotation type is annotated with. + Annotation[] metaAnnotations = annotationClass.getAnnotations(); + Set metaAnnotationTypeNames = new HashSet(); + for (Annotation metaAnnotation : metaAnnotations) { + metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName()); + } + metaAnnotationMap.put(className, metaAnnotationTypeNames); + } + catch (ClassNotFoundException ex) { + // Class not found + } + attributesMap.put(className, attributes); + } + }; + } + + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.java index d4b711fe81..45c080171d 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -16,14 +16,13 @@ package org.springframework.core.type.classreading; -import org.objectweb.asm.ClassReader; - +import org.springframework.asm.ClassReader; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; /** * {@link MetadataReader} implementation based on an ASM - * {@link org.objectweb.asm.ClassReader}. + * {@link org.springframework.asm.ClassReader}. * *

Package-visible in order to allow for repackaging the ASM library * without effect on users of the core.type package. diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java index 90b7b2ce9b..a85a84b28e 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -19,8 +19,7 @@ package org.springframework.core.type.classreading; import java.io.IOException; import java.io.InputStream; -import org.objectweb.asm.ClassReader; - +import org.springframework.asm.ClassReader; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; @@ -28,7 +27,7 @@ import org.springframework.util.ClassUtils; /** * Simple implementation of the {@link MetadataReaderFactory} interface, - * creating a new ASM {@link org.objectweb.asm.ClassReader} for every request. + * creating a new ASM {@link org.springframework.asm.ClassReader} for every request. * * @author Juergen Hoeller * @since 2.5 diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/package-info.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/package-info.java new file mode 100644 index 0000000000..976c3285df --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2002-2009 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. + */ + +/** + * Core support package for type introspection through ASM-based class reading. + */ +package org.springframework.core.type.classreading; \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/package.html b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/package.html deleted file mode 100644 index 4af765c4ff..0000000000 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/package.html +++ /dev/null @@ -1,7 +0,0 @@ - - - -Core support package for type introspection through ASM-based class reading. - - - diff --git a/org.springframework.core/template.mf b/org.springframework.core/template.mf index 94327ee9d1..77939e1157 100644 --- a/org.springframework.core/template.mf +++ b/org.springframework.core/template.mf @@ -8,7 +8,7 @@ Import-Template: edu.emory.mathcs.backport.*;version="[3.0.0, 4.0.0)";resolution:=optional, org.apache.commons.collections.*;version="[3.2.0, 4.0.0)";resolution:=optional, org.apache.commons.logging.*;version="[1.1.1, 2.0.0)", - org.objectweb.asm.*;version="[2.2.3, 3.0.0)";resolution:=optional, + org.springframework.asm.*;version="[2.5.6, 3.0.0]";resolution:=optional, org.apache.log4j.*;version="[1.2.15, 2.0.0)";resolution:=optional, org.aspectj.*;version="[1.5.4, 2.0.0)";resolution:=optional Unversioned-Imports: diff --git a/org.springframework.integration-tests/.classpath b/org.springframework.integration-tests/.classpath index 3a34f22933..2bb12835b0 100644 --- a/org.springframework.integration-tests/.classpath +++ b/org.springframework.integration-tests/.classpath @@ -18,6 +18,7 @@ + @@ -51,8 +52,6 @@ - - diff --git a/org.springframework.integration-tests/ivy.xml b/org.springframework.integration-tests/ivy.xml index 1b60eb6545..c2ec14be4c 100644 --- a/org.springframework.integration-tests/ivy.xml +++ b/org.springframework.integration-tests/ivy.xml @@ -76,8 +76,7 @@ - - + diff --git a/org.springframework.samples.petclinic/ivy.xml b/org.springframework.samples.petclinic/ivy.xml index 17f3245541..818d358182 100644 --- a/org.springframework.samples.petclinic/ivy.xml +++ b/org.springframework.samples.petclinic/ivy.xml @@ -29,8 +29,7 @@ - - + diff --git a/org.springframework.web.portlet/.classpath b/org.springframework.web.portlet/.classpath index f272084009..763cf00925 100644 --- a/org.springframework.web.portlet/.classpath +++ b/org.springframework.web.portlet/.classpath @@ -10,13 +10,12 @@ + - - diff --git a/org.springframework.web.portlet/ivy.xml b/org.springframework.web.portlet/ivy.xml index 6bd790f129..0480526658 100644 --- a/org.springframework.web.portlet/ivy.xml +++ b/org.springframework.web.portlet/ivy.xml @@ -32,8 +32,7 @@ - - + diff --git a/org.springframework.web.servlet/ivy.xml b/org.springframework.web.servlet/ivy.xml index 37cd41810c..ad6389a496 100644 --- a/org.springframework.web.servlet/ivy.xml +++ b/org.springframework.web.servlet/ivy.xml @@ -76,14 +76,12 @@ - - + - - + +