From b93e67deba86808ae62a3206ac504531d266ff09 Mon Sep 17 00:00:00 2001 From: Jon Schneider Date: Fri, 5 Jun 2020 13:04:22 -0500 Subject: [PATCH] Remove XML migration work for now --- .../spring/xml/AddConfigurationClass.java | 61 --- .../xml/GenerateConfigurationClasses.java | 5 - .../spring/xml/MakeComponentScannable.java | 252 ------------ .../MigrateSpringXmlConfigurationJava.java | 97 ----- .../spring/xml/SpringMetadata.java | 22 - .../bean/AddBeanForClassNotInSourceSet.java | 50 --- .../spring/xml/bean/AddBeanMethod.java | 218 ---------- .../spring/xml/bean/AddBeanMethodBody.java | 46 --- .../spring/xml/bean/AddComponentScan.java | 91 ----- ...dPropertySourcesPlaceholderConfigurer.java | 135 ------ .../xml/bean/BeanDefinitionVisitor.java | 30 -- .../xml/parse/RewriteBeanDefinition.java | 384 ------------------ .../parse/RewriteBeanDefinitionRegistry.java | 39 -- .../xml/parse/RewriteNamespaceHandler.java | 59 --- .../spring/xml/AddConfigurationClassTest.kt | 146 ------- .../spring/xml/MakeComponentScannableTest.kt | 243 ----------- ...pertySourcesPlaceholderConfigurerTest.java | 31 -- .../org/openrewrite/spring/xml/beans.kt | 48 --- 18 files changed, 1957 deletions(-) delete mode 100644 src/main/java/org/openrewrite/spring/xml/AddConfigurationClass.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/GenerateConfigurationClasses.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/MakeComponentScannable.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/MigrateSpringXmlConfigurationJava.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/SpringMetadata.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/bean/AddBeanForClassNotInSourceSet.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/bean/AddBeanMethod.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/bean/AddBeanMethodBody.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/bean/AddComponentScan.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/bean/AddPropertySourcesPlaceholderConfigurer.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/bean/BeanDefinitionVisitor.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/parse/RewriteBeanDefinition.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/parse/RewriteBeanDefinitionRegistry.java delete mode 100644 src/main/java/org/openrewrite/spring/xml/parse/RewriteNamespaceHandler.java delete mode 100644 src/test/kotlin/org/openrewrite/spring/xml/AddConfigurationClassTest.kt delete mode 100644 src/test/kotlin/org/openrewrite/spring/xml/MakeComponentScannableTest.kt delete mode 100644 src/test/kotlin/org/openrewrite/spring/xml/bean/AddPropertySourcesPlaceholderConfigurerTest.java delete mode 100644 src/test/kotlin/org/openrewrite/spring/xml/beans.kt diff --git a/src/main/java/org/openrewrite/spring/xml/AddConfigurationClass.java b/src/main/java/org/openrewrite/spring/xml/AddConfigurationClass.java deleted file mode 100644 index add8a9321..000000000 --- a/src/main/java/org/openrewrite/spring/xml/AddConfigurationClass.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml; - -import org.openrewrite.spring.xml.bean.AddBeanForClassNotInSourceSet; -import org.openrewrite.spring.xml.bean.AddComponentScan; -import org.openrewrite.spring.xml.bean.AddPropertySourcesPlaceholderConfigurer; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinitionRegistry; -import org.openrewrite.java.AddAnnotation; -import org.openrewrite.java.JavaRefactorVisitor; -import org.openrewrite.java.tree.J; - -import java.nio.file.Path; - -public class AddConfigurationClass extends JavaRefactorVisitor { - private final RewriteBeanDefinitionRegistry beanDefinitionRegistry; - private final Path mainSourceSet; - - public AddConfigurationClass(RewriteBeanDefinitionRegistry beanDefinitionRegistry, Path mainSourceSet) { - this.beanDefinitionRegistry = beanDefinitionRegistry; - this.mainSourceSet = mainSourceSet; - } - - @Override - public boolean isIdempotent() { - return false; - } - - @Override - public J visitCompilationUnit(J.CompilationUnit cu) { - if (cu.getMetadata() - .getOrDefault(SpringMetadata.FILE_TYPE, "unknown") - .equals("ConfigurationClass")) { - return super.visitCompilationUnit(cu); - } - return cu; - } - - @Override - public J visitClassDecl(J.ClassDecl classDecl) { - andThen(new AddAnnotation.Scoped(classDecl, "org.springframework.context.annotation.Configuration")); - andThen(new AddComponentScan(classDecl, beanDefinitionRegistry)); - andThen(new AddBeanForClassNotInSourceSet(classDecl, beanDefinitionRegistry, mainSourceSet)); - andThen(new AddPropertySourcesPlaceholderConfigurer(classDecl, beanDefinitionRegistry)); - - return super.visitClassDecl(classDecl); - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/GenerateConfigurationClasses.java b/src/main/java/org/openrewrite/spring/xml/GenerateConfigurationClasses.java deleted file mode 100644 index edd1c9917..000000000 --- a/src/main/java/org/openrewrite/spring/xml/GenerateConfigurationClasses.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.openrewrite.spring.xml; - -public class GenerateConfigurationClasses implements Generate { - -} diff --git a/src/main/java/org/openrewrite/spring/xml/MakeComponentScannable.java b/src/main/java/org/openrewrite/spring/xml/MakeComponentScannable.java deleted file mode 100644 index 386994b99..000000000 --- a/src/main/java/org/openrewrite/spring/xml/MakeComponentScannable.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml; - -import org.openrewrite.java.AddAnnotation; -import org.openrewrite.java.JavaRefactorVisitor; -import org.openrewrite.java.tree.*; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanReference; -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.TypedStringValue; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Stream; - -import static java.util.stream.Collectors.toList; -import static java.util.stream.StreamSupport.stream; -import static org.openrewrite.Formatting.EMPTY; -import static org.openrewrite.Tree.randomId; - -/** - * Any changes necessary to make a component defined in XML configuration configurable via - * component scanning instead. - */ -class MakeComponentScannable extends JavaRefactorVisitor { - private final BeanDefinitionRegistry registry; - - public MakeComponentScannable(BeanDefinitionRegistry registry) { - this.registry = registry; - } - - @Override - public J visitCompilationUnit(J.CompilationUnit cu) { - andThen(new AnnotateBeanClass(registry)); - return super.visitCompilationUnit(cu); - } - - private static class AnnotateBeanClass extends JavaRefactorVisitor { - private final BeanDefinitionRegistry beanDefinitionRegistry; - - private AnnotateBeanClass(BeanDefinitionRegistry beanDefinitionRegistry) { - this.beanDefinitionRegistry = beanDefinitionRegistry; - setCursoringOn(); - } - - @Override - public J visitClassDecl(J.ClassDecl classDecl) { - Arrays.stream(beanDefinitionRegistry.getBeanDefinitionNames()) - .map(beanDefinitionRegistry::getBeanDefinition) - .filter(bd -> TypeUtils.isOfClassType(classDecl.getType(), bd.getBeanClassName())) - .findAny() - .ifPresent(beanDefinition -> { - andThen(new AddAnnotation.Scoped(classDecl, "org.springframework.stereotype.Component")); - andThen(new AutowireFields(classDecl, beanDefinition)); - - if (beanDefinition.isLazyInit()) { - andThen(new AddAnnotation.Scoped(classDecl, "org.springframework.context.annotation.Lazy")); - } - - if (beanDefinition.isPrototype()) { - JavaType.Class cbf = JavaType.Class.build("org.springframework.beans.factory.config.ConfigurableBeanFactory"); - maybeAddImport(cbf.getFullyQualifiedName()); - andThen(new AddAnnotation.Scoped(classDecl, "org.springframework.context.annotation.Scope", - TreeBuilder.buildName("ConfigurableBeanFactory.SCOPE_PROTOTYPE").withType(cbf))); - } - - if (beanDefinition.getInitMethodName() != null) { - classDecl.getMethods().stream() - .filter(m -> m.getSimpleName().equals(beanDefinition.getInitMethodName())) - .findAny() - .ifPresent(m -> andThen(new AddAnnotation.Scoped(m, "javax.annotation.PostConstruct"))); - } - - if (beanDefinition.getDestroyMethodName() != null) { - classDecl.getMethods().stream() - .filter(m -> m.getSimpleName().equals(beanDefinition.getDestroyMethodName())) - .findAny() - .ifPresent(m -> andThen(new AddAnnotation.Scoped(m, "javax.annotation.PreDestroy"))); - } - }); - - return super.visitClassDecl(classDecl); - } - } - - private static class AutowireFields extends JavaRefactorVisitor { - private final J.ClassDecl scope; - private final BeanDefinition beanDefinition; - - public AutowireFields(J.ClassDecl classDecl, BeanDefinition beanDefinition) { - this.scope = classDecl; - this.beanDefinition = beanDefinition; - setCursoringOn(); - } - - @Override - public J visitMultiVariable(J.VariableDecls multiVariable) { - getCursor().getParentOrThrow().getParentOrThrow().getTree().whenType(J.ClassDecl.class).ifPresent(classDecl -> { - stream(beanDefinition.getPropertyValues().spliterator(), false) - .filter(prop -> prop.getName().equals(multiVariable.getVars().get(0).getSimpleName())) - .findAny() - .ifPresent(beanProperty -> { - if (beanProperty.getValue() instanceof BeanReference) { - andThen(new AddAnnotation.Scoped(multiVariable, "org.springframework.beans.factory.annotation.Autowired")); - } else if (beanProperty.getValue() instanceof TypedStringValue) { - valueExpression(beanProperty.getValue(), multiVariable).ifPresent(valueTree -> - andThen(new AddAnnotation.Scoped(multiVariable, - "org.springframework.beans.factory.annotation.Value", valueTree))); - } - }); - - ConstructorArgumentValues constructorArgs = beanDefinition.getConstructorArgumentValues(); - if (constructorArgs.getArgumentCount() > 0) { - classDecl.getMethods().stream() - .filter(m -> m.isConstructor() && m.getParams().getParams().size() == constructorArgs.getArgumentCount()) - .findAny() - .ifPresent(injectableConstructor -> { - List indexedValues = Stream.concat( - constructorArgs.getIndexedArgumentValues().entrySet().stream() - .sorted(Map.Entry.comparingByKey()) - .map(Map.Entry::getValue), - constructorArgs.getGenericArgumentValues().stream() - .filter(valueHolder -> valueHolder.getType() == null && valueHolder.getName() == null) - ).collect(toList()); - - for (int i = 0; i < indexedValues.size(); i++) { - int param = i; - valueExpression(indexedValues.get(i).getValue(), multiVariable).ifPresent(valueTree -> - andThen(new AddAnnotation.Scoped(injectableConstructor.getParams().getParams().get(param), - "org.springframework.beans.factory.annotation.Value", valueTree))); - } - - List genericValues = constructorArgs.getGenericArgumentValues().stream() - .filter(valueHolder -> valueHolder.getType() != null || valueHolder.getName() != null) - .collect(toList()); - - for (ConstructorArgumentValues.ValueHolder genericValue : genericValues) { - valueExpression(genericValue.getValue(), multiVariable).ifPresent(valueTree -> { - Statement param; - if(genericValue.getType() != null) { - param = injectableConstructor.getParams().getParams().stream() - .filter(methodParam -> { - JavaType genericValueType = Optional.ofNullable((JavaType) JavaType.Primitive.fromKeyword(genericValue.getType())) - .orElseGet(() -> JavaType.Class.build(genericValue.getType())); - - //noinspection ConstantConditions - return methodParam.whenType(J.VariableDecls.class) - .map(methodParamVar -> methodParamVar.getTypeExpr().getType().equals(genericValueType)) - .orElse(false); - }) - .findAny() - .orElse(null); - } else { - param = injectableConstructor.getParams().getParams().stream() - .filter(methodParam -> methodParam.whenType(J.VariableDecls.class) - .map(methodParamVar -> methodParamVar.getVars().get(0).getSimpleName().equals(genericValue.getName())) - .orElse(false)) - .findAny() - .orElse(null); - } - - if(param != null) { - andThen(new AddAnnotation.Scoped(param, - "org.springframework.beans.factory.annotation.Value", valueTree)); - } - }); - } - }); - } - }); - - return super.visitMultiVariable(multiVariable); - } - - private Optional valueExpression(Object typedStringValue, J.VariableDecls multiVariable) { - if (!(typedStringValue instanceof TypedStringValue) || multiVariable.getTypeExpr() == null) { - return Optional.empty(); - } - - String value = ((TypedStringValue) typedStringValue).getValue(); - if (value == null) { - return Optional.empty(); - } - - JavaType type = multiVariable.getTypeExpr().getType(); - JavaType.Primitive primitive = TypeUtils.asPrimitive(type); - - if (TypeUtils.isString(type) || value.contains("${") || value.contains("#{")) { - return Optional.of(new J.Literal(randomId(), value, "\"" + value + "\"", JavaType.Primitive.String, EMPTY)); - } else if (primitive != null) { - Object primitiveValue; - - switch (primitive) { - case Int: - primitiveValue = Integer.parseInt(value); - break; - case Boolean: - primitiveValue = Boolean.parseBoolean(value); - break; - case Byte: - case Char: - primitiveValue = value.length() > 0 ? value.charAt(0) : 0; - break; - case Double: - primitiveValue = Double.parseDouble(value); - break; - case Float: - primitiveValue = Float.parseFloat(value); - break; - case Long: - primitiveValue = Long.parseLong(value); - break; - case Short: - primitiveValue = Short.parseShort(value); - break; - case Null: - primitiveValue = null; - break; - case Void: - case String: - case None: - case Wildcard: - default: - return Optional.empty(); // not reachable - } - - return Optional.of(new J.Literal(randomId(), primitiveValue, - JavaType.Primitive.Char.equals(primitive) ? "'" + value + "'" : value, - primitive, EMPTY)); - } - - return Optional.empty(); - } - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/MigrateSpringXmlConfigurationJava.java b/src/main/java/org/openrewrite/spring/xml/MigrateSpringXmlConfigurationJava.java deleted file mode 100644 index 45a55eeb6..000000000 --- a/src/main/java/org/openrewrite/spring/xml/MigrateSpringXmlConfigurationJava.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml; - -import org.openrewrite.Refactor; -import org.openrewrite.RefactorModule; -import org.openrewrite.java.tree.J; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinition; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinitionRegistry; -import org.openrewrite.spring.xml.parse.RewriteNamespaceHandler; -import org.springframework.beans.factory.BeanDefinitionStoreException; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.xml.sax.InputSource; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.List; -import java.util.Map; - -import static java.util.Collections.singletonList; - -public class MigrateSpringXmlConfigurationJava implements RefactorModule { - private final Path mainSourceSet; - private final String configurationPackage; - private final RewriteBeanDefinitionRegistry beanDefinitionRegistry = new RewriteBeanDefinitionRegistry(); - - public MigrateSpringXmlConfigurationJava(Path mainSourceSet, String configurationPackage, List xmlConfigurations) { - this.mainSourceSet = mainSourceSet; - this.configurationPackage = configurationPackage; - loadBeanDefinitions(xmlConfigurations, beanDefinitionRegistry); - } - - static void loadBeanDefinitions(List xmlConfigurations, BeanDefinitionRegistry beanDefinitionRegistry) { - XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanDefinitionRegistry); - reader.setValidating(false); - - DefaultNamespaceHandlerResolver namespaceHandlerResolver = (DefaultNamespaceHandlerResolver) reader.getNamespaceHandlerResolver(); - try { - Method getHandlerMappings = DefaultNamespaceHandlerResolver.class.getDeclaredMethod("getHandlerMappings"); - getHandlerMappings.setAccessible(true); - @SuppressWarnings("unchecked") Map handlerMappings = (Map) getHandlerMappings - .invoke(namespaceHandlerResolver); - - // Override default handler mappings to preserve the attributes in the original XML so we - // can build annotations that, when interpreted by Spring, will do something similar as the original - // handler mappings. - handlerMappings.put("http://www.springframework.org/schema/context", new RewriteNamespaceHandler(Map.of( - "property-placeholder", RewriteBeanDefinition.Type.PropertyPlaceholder, - "component-scan", RewriteBeanDefinition.Type.ComponentScan))); - - System.out.println(handlerMappings); - } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - throw new RuntimeException(e); - } - - for (Path xmlConfiguration : xmlConfigurations) { - try (InputStream configInput = Files.newInputStream(xmlConfiguration, StandardOpenOption.READ)) { - reader.loadBeanDefinitions(new InputSource(configInput)); - } catch (IOException | BeanDefinitionStoreException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public Refactor apply(Refactor refactor) { - return refactor.visit(new MakeComponentScannable(beanDefinitionRegistry)) - .visit(new AddConfigurationClass(beanDefinitionRegistry, mainSourceSet)); - } - - @Override - public List getDeclaredOutputs() { - return singletonList(J.CompilationUnit - .buildEmptyClass(mainSourceSet, configurationPackage, "MyConfiguration") - .withMetadata(Map.of(SpringMetadata.FILE_TYPE, "ConfigurationClass"))); - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/SpringMetadata.java b/src/main/java/org/openrewrite/spring/xml/SpringMetadata.java deleted file mode 100644 index 16267484e..000000000 --- a/src/main/java/org/openrewrite/spring/xml/SpringMetadata.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml; - -import org.openrewrite.Metadata; - -public enum SpringMetadata implements Metadata { - FILE_TYPE -} diff --git a/src/main/java/org/openrewrite/spring/xml/bean/AddBeanForClassNotInSourceSet.java b/src/main/java/org/openrewrite/spring/xml/bean/AddBeanForClassNotInSourceSet.java deleted file mode 100644 index b2a54a499..000000000 --- a/src/main/java/org/openrewrite/spring/xml/bean/AddBeanForClassNotInSourceSet.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.bean; - -import org.openrewrite.java.tree.J; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinition; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinitionRegistry; - -import java.nio.file.Path; -import java.util.Map; - -public class AddBeanForClassNotInSourceSet extends BeanDefinitionVisitor { - private final Path mainSourceSet; - - public AddBeanForClassNotInSourceSet(J.ClassDecl profileConfigurationClass, RewriteBeanDefinitionRegistry registry, Path mainSourceSet) { - super(profileConfigurationClass, registry); - this.mainSourceSet = mainSourceSet; - } - - @Override - public J visitClassDecl(J.ClassDecl classDecl) { - if (isScope()) { - for (Map.Entry beanDefinitionByName : registry.getBeanDefinitions(null).entrySet()) { - RewriteBeanDefinition bean = beanDefinitionByName.getValue(); - if (!mainSourceSet.resolve(bean.getBeanClassName().replace(".", "/")) - .toFile().exists()) { - AddBeanMethod beanMethod = new AddBeanMethod(classDecl, beanDefinitionByName.getKey(), bean, registry); - andThen(beanMethod); - - andThen(new AddBeanMethodBody(beanMethod.getMethodId(), bean.getBeanDefinitionBody())); - } - } - } - - return super.visitClassDecl(classDecl); - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/bean/AddBeanMethod.java b/src/main/java/org/openrewrite/spring/xml/bean/AddBeanMethod.java deleted file mode 100644 index 8db100a06..000000000 --- a/src/main/java/org/openrewrite/spring/xml/bean/AddBeanMethod.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.bean; - -import org.openrewrite.Formatting; -import org.openrewrite.java.AddAnnotation; -import org.openrewrite.java.JavaRefactorVisitor; -import org.openrewrite.java.tree.*; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinition; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinitionRegistry; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static org.openrewrite.Formatting.*; -import static org.openrewrite.Tree.randomId; - -class AddBeanMethod extends JavaRefactorVisitor { - private static final JavaType.Class BEAN_TYPE = JavaType.Class.build("org.springframework.context.annotation.Bean"); - - private final J.ClassDecl scope; - private final String name; - private final JavaType.Class returnType; - private final boolean statik; - private final boolean lazy; - private final boolean prototype; - private final List arguments; - - @Nullable - private final String initMethod; - - @Nullable - private final String destroyMethod; - - public AddBeanMethod(J.ClassDecl scope, - String beanName, - RewriteBeanDefinition bean, - RewriteBeanDefinitionRegistry registry) { - this(scope, beanName, bean.getType(), false, - Formatting.formatFirstPrefix(bean.getPropertyValues().stream() - .map(pv -> { - RewriteBeanDefinition propertyBean = registry.getBeanDefinition(pv.getName()); - JavaType.Class propertyBeanType = JavaType.Class.build(propertyBean.getBeanClassName()); - - return new J.VariableDecls( - randomId(), - emptyList(), - emptyList(), - J.Ident.build( - randomId(), - propertyBeanType.getClassName(), - propertyBeanType, - Formatting.EMPTY - ), - null, - emptyList(), - singletonList(new J.VariableDecls.NamedVar( - randomId(), - J.Ident.build( - randomId(), - pv.getName(), - propertyBeanType, - format(" ")), - emptyList(), - null, - propertyBeanType, - EMPTY) - ), - format(" ")); - }) - .collect(Collectors.toList()), ""), - bean.isLazyInit(), - bean.isPrototype(), - bean.getInitMethodName(), - bean.getDestroyMethodName()); - } - - public AddBeanMethod(J.ClassDecl scope, - String name, - JavaType.Class returnType, - boolean statik, - List arguments) { - this(scope, name, returnType, statik, arguments, false, false, null, null); - } - - public AddBeanMethod(J.ClassDecl scope, - String name, - JavaType.Class returnType, - boolean statik, - List arguments, - boolean lazy, - boolean prototype, - @Nullable String initMethod, - @Nullable String destroyMethod) { - this.scope = scope; - this.name = name; - this.returnType = returnType; - this.statik = statik; - this.lazy = lazy; - this.prototype = prototype; - this.arguments = arguments; - this.initMethod = initMethod; - this.destroyMethod = destroyMethod; - } - - @Override - public boolean isIdempotent() { - return false; - } - - @Override - public J visitClassDecl(J.ClassDecl classDecl) { - J.ClassDecl c = refactor(classDecl, super::visitClassDecl); - - if (scope.isScope(classDecl)) { - List statements = new ArrayList<>(c.getBody().getStatements()); - - int insertionIndex = statements.size(); - for (int i = 0; i < statements.size(); i++) { - J statement = statements.get(i); - if (statement.whenType(J.MethodDecl.class) - .map(m -> !m.isConstructor() && m.hasModifier("public") && m.getSimpleName().compareTo(name) > 0) - .orElse(false)) { - insertionIndex = i; - break; - } - } - - maybeAddImport(BEAN_TYPE.getFullyQualifiedName()); - maybeAddImport(returnType); - - Formatting format = formatter.format(classDecl.getBody()); - - J.MethodDecl beanMethod = new J.MethodDecl(randomId(), - singletonList(buildBeanAnnotation()), - emptyList(), - null, - TreeBuilder.buildName(returnType.getClassName(), EMPTY).withType(returnType), - TreeBuilder.buildName(name, format(" ")), - new J.MethodDecl.Parameters(randomId(), arguments, EMPTY), - null, - new J.Block<>(randomId(), null, - emptyList(), format(" "), format.getPrefix()), - null, - EMPTY).withModifiers("public"); - - if (lazy) { - andThen(new AddAnnotation.Scoped(beanMethod, "org.springframework.context.annotation.Lazy")); - } - - if (prototype) { - JavaType.Class cbf = JavaType.Class.build("org.springframework.beans.factory.config.ConfigurableBeanFactory"); - maybeAddImport(cbf.getFullyQualifiedName()); - andThen(new AddAnnotation.Scoped(beanMethod, "org.springframework.context.annotation.Scope", - TreeBuilder.buildName("ConfigurableBeanFactory.SCOPE_PROTOTYPE").withType(cbf))); - } - - if (statik) { - beanMethod = beanMethod.withModifiers("static"); - } - - beanMethod = beanMethod.withFormatting(format.withPrefix("\n" + format.getPrefix())); - beanMethod = beanMethod.withModifiers(formatFirstPrefix(beanMethod.getModifiers(), format.getPrefix())); - - statements.add(insertionIndex, beanMethod); - - c = c.withBody(c.getBody().withStatements(statements)); - } - - return c; - } - - private J.Annotation buildBeanAnnotation() { - List arguments = new ArrayList<>(); - - if(initMethod != null) { - arguments.add(new J.Assign( - randomId(), - J.Ident.build(randomId(), "initMethod", JavaType.Primitive.String, EMPTY), - new J.Literal(randomId(), initMethod, "\"" + initMethod + "\"", JavaType.Primitive.String, EMPTY), - JavaType.Primitive.String, - EMPTY - )); - } - - if(destroyMethod != null) { - arguments.add(new J.Assign( - randomId(), - J.Ident.build(randomId(), "destroyMethod", JavaType.Primitive.String, EMPTY), - new J.Literal(randomId(), destroyMethod, "\"" + destroyMethod + "\"", JavaType.Primitive.String, EMPTY), - JavaType.Primitive.String, - initMethod != null ? format(" ") : EMPTY - )); - } - - return new J.Annotation(randomId(), - J.Ident.build(randomId(), BEAN_TYPE.getClassName(), BEAN_TYPE, EMPTY), - arguments.isEmpty() ? null : new J.Annotation.Arguments(randomId(), arguments, EMPTY), - EMPTY); - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/bean/AddBeanMethodBody.java b/src/main/java/org/openrewrite/spring/xml/bean/AddBeanMethodBody.java deleted file mode 100644 index 2a96c7be3..000000000 --- a/src/main/java/org/openrewrite/spring/xml/bean/AddBeanMethodBody.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.bean; - -import org.openrewrite.java.JavaRefactorVisitor; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.JavaType; -import org.openrewrite.java.tree.TreeBuilder; - -class AddBeanMethodBody extends JavaRefactorVisitor { - private final J.MethodDecl scope; - private final String snippet; - private final JavaType.Class[] imports; - - public AddBeanMethodBody(J.MethodDecl methodDecl, String snippet, JavaType.Class... imports) { - this.scope = methodDecl; - this.snippet = snippet; - this.imports = imports; - setCursoringOn(); - } - - @Override - public J visitMethod(J.MethodDecl method) { - J.MethodDecl m = refactor(method, super::visitMethod); - - if (scope.isScope(method) && m.getBody() != null) { - m = m.withBody(m.getBody().withStatements(TreeBuilder.buildSnippet(enclosingCompilationUnit(), - getCursor(), snippet, imports))); - } - - return m; - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/bean/AddComponentScan.java b/src/main/java/org/openrewrite/spring/xml/bean/AddComponentScan.java deleted file mode 100644 index 46de8900a..000000000 --- a/src/main/java/org/openrewrite/spring/xml/bean/AddComponentScan.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.bean; - -import org.openrewrite.refactor.Formatter; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinition; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinitionRegistry; -import org.openrewrite.java.AddAnnotation; -import org.openrewrite.java.tree.Expression; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.JavaType; - -import java.util.List; -import java.util.Objects; - -import static java.util.Collections.emptyList; -import static java.util.stream.Collectors.toList; -import static org.openrewrite.Formatting.*; -import static org.openrewrite.Tree.randomId; - -public class AddComponentScan extends BeanDefinitionVisitor { - - public AddComponentScan(J.ClassDecl profileConfigurationClass, RewriteBeanDefinitionRegistry registry) { - super(profileConfigurationClass, registry); - } - - @Override - public J visitClassDecl(J.ClassDecl classDecl) { - if(configurationClass.isScope(classDecl)) { - List basePackagesToComponentScan = registry.getBeanDefinitions(RewriteBeanDefinition.Type.ComponentScan).values().stream() - .map(bd -> bd.getProperty("basePackage").orElse(null)) - .filter(Objects::nonNull) - .sorted((p1, p2) -> { - var p1s = p1.split("\\."); - var p2s = p2.split("\\."); - - for (int i = 0; i < p1s.length; i++) { - String s = p1s[i]; - if (p2s.length < i + 1) { - return 1; - } - if (!s.equals(p2s[i])) { - return s.compareTo(p2s[i]); - } - } - - return p1s.length < p2s.length ? -1 : 0; - }) - .collect(toList()); - - if (!basePackagesToComponentScan.isEmpty()) { - Expression arguments; - if (basePackagesToComponentScan.size() == 1) { - String bp = basePackagesToComponentScan.get(0); - arguments = new J.Literal(randomId(), bp, "\"" + bp + "\"", - JavaType.Primitive.String, EMPTY); - } else { - Formatter.Result classDeclIndent = formatter.findIndent(0, classDecl); - String prefix = classDeclIndent.getPrefix(); - - List argExpressions = basePackagesToComponentScan.stream() - .map(bp -> (Expression) new J.Literal(randomId(), bp, "\"" + bp + "\"", - JavaType.Primitive.String, format(prefix))) - .collect(toList()); - argExpressions = formatLastSuffix(argExpressions, classDeclIndent.getPrefix(-1)); - - arguments = new J.NewArray(randomId(), null, emptyList(), - new J.NewArray.Initializer(randomId(), argExpressions, EMPTY), - JavaType.Class.build("java.lang.String"), EMPTY); - } - - andThen(new AddAnnotation.Scoped(classDecl, "org.springframework.context.annotation.ComponentScan", arguments)); - } - } - - return super.visitClassDecl(classDecl); - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/bean/AddPropertySourcesPlaceholderConfigurer.java b/src/main/java/org/openrewrite/spring/xml/bean/AddPropertySourcesPlaceholderConfigurer.java deleted file mode 100644 index 735003b3f..000000000 --- a/src/main/java/org/openrewrite/spring/xml/bean/AddPropertySourcesPlaceholderConfigurer.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.bean; - -import org.openrewrite.spring.xml.parse.RewriteBeanDefinition; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinitionRegistry; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.JavaType; -import org.openrewrite.java.tree.Statement; -import org.openrewrite.java.tree.TreeBuilder; - -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static java.util.Arrays.stream; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; -import static org.openrewrite.Formatting.*; -import static org.openrewrite.Tree.randomId; - -public class AddPropertySourcesPlaceholderConfigurer extends BeanDefinitionVisitor { - static final Pattern PROPERTY_PATTERN = Pattern.compile("\\$\\{([^:}]+):?[^}]*}"); - - public AddPropertySourcesPlaceholderConfigurer(J.ClassDecl profileConfigurationClass, RewriteBeanDefinitionRegistry beanDefinitionRegistry) { - super(profileConfigurationClass, beanDefinitionRegistry); - } - - @Override - public J visitClassDecl(J.ClassDecl classDecl) { - if(configurationClass.isScope(classDecl)) { - AtomicInteger seq = new AtomicInteger(); - - List propertyPlaceholders = registry.getBeanDefinitions(RewriteBeanDefinition.Type.PropertyPlaceholder).values().stream() - .sorted(Comparator.comparingInt(bd -> bd.getIntegerProperty("order").orElseGet(seq::incrementAndGet))) - .collect(toList()); - - Map propertyNamesByReference = propertyPlaceholders.stream() - .flatMap(pp -> pp.getStringProperty("location").stream().flatMap(loc -> stream(loc.split(",")))) - .flatMap(location -> PROPERTY_PATTERN.matcher(location).results()) - .collect(Collectors.toMap(res -> res.group(0), res -> res.group(1), (m1, m2) -> m1, LinkedHashMap::new)); - - if (!propertyPlaceholders.isEmpty()) { - AddBeanMethod addBeanMethod = new AddBeanMethod(classDecl, - "properties", - JavaType.Class.build("org.springframework.context.support.PropertySourcesPlaceholderConfigurer"), - true, - formatFirstPrefix(propertyNamesByReference.entrySet().stream() - .map(nameByRef -> (Statement) valueArgument(nameByRef.getValue(), nameByRef.getKey()).withPrefix(" ")) - .collect(toList()), "") - ); - - andThen(addBeanMethod); - - boolean ignoreResourceNotFound = propertyPlaceholders.stream() - .anyMatch(pp -> pp.getBooleanProperty("ignoreResourceNotFound").orElse(false)); - - boolean ignoreUnresolvablePlaceholders = propertyPlaceholders.stream() - .anyMatch(pp -> pp.getBooleanProperty("ignoreUnresolvable").orElse(false)); - - andThen(new AddBeanMethodBody(addBeanMethod, - "PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();\n" + - "Resource[] resources = new Resource[]{\n" + - propertyPlaceholders.stream() - .flatMap(pp -> pp.getStringProperty("location").stream().flatMap(loc -> stream(loc.split(",")))) - .map(location -> { - location = "\"" + propertyNamesByReference.entrySet().stream() - .reduce(location, (acc, nameByRef) -> acc.replace(nameByRef.getKey(), "\" + " + nameByRef.getValue() + " + \""), (r1, r2) -> r1) + "\""; - location = location.replace("\"\" + ", ""); - location = location.replace(" + \"\"", ""); - - if (location.startsWith("\"classpath:")) { - addImport("org.springframework.core.io.ClassPathResource"); - return "new ClassPathResource(\"" + location.substring("\"classpath:".length()) + ")"; - } - - addImport("org.springframework.core.io.FileSystemResource"); - return "new FileSystemResource(" + location + ")"; - }) - .collect(joining(",\n ", " ", "\n")) + - "};\n" + - "pspc.setLocations(resources);\n" + - (ignoreResourceNotFound ? "pspc.setIgnoreResourceNotFound(true);\n" : "") + - (ignoreUnresolvablePlaceholders ? "pspc.setIgnoreUnresolvablePlaceholders(true);\n" : "") + - "return pspc;", - JavaType.Class.build("org.springframework.core.io.ClassPathResource"), - JavaType.Class.build("org.springframework.core.io.FileSystemResource"), - JavaType.Class.build("org.springframework.core.io.Resource"), - JavaType.Class.build("org.springframework.context.support.PropertySourcesPlaceholderConfigurer"))); - - addImport("org.springframework.core.io.Resource"); - maybeAddImport("org.springframework.beans.factory.annotation.Value"); - } - } - - return super.visitClassDecl(classDecl); - } - - private Statement valueArgument(String name, String value) { - JavaType.Class valueType = JavaType.Class.build("org.springframework.beans.factory.annotation.Value"); - - J.Annotation valueAnnotation = new J.Annotation(randomId(), - J.Ident.build(randomId(), valueType.getClassName(), valueType, EMPTY), - new J.Annotation.Arguments( - randomId(), - singletonList(new J.Literal(randomId(), value, "\"" + value + "\"", JavaType.Primitive.String, EMPTY)), - EMPTY), - EMPTY); - - return new J.VariableDecls(randomId(), singletonList(valueAnnotation), emptyList(), - TreeBuilder.buildName("String").withType(JavaType.Class.build("java.lang.String")).withPrefix(" "), - null, - emptyList(), - singletonList(new J.VariableDecls.NamedVar(randomId(), - TreeBuilder.buildName(name), - emptyList(), null, JavaType.Class.build("java.lang.String"), format(" "))), - EMPTY); - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/bean/BeanDefinitionVisitor.java b/src/main/java/org/openrewrite/spring/xml/bean/BeanDefinitionVisitor.java deleted file mode 100644 index e8d758c75..000000000 --- a/src/main/java/org/openrewrite/spring/xml/bean/BeanDefinitionVisitor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.bean; - -import org.openrewrite.java.JavaRefactorVisitor; -import org.openrewrite.java.tree.J; -import org.openrewrite.spring.xml.parse.RewriteBeanDefinitionRegistry; - -public abstract class BeanDefinitionVisitor extends JavaRefactorVisitor { - protected final J.ClassDecl configurationClass; - protected final RewriteBeanDefinitionRegistry registry; - - public BeanDefinitionVisitor(J.ClassDecl profileConfigurationClass, RewriteBeanDefinitionRegistry registry) { - this.configurationClass = profileConfigurationClass; - this.registry = registry; - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/parse/RewriteBeanDefinition.java b/src/main/java/org/openrewrite/spring/xml/parse/RewriteBeanDefinition.java deleted file mode 100644 index 834355191..000000000 --- a/src/main/java/org/openrewrite/spring/xml/parse/RewriteBeanDefinition.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.parse; - -import org.openrewrite.internal.lang.NonNull; -import org.openrewrite.java.tree.JavaType; -import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.PropertyValue; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.core.ResolvableType; -import org.springframework.lang.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -public class RewriteBeanDefinition implements BeanDefinition { - public static final String TYPE_PROPERTY_KEY = "__rewrite_type"; - - private final BeanDefinition delegate; - - public RewriteBeanDefinition(BeanDefinition delegate) { - this.delegate = delegate; - } - - public JavaType.Class getType() { - return JavaType.Class.build(getBeanClassName()); - } - - public String getBeanDefinitionBody() { - JavaType.Class beanType = getType(); - String newClass = "new " + beanType.getClassName() + "("; - - ConstructorArgumentValues cav = getConstructorArgumentValues(); - if(!cav.isEmpty()) { - if(!cav.getIndexedArgumentValues().isEmpty()) { - newClass = cav.getIndexedArgumentValues().values().stream() - .map(ConstructorArgumentValues.ValueHolder::getName) - .collect(Collectors.joining(",")); - } - else { - List args = cav.getGenericArgumentValues(); - Optional> argsInOrder = beanType.getConstructors().stream() - .filter(c -> c.getParamNames().size() == args.size()) - .map(c -> { - List outOfOrder = new ArrayList<>(args); - List inOrder = new ArrayList<>(); - - for(JavaType paramType : c.getGenericSignature().getParamTypes()) { - if (!(paramType instanceof JavaType.FullyQualified)) { - return null; - } - - String paramTypeName = ((JavaType.FullyQualified) paramType).getFullyQualifiedName(); - for(int i = 0; i < outOfOrder.size(); i++) { - if(paramTypeName.equals(outOfOrder.get(i).getType())) { - inOrder.add(outOfOrder.get(i)); - outOfOrder.remove(i); - break; - } - } - } - - return outOfOrder.isEmpty() ? inOrder : null; - }) - .filter(Objects::nonNull) - .findAny(); - } - } - - newClass += ")"; - - if(getPropertyValues().isEmpty()) { - return "return " + newClass; - } - - else { - final String variableName = beanType.getClassName().substring(0, 1).toLowerCase() + - beanType.getClassName().substring(1); - - return beanType.getClassName() + " " + variableName + " = " + newClass + ";" + - getPropertyValues().getPropertyValueList().stream() - .map(pv -> variableName + ".set" + - pv.getName().substring(0, 1).toUpperCase() + - pv.getName().substring(1) + - "(" + - pv.getName() + - ");") - .collect(Collectors.joining("\n", "\n", "\n")) + - "return " + variableName + ";\n"; - } - } - - @SuppressWarnings("unchecked") - public final Optional getProperty(String property) { - PropertyValue propertyValue = getPropertyValues().getPropertyValue(property); - return propertyValue == null ? Optional.empty() : Optional.ofNullable((T) propertyValue.getValue()); - } - - public final Optional getStringProperty(String property) { - return this.getProperty(property); - } - - public final Optional getBooleanProperty(String property) { - return this.getProperty(property).map(value -> { - if (value instanceof String) - return Boolean.parseBoolean((String) value); - return (Boolean) value; - }); - } - - public final Optional getIntegerProperty(String property) { - return this.getProperty(property).map(value -> { - if (value instanceof String) - return Integer.parseInt((String) value); - return (Integer) value; - }); - } - - public final boolean isType(@Nullable Type type) { - return isPropertyEqualTo(TYPE_PROPERTY_KEY, type); - } - - public final boolean isPropertyEqualTo(String property, @org.openrewrite.internal.lang.Nullable Object value) { - Object propertyValue = getProperty(property).orElse(null); - return (value == null && propertyValue == null) || (value != null && value.equals(propertyValue)); - } - - public enum Type { - ComponentScan("context"), - PropertyPlaceholder("context"); - - private final String namespace; - - Type(String namespace) { - this.namespace = namespace; - } - - public String getNamespace() { - return namespace; - } - } - - @Override - public void setParentName(String parentName) { - delegate.setParentName(parentName); - } - - @Override - @Nullable - public String getParentName() { - return delegate.getParentName(); - } - - @Override - public void setBeanClassName(String beanClassName) { - delegate.setBeanClassName(beanClassName); - } - - @SuppressWarnings("ConstantConditions") - @Override - @NonNull - public String getBeanClassName() { - return delegate.getBeanClassName(); - } - - @Override - public void setScope(String scope) { - delegate.setScope(scope); - } - - @Override - @Nullable - public String getScope() { - return delegate.getScope(); - } - - @Override - public void setLazyInit(boolean lazyInit) { - delegate.setLazyInit(lazyInit); - } - - @Override - public boolean isLazyInit() { - return delegate.isLazyInit(); - } - - @Override - public void setDependsOn(String... dependsOn) { - delegate.setDependsOn(dependsOn); - } - - @Override - @Nullable - public String[] getDependsOn() { - return delegate.getDependsOn(); - } - - @Override - public void setAutowireCandidate(boolean autowireCandidate) { - delegate.setAutowireCandidate(autowireCandidate); - } - - @Override - public boolean isAutowireCandidate() { - return delegate.isAutowireCandidate(); - } - - @Override - public void setPrimary(boolean primary) { - delegate.setPrimary(primary); - } - - @Override - public boolean isPrimary() { - return delegate.isPrimary(); - } - - @Override - public void setFactoryBeanName(String factoryBeanName) { - delegate.setFactoryBeanName(factoryBeanName); - } - - @Override - @Nullable - public String getFactoryBeanName() { - return delegate.getFactoryBeanName(); - } - - @Override - public void setFactoryMethodName(String factoryMethodName) { - delegate.setFactoryMethodName(factoryMethodName); - } - - @Override - @Nullable - public String getFactoryMethodName() { - return delegate.getFactoryMethodName(); - } - - @Override - public ConstructorArgumentValues getConstructorArgumentValues() { - return delegate.getConstructorArgumentValues(); - } - - @Override - public boolean hasConstructorArgumentValues() { - return delegate.hasConstructorArgumentValues(); - } - - @Override - public MutablePropertyValues getPropertyValues() { - return delegate.getPropertyValues(); - } - - @Override - public boolean hasPropertyValues() { - return delegate.hasPropertyValues(); - } - - @Override - public void setInitMethodName(String initMethodName) { - delegate.setInitMethodName(initMethodName); - } - - @Override - @Nullable - public String getInitMethodName() { - return delegate.getInitMethodName(); - } - - @Override - public void setDestroyMethodName(String destroyMethodName) { - delegate.setDestroyMethodName(destroyMethodName); - } - - @Override - @Nullable - public String getDestroyMethodName() { - return delegate.getDestroyMethodName(); - } - - @Override - public void setRole(int role) { - delegate.setRole(role); - } - - @Override - public int getRole() { - return delegate.getRole(); - } - - @Override - public void setDescription(String description) { - delegate.setDescription(description); - } - - @Override - @Nullable - public String getDescription() { - return delegate.getDescription(); - } - - @Override - public ResolvableType getResolvableType() { - return delegate.getResolvableType(); - } - - @Override - public boolean isSingleton() { - return delegate.isSingleton(); - } - - @Override - public boolean isPrototype() { - return delegate.isPrototype(); - } - - @Override - public boolean isAbstract() { - return delegate.isAbstract(); - } - - @Override - @Nullable - public String getResourceDescription() { - return delegate.getResourceDescription(); - } - - @Override - @Nullable - public BeanDefinition getOriginatingBeanDefinition() { - return delegate.getOriginatingBeanDefinition(); - } - - @Override - public void setAttribute(String name, Object value) { - delegate.setAttribute(name, value); - } - - @Override - @Nullable - public Object getAttribute(String name) { - return delegate.getAttribute(name); - } - - @Override - @Nullable - public Object removeAttribute(String name) { - return delegate.removeAttribute(name); - } - - @Override - public boolean hasAttribute(String name) { - return delegate.hasAttribute(name); - } - - @Override - public String[] attributeNames() { - return delegate.attributeNames(); - } - - @Override - @Nullable - public Object getSource() { - return delegate.getSource(); - } -} \ No newline at end of file diff --git a/src/main/java/org/openrewrite/spring/xml/parse/RewriteBeanDefinitionRegistry.java b/src/main/java/org/openrewrite/spring/xml/parse/RewriteBeanDefinitionRegistry.java deleted file mode 100644 index b7187fbbb..000000000 --- a/src/main/java/org/openrewrite/spring/xml/parse/RewriteBeanDefinitionRegistry.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.parse; - -import org.openrewrite.internal.lang.Nullable; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry; - -import java.util.Map; -import java.util.function.Function; - -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; - -public class RewriteBeanDefinitionRegistry extends SimpleBeanDefinitionRegistry { - public final Map getBeanDefinitions(@Nullable RewriteBeanDefinition.Type type) { - return stream(getBeanDefinitionNames()) - .filter(name -> getBeanDefinition(name).isPropertyEqualTo(RewriteBeanDefinition.TYPE_PROPERTY_KEY, type)) - .collect(toMap(Function.identity(), this::getBeanDefinition)); - } - - @Override - public RewriteBeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { - return new RewriteBeanDefinition(super.getBeanDefinition(beanName)); - } -} diff --git a/src/main/java/org/openrewrite/spring/xml/parse/RewriteNamespaceHandler.java b/src/main/java/org/openrewrite/spring/xml/parse/RewriteNamespaceHandler.java deleted file mode 100644 index 9861b26a4..000000000 --- a/src/main/java/org/openrewrite/spring/xml/parse/RewriteNamespaceHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.parse; - -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser; -import org.springframework.beans.factory.xml.NamespaceHandlerSupport; -import org.w3c.dom.Element; - -import java.util.Map; - -public class RewriteNamespaceHandler extends NamespaceHandlerSupport { - private final Map types; - - public RewriteNamespaceHandler(Map types) { - this.types = types; - init(); - } - - @Override - public void init() { - for (Map.Entry parserByElementName : types.entrySet()) { - registerBeanDefinitionParser(parserByElementName.getKey(), new PropertyPreservingBeanDefinitionParser(parserByElementName.getValue())); - } - } - - private static class PropertyPreservingBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser { - private final RewriteBeanDefinition.Type type; - - private PropertyPreservingBeanDefinitionParser(RewriteBeanDefinition.Type type) { - this.type = type; - } - - @Override - protected boolean shouldGenerateId() { - return true; - } - - @Override - protected void postProcess(BeanDefinitionBuilder beanDefinition, Element element) { - beanDefinition.getBeanDefinition().setBeanClassName(type.getNamespace() + ":" + type.name()); - beanDefinition.getBeanDefinition().getPropertyValues().addPropertyValue(RewriteBeanDefinition.TYPE_PROPERTY_KEY, type); - super.postProcess(beanDefinition, element); - } - } -} \ No newline at end of file diff --git a/src/test/kotlin/org/openrewrite/spring/xml/AddConfigurationClassTest.kt b/src/test/kotlin/org/openrewrite/spring/xml/AddConfigurationClassTest.kt deleted file mode 100644 index 83cda1fa5..000000000 --- a/src/test/kotlin/org/openrewrite/spring/xml/AddConfigurationClassTest.kt +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml - -import org.openrewrite.spring.assertRefactored -import org.junit.jupiter.api.Test -import org.openrewrite.java.tree.J -import java.nio.file.Path - -class AddConfigurationClassTest { - private val mainSourceSet = Path.of("sourceSet") - - private val config = J.CompilationUnit - .buildEmptyClass(mainSourceSet, "my.org", "MyConfiguration") - .withMetadata(listOf(SpringMetadata.FILE_TYPE to "ConfigurationClass").toMap()) - - @Test - fun propertyPlaceholder() { - val fixed = config.refactor().visit(AddConfigurationClass(beanDefinitions(""" - - - - """), mainSourceSet)).fix().fixed - - assertRefactored(fixed, """ - package my.org; - - import org.springframework.beans.factory.annotation.Value; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; - import org.springframework.core.io.ClassPathResource; - import org.springframework.core.io.FileSystemResource; - import org.springframework.core.io.Resource; - - @Configuration - public class MyConfiguration { - - @Bean - public static PropertySourcesPlaceholderConfigurer properties(@Value("${'$'}{projectConfigPrefix:file:///}") String projectConfigPrefix, @Value("${'$'}{projectConfigDir}") String projectConfigDir) { - PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer(); - Resource[] resources = new Resource[]{ - new FileSystemResource(projectConfigPrefix + projectConfigDir + "/environment.properties"), - new ClassPathResource("project.properties"), - new FileSystemResource(projectConfigPrefix + projectConfigDir + "/sso.properties") - }; - pspc.setLocations(resources); - pspc.setIgnoreResourceNotFound(true); - pspc.setIgnoreUnresolvablePlaceholders(true); - return pspc; - } - } - """) - } - - @Test - fun componentScan() { - val fixed = config.refactor().visit(AddConfigurationClass(beanDefinitions(""" - - """), mainSourceSet)).fix().fixed - - assertRefactored(fixed, """ - package my.org; - - import org.springframework.context.annotation.ComponentScan; - import org.springframework.context.annotation.Configuration; - - @Configuration - @ComponentScan("nz.govt.project") - public class MyConfiguration { - } - """) - } - - @Test - fun multipleComponentScan() { - val fixed = config.refactor().visit(AddConfigurationClass(beanDefinitions(""" - - - """), mainSourceSet)).fix().fixed - - assertRefactored(fixed, """ - package my.org; - - import org.springframework.context.annotation.ComponentScan; - import org.springframework.context.annotation.Configuration; - - @Configuration - @ComponentScan({ - "au.govt.project", - "nz.govt.project" - }) - public class MyConfiguration { - } - """) - } - - @Test - fun wireBeanNotInSourceSet() { - val fixed = config.refactor().visit(AddConfigurationClass(beanDefinitions(""" - - - - - - """), mainSourceSet)).fix().fixed - - assertRefactored(fixed, """ - package my.org; - - import org.apache.tomcat.jdbc.pool.DataSource; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import org.springframework.jdbc.datasource.DataSourceTransactionManager; - - @Configuration - public class MyConfiguration { - - @Bean(destroyMethod="close") - public DataSource dataSource() { - return new DataSource(); - } - - @Bean - public DataSourceTransactionManager transactionManager(DataSource dataSource) { - DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); - dataSourceTransactionManager.setDataSource(dataSource); - return dataSourceTransactionManager; - } - } - """) - } -} diff --git a/src/test/kotlin/org/openrewrite/spring/xml/MakeComponentScannableTest.kt b/src/test/kotlin/org/openrewrite/spring/xml/MakeComponentScannableTest.kt deleted file mode 100644 index 775b3e7f3..000000000 --- a/src/test/kotlin/org/openrewrite/spring/xml/MakeComponentScannableTest.kt +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml - -import org.openrewrite.spring.assertRefactored -import org.junit.jupiter.api.Test -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.EmptySource -import org.junit.jupiter.params.provider.ValueSource -import org.openrewrite.java.JavaParser - - -class MakeComponentScannableTest : JavaParser() { - @Test - fun propertyRef() { - val repository = """ - package repositories; - public class UserRepository { - } - """.trimIndent() - - val service = parse(""" - package services; - - import repositories.*; - - public class UserService { - private UserRepository userRepository; - - public void setUserRepository(UserRepository userRepository) { - this.userRepository = userRepository; - } - } - """.trimIndent(), repository) - - val fixed = service.refactor().visit(MakeComponentScannable(beanDefinitions(""" - - - - - """))).fix().fixed - - assertRefactored(fixed, """ - package services; - - import org.springframework.beans.factory.annotation.Autowired; - import org.springframework.stereotype.Component; - import repositories.*; - - @Component - public class UserService { - @Autowired - private UserRepository userRepository; - - public void setUserRepository(UserRepository userRepository) { - this.userRepository = userRepository; - } - } - """) - } - - @ParameterizedTest - @ValueSource(strings = ["1000", "\${maxUsers}", "#{1000}"]) - fun propertyValue(value: String) { - val service = parse(""" - package services; - - public class UserService { - private int maxUsers; - - public void setMaxUsers(int maxUsers) { - this.maxUsers = maxUsers; - } - } - """.trimIndent()) - - val fixed = service.refactor().visit(MakeComponentScannable(beanDefinitions(""" - - - - """))).fix().fixed - - assertRefactored(fixed, """ - package services; - - import org.springframework.beans.factory.annotation.Value; - import org.springframework.stereotype.Component; - - @Component - public class UserService { - @Value(${if (value.contains("\${") || value.contains("#{")) "\"$value\"" else value}) - private int maxUsers; - - public void setMaxUsers(int maxUsers) { - this.maxUsers = maxUsers; - } - } - """) - } - - @ParameterizedTest - @EmptySource // technically Spring can't even do this for primitive types, but we don't need to unnecessarily limit argument resolution here - @ValueSource(strings = ["name=\"maxUsers\"", "index=\"0\"", "type=\"int\""]) - fun constructorArgValue(arg: String) { - val service = parse(""" - package services; - - public class UserService { - private int maxUsers; - - public UserService(int maxUsers) { - this.maxUsers = maxUsers; - } - } - """.trimIndent()) - - val fixed = service.refactor().visit(MakeComponentScannable(beanDefinitions(""" - - - - """))).fix().fixed - - assertRefactored(fixed, """ - package services; - - import org.springframework.beans.factory.annotation.Value; - import org.springframework.stereotype.Component; - - @Component - public class UserService { - private int maxUsers; - - public UserService(@Value(1000) int maxUsers) { - this.maxUsers = maxUsers; - } - } - """) - } - - @Test - fun lazyInit() { - val service = parse(""" - package services; - - public class UserService { - } - """.trimIndent()) - - val fixed = service.refactor().visit(MakeComponentScannable(beanDefinitions(""" - - """))).fix().fixed - - assertRefactored(fixed, """ - package services; - - import org.springframework.context.annotation.Lazy; - import org.springframework.stereotype.Component; - - @Component - @Lazy - public class UserService { - } - """) - } - - @Test - fun prototypeScope() { - val service = parse(""" - package services; - - public class UserService { - } - """.trimIndent()) - - val fixed = service.refactor().visit(MakeComponentScannable(beanDefinitions(""" - - """))).fix().fixed - - assertRefactored(fixed, """ - package services; - - import org.springframework.beans.factory.config.ConfigurableBeanFactory; - import org.springframework.context.annotation.Scope; - import org.springframework.stereotype.Component; - - @Component - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public class UserService { - } - """) - } - - @Test - fun lifecycleMethods() { - val service = parse(""" - package services; - - public class UserService { - public void onInit() { - } - - public void onDestroy() { - } - } - """.trimIndent()) - - val fixed = service.refactor().visit(MakeComponentScannable(beanDefinitions(""" - - """))).fix().fixed - - assertRefactored(fixed, """ - package services; - - import javax.annotation.PostConstruct; - import javax.annotation.PreDestroy; - import org.springframework.stereotype.Component; - - @Component - public class UserService { - @PostConstruct - public void onInit() { - } - - @PreDestroy - public void onDestroy() { - } - } - """) - } -} diff --git a/src/test/kotlin/org/openrewrite/spring/xml/bean/AddPropertySourcesPlaceholderConfigurerTest.java b/src/test/kotlin/org/openrewrite/spring/xml/bean/AddPropertySourcesPlaceholderConfigurerTest.java deleted file mode 100644 index 06a4b5e02..000000000 --- a/src/test/kotlin/org/openrewrite/spring/xml/bean/AddPropertySourcesPlaceholderConfigurerTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml.bean; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class AddPropertySourcesPlaceholderConfigurerTest { - @Test - void propertyPattern() { - String value = "${projectConfigPrefix:file:///}${projectConfigDir}/environment.properties"; - assertThat(AddPropertySourcesPlaceholderConfigurer.PROPERTY_PATTERN.matcher(value) - .results() - .map(res -> res.group(1))) - .containsExactlyInAnyOrder("projectConfigPrefix", "projectConfigDir"); - } -} diff --git a/src/test/kotlin/org/openrewrite/spring/xml/beans.kt b/src/test/kotlin/org/openrewrite/spring/xml/beans.kt deleted file mode 100644 index 8d06452f2..000000000 --- a/src/test/kotlin/org/openrewrite/spring/xml/beans.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2020 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 - *

- * https://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.openrewrite.spring.xml - -import com.github.marschall.memoryfilesystem.MemoryFileSystemBuilder -import org.openrewrite.spring.xml.parse.RewriteBeanDefinitionRegistry -import java.nio.file.Files -import java.nio.file.Path - -fun beanDefinitions(beanDefinitions: String): RewriteBeanDefinitionRegistry { - MemoryFileSystemBuilder.newEmpty().build("project").use { fs -> - val path: Path = fs.getPath("beans.xml") - - Files.newOutputStream(path).bufferedWriter().use { - it.write( - """ - - $beanDefinitions - - """.trimIndent() - ) - } - - val beanDefinitionRegistry = RewriteBeanDefinitionRegistry() - MigrateSpringXmlConfigurationJava.loadBeanDefinitions(listOf(path), beanDefinitionRegistry) - return beanDefinitionRegistry - } -} \ No newline at end of file