From 70d0e35806641b3f6be8a8333243d10153e278e6 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Fri, 14 Feb 2014 16:24:11 +0200 Subject: [PATCH] `IntegrationComponentSpec` refactoring Introduce `Tuple` Apply `EndpointConfigurer` for `MessageSource<>` DSL-method --- .../integration/dsl/FilterEndpointSpec.java | 9 +- .../integration/dsl/GenericEndpointSpec.java | 3 +- .../dsl/IntegrationFlowBuilder.java | 7 +- .../integration/dsl/IntegrationFlows.java | 26 +-- .../dsl/SourcePollingChannelAdapterSpec.java | 35 ++++ .../dsl/channel/MessageChannelSpec.java | 13 +- .../dsl/channel/QueueChannelSpec.java | 2 +- .../dsl/config/InstanceBeanDefinition.java | 2 +- .../ConsumerEndpointSpec.java} | 66 ++------ ...slIntegrationConfigurationInitializer.java | 18 +- .../integration/dsl/core/EndpointSpec.java | 48 ++++++ ...pec.java => IntegrationComponentSpec.java} | 17 +- .../dsl/support/EndpointConfigurer.java | 4 +- .../integration/dsl/support/PollerSpec.java | 4 +- .../integration/dsl/tuple/Tuple.java | 156 ++++++++++++++++++ .../integration/dsl/tuple/Tuple1.java | 44 +++++ .../integration/dsl/tuple/Tuple2.java | 45 +++++ .../integration/dsl/tuple/package-info.java | 4 + .../main/resources/META-INF/spring.factories | 2 +- .../dsl/test/IntegrationFlowTests.java | 2 +- 20 files changed, 404 insertions(+), 103 deletions(-) create mode 100644 spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/SourcePollingChannelAdapterSpec.java rename spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/{EndpointSpec.java => core/ConsumerEndpointSpec.java} (50%) rename spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/{ => core}/DslIntegrationConfigurationInitializer.java (89%) create mode 100644 spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/EndpointSpec.java rename spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/{Spec.java => IntegrationComponentSpec.java} (76%) create mode 100644 spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple.java create mode 100644 spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple1.java create mode 100644 spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple2.java create mode 100644 spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/package-info.java diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/FilterEndpointSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/FilterEndpointSpec.java index 71b7e35..b1a0607 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/FilterEndpointSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/FilterEndpointSpec.java @@ -16,6 +16,7 @@ package org.springframework.integration.dsl; +import org.springframework.integration.dsl.core.ConsumerEndpointSpec; import org.springframework.integration.filter.MessageFilter; import org.springframework.messaging.MessageChannel; @@ -23,24 +24,24 @@ import org.springframework.messaging.MessageChannel; * @author Artem Bilan * @since 4.0 */ -public final class FilterEndpointSpec extends EndpointSpec { +public final class FilterEndpointSpec extends ConsumerEndpointSpec { FilterEndpointSpec(MessageFilter messageFilter) { super(messageFilter); } public FilterEndpointSpec throwExceptionOnRejection(boolean throwExceptionOnRejection) { - this.getHandler().setThrowExceptionOnRejection(throwExceptionOnRejection); + this.target.getT2().setThrowExceptionOnRejection(throwExceptionOnRejection); return _this(); } public FilterEndpointSpec discardChannel(MessageChannel discardChannel) { - this.getHandler().setDiscardChannel(discardChannel); + this.target.getT2().setDiscardChannel(discardChannel); return _this(); } public FilterEndpointSpec discardWithinAdvice(boolean discardWithinAdvice) { - this.getHandler().setDiscardWithinAdvice(discardWithinAdvice); + this.target.getT2().setDiscardWithinAdvice(discardWithinAdvice); return _this(); } diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/GenericEndpointSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/GenericEndpointSpec.java index 8590de3..2bb37d1 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/GenericEndpointSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/GenericEndpointSpec.java @@ -16,13 +16,14 @@ package org.springframework.integration.dsl; +import org.springframework.integration.dsl.core.ConsumerEndpointSpec; import org.springframework.messaging.MessageHandler; /** * @author Artem Bilan * @since 4.0 */ -public final class GenericEndpointSpec extends EndpointSpec, H> { +public final class GenericEndpointSpec extends ConsumerEndpointSpec, H> { GenericEndpointSpec(H messageHandler) { super(messageHandler); diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlowBuilder.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlowBuilder.java index fd4a6d0..aad3672 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlowBuilder.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlowBuilder.java @@ -24,6 +24,7 @@ import org.springframework.integration.core.GenericSelector; import org.springframework.integration.core.MessageProducer; import org.springframework.integration.core.MessageSelector; import org.springframework.integration.dsl.channel.MessageChannelSpec; +import org.springframework.integration.dsl.core.ConsumerEndpointSpec; import org.springframework.integration.dsl.support.EndpointConfigurer; import org.springframework.integration.filter.ExpressionEvaluatingSelector; import org.springframework.integration.filter.MessageFilter; @@ -124,7 +125,7 @@ public final class IntegrationFlowBuilder { return this; } - private > IntegrationFlowBuilder register(S endpointSpec, EndpointConfigurer endpointConfigurer) { + private > IntegrationFlowBuilder register(S endpointSpec, EndpointConfigurer endpointConfigurer) { if (endpointConfigurer != null) { endpointConfigurer.configure(endpointSpec); } @@ -135,9 +136,9 @@ public final class IntegrationFlowBuilder { this.registerOutputChannelIfCan(inputChannel); } - endpointSpec.getEndpoint().setInputChannel(inputChannel); + endpointSpec.get().getT1().setInputChannel(inputChannel); - return this.addComponent(endpointSpec).currentComponent(endpointSpec.getHandler()); + return this.addComponent(endpointSpec).currentComponent(endpointSpec.get().getT2()); } public IntegrationFlow get() { diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlows.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlows.java index a85a47f..cd11ddc 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlows.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlows.java @@ -19,10 +19,8 @@ package org.springframework.integration.dsl; import org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean; import org.springframework.integration.core.MessageSource; import org.springframework.integration.dsl.channel.MessageChannelSpec; -import org.springframework.integration.dsl.support.PollerSpec; -import org.springframework.integration.scheduling.PollerMetadata; +import org.springframework.integration.dsl.support.EndpointConfigurer; import org.springframework.messaging.MessageChannel; -import org.springframework.util.Assert; /** * @author Artem Bilan @@ -38,22 +36,16 @@ public final class IntegrationFlows { } public static IntegrationFlowBuilder from(MessageSource messageSource) { - return from(messageSource, (PollerMetadata) null); + return from(messageSource, null); } - public static IntegrationFlowBuilder from(MessageSource messageSource, PollerSpec pollerSpec) { - Assert.notNull(pollerSpec); - return from(messageSource, pollerSpec.get()); - } - - public static IntegrationFlowBuilder from(MessageSource messageSource, PollerMetadata pollerMetadata) { - SourcePollingChannelAdapterFactoryBean factoryBean = new SourcePollingChannelAdapterFactoryBean(); - factoryBean.setSource(messageSource); - factoryBean.setPollerMetadata(pollerMetadata); - return new IntegrationFlowBuilder() - .addComponent(messageSource) - .addComponent(factoryBean) - .currentComponent(factoryBean); + public static IntegrationFlowBuilder from(MessageSource messageSource, EndpointConfigurer endpointConfigurer) { + SourcePollingChannelAdapterSpec spec = new SourcePollingChannelAdapterSpec(messageSource); + if (endpointConfigurer != null) { + endpointConfigurer.configure(spec); + } + SourcePollingChannelAdapterFactoryBean sourcePollingChannelAdapterFactoryBean = spec.get().getT1(); + return new IntegrationFlowBuilder().addComponent(sourcePollingChannelAdapterFactoryBean).currentComponent(sourcePollingChannelAdapterFactoryBean); } /*public static IntegrationFlowBuilder from(AbstractEndpoint endpoint) { diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/SourcePollingChannelAdapterSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/SourcePollingChannelAdapterSpec.java new file mode 100644 index 0000000..4504410 --- /dev/null +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/SourcePollingChannelAdapterSpec.java @@ -0,0 +1,35 @@ +package org.springframework.integration.dsl; + +import org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean; +import org.springframework.integration.core.MessageSource; +import org.springframework.integration.dsl.core.EndpointSpec; +import org.springframework.integration.scheduling.PollerMetadata; + +/** + * @author Artem Bilan + * @since 4.0 + */ +public final class SourcePollingChannelAdapterSpec + extends EndpointSpec> { + + SourcePollingChannelAdapterSpec(MessageSource messageSource) { + super(messageSource); + this.target.getT1().setSource(messageSource); + } + + public SourcePollingChannelAdapterSpec phase(int phase) { + this.target.getT1().setPhase(phase); + return _this(); + } + + public SourcePollingChannelAdapterSpec autoStartup(boolean autoStartup) { + this.target.getT1().setAutoStartup(autoStartup); + return _this(); + } + + public SourcePollingChannelAdapterSpec poller(PollerMetadata pollerMetadata) { + this.target.getT1().setPollerMetadata(pollerMetadata); + return _this(); + } + +} diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannelSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannelSpec.java index 74951e8..1ee32bc 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannelSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/MessageChannelSpec.java @@ -19,25 +19,23 @@ package org.springframework.integration.dsl.channel; import java.util.Arrays; import org.springframework.integration.channel.AbstractMessageChannel; -import org.springframework.integration.dsl.core.Spec; +import org.springframework.integration.dsl.core.IntegrationComponentSpec; import org.springframework.messaging.support.ChannelInterceptor; /** * @author Artem Bilan */ -public abstract class MessageChannelSpec, C extends AbstractMessageChannel> extends Spec { +public abstract class MessageChannelSpec, C extends AbstractMessageChannel> extends IntegrationComponentSpec { protected C channel; - private String id; - private Class[] datatypes; private ChannelInterceptor[] interceptors; - S id(String id) { - this.id = id; - return _this(); + @Override + protected S id(String id) { + return super.id(id); } public S datatypes(Class... datatypes) { @@ -60,5 +58,4 @@ public abstract class MessageChannelSpec, C e return this.channel; } - } diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/QueueChannelSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/QueueChannelSpec.java index f3e9ff4..3cc9d07 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/QueueChannelSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/channel/QueueChannelSpec.java @@ -73,7 +73,7 @@ public class QueueChannelSpec extends MessageChannelSpec, H extends MessageHandler> { - - private final ConsumerEndpointFactoryBean endpointFactoryBean = new ConsumerEndpointFactoryBean(); - - private final H messageHandler; +public abstract class ConsumerEndpointSpec, H extends MessageHandler> + extends EndpointSpec { private final List adviceChain = new LinkedList(); - private String id; - - EndpointSpec(H messageHandler) { - this.messageHandler = messageHandler; - this.endpointFactoryBean.setHandler(this.messageHandler); - if (this.messageHandler instanceof AbstractReplyProducingMessageHandler) { - ((AbstractReplyProducingMessageHandler) this.messageHandler).setAdviceChain(this.adviceChain); + protected ConsumerEndpointSpec(H messageHandler) { + super(messageHandler); + this.target.getT1().setHandler(messageHandler); + if (messageHandler instanceof AbstractReplyProducingMessageHandler) { + ((AbstractReplyProducingMessageHandler) messageHandler).setAdviceChain(this.adviceChain); } else { - this.endpointFactoryBean.setAdviceChain(this.adviceChain); + this.target.getT1().setAdviceChain(this.adviceChain); } } - public S id(String id) { - this.id = id; - this.endpointFactoryBean.setBeanName(id); - return _this(); - } - public S phase(int phase) { - this.endpointFactoryBean.setPhase(phase); + this.target.getT1().setPhase(phase); return _this(); } public S autoStartup(boolean autoStartup) { - this.endpointFactoryBean.setAutoStartup(autoStartup); + this.target.getT1().setAutoStartup(autoStartup); + return _this(); + } + + public S poller(PollerMetadata pollerMetadata) { + this.target.getT1().setPollerMetadata(pollerMetadata); return _this(); } @@ -74,31 +67,4 @@ public abstract class EndpointSpec, H extends Messa return _this(); } - public S poller(PollerMetadata pollerMetadata) { - this.endpointFactoryBean.setPollerMetadata(pollerMetadata); - return _this(); - } - - public S poller(PollerSpec pollerMetadataSpec) { - this.endpointFactoryBean.setPollerMetadata(pollerMetadataSpec.get()); - return _this(); - } - - String getId() { - return id; - } - - ConsumerEndpointFactoryBean getEndpoint() { - return this.endpointFactoryBean; - } - - H getHandler() { - return this.messageHandler; - } - - @SuppressWarnings("unchecked") - protected S _this() { - return (S) this; - } - } diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/DslIntegrationConfigurationInitializer.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/DslIntegrationConfigurationInitializer.java similarity index 89% rename from spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/DslIntegrationConfigurationInitializer.java rename to spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/DslIntegrationConfigurationInitializer.java index 2aaeeb4..250f975 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/DslIntegrationConfigurationInitializer.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/DslIntegrationConfigurationInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.integration.dsl; +package org.springframework.integration.dsl.core; import java.util.Collection; import java.util.Map; @@ -31,8 +31,8 @@ import org.springframework.integration.channel.AbstractMessageChannel; import org.springframework.integration.config.ConsumerEndpointFactoryBean; import org.springframework.integration.config.IntegrationConfigurationInitializer; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; +import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.dsl.config.InstanceBeanDefinition; -import org.springframework.integration.dsl.core.Spec; import org.springframework.messaging.MessageHandler; import org.springframework.util.Assert; @@ -72,10 +72,10 @@ public class DslIntegrationConfigurationInitializer implements IntegrationConfig } registry.registerBeanDefinition(channelBeanName, beanDefinition); } - else if (instance instanceof EndpointSpec) { - EndpointSpec endpointSpec = (EndpointSpec) instance; - MessageHandler messageHandler = endpointSpec.getHandler(); - ConsumerEndpointFactoryBean endpoint = endpointSpec.getEndpoint(); + else if (instance instanceof ConsumerEndpointSpec) { + ConsumerEndpointSpec endpointSpec = (ConsumerEndpointSpec) instance; + MessageHandler messageHandler = endpointSpec.get().getT2(); + ConsumerEndpointFactoryBean endpoint = endpointSpec.get().getT1(); String id = endpointSpec.getId(); String handlerBeanName = generateInstanceBeanDefinitionName(registry, messageHandler); @@ -106,11 +106,11 @@ public class DslIntegrationConfigurationInitializer implements IntegrationConfig } private void populateBeansFromSpecs(ConfigurableListableBeanFactory beanFactory) { - Map specs = beanFactory.getBeansOfType(Spec.class, false, false); + Map specs = beanFactory.getBeansOfType(IntegrationComponentSpec.class, false, false); BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; - for (Map.Entry specEntry : specs.entrySet()) { + for (Map.Entry specEntry : specs.entrySet()) { String id = specEntry.getKey(); - Spec spec = specEntry.getValue(); + IntegrationComponentSpec spec = (IntegrationComponentSpec) specEntry.getValue(); registry.removeBeanDefinition(id); beanFactory.registerSingleton(id, spec.get()); beanFactory.initializeBean(spec.get(), id); diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/EndpointSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/EndpointSpec.java new file mode 100644 index 0000000..be8cd2c --- /dev/null +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/EndpointSpec.java @@ -0,0 +1,48 @@ +package org.springframework.integration.dsl.core; + +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.core.ResolvableType; +import org.springframework.integration.dsl.support.PollerSpec; +import org.springframework.integration.dsl.tuple.Tuple; +import org.springframework.integration.dsl.tuple.Tuple2; +import org.springframework.integration.scheduling.PollerMetadata; + +/** + * @author Artem Bilan + * @since 4.0 + */ +public abstract class EndpointSpec, F extends BeanNameAware, H> extends IntegrationComponentSpec> { + + @SuppressWarnings("unchecked") + protected EndpointSpec(H handler) { + try { + Class fClass = ResolvableType.forClass(this.getClass()).as(EndpointSpec.class).resolveGenerics()[1]; + F endpointFactoryBean = (F) fClass.newInstance(); + this.target = Tuple.of(endpointFactoryBean, handler); + } + catch (Exception e) { + throw new IllegalStateException(e); + } + } + + public S id(String id) { + this.target.getT1().setBeanName(id); + return super.id(id); + } + + public abstract S phase(int phase); + + public abstract S autoStartup(boolean autoStartup); + + public abstract S poller(PollerMetadata pollerMetadata); + + public S poller(PollerSpec pollerMetadataSpec) { + return this.poller(pollerMetadataSpec.get()); + } + + @Override + protected final Tuple2 doGet() { + throw new UnsupportedOperationException(); + } + +} diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/Spec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/IntegrationComponentSpec.java similarity index 76% rename from spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/Spec.java rename to spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/IntegrationComponentSpec.java index bd6d5f3..bb135a8 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/Spec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/core/IntegrationComponentSpec.java @@ -20,9 +20,20 @@ package org.springframework.integration.dsl.core; * @author Artem Bilan * @since 4.0 */ -public abstract class Spec, T> { +public abstract class IntegrationComponentSpec, T> { - private volatile T target; + protected volatile T target; + + protected String id; + + protected S id(String id) { + this.id = id; + return _this(); + } + + String getId() { + return id; + } public final T get() { if (this.target == null) { @@ -34,7 +45,7 @@ public abstract class Spec, T> { protected abstract T doGet(); @SuppressWarnings("unchecked") - protected S _this() { + protected final S _this() { return (S) this; } diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/support/EndpointConfigurer.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/support/EndpointConfigurer.java index 1b8297b..fc22f15 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/support/EndpointConfigurer.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/support/EndpointConfigurer.java @@ -16,13 +16,13 @@ package org.springframework.integration.dsl.support; -import org.springframework.integration.dsl.EndpointSpec; +import org.springframework.integration.dsl.core.EndpointSpec; /** * @author Artem Bilan * @since 4.0 */ -public interface EndpointConfigurer> { +public interface EndpointConfigurer> { void configure(S spec); diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/support/PollerSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/support/PollerSpec.java index ef092ed..5854f52 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/support/PollerSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/support/PollerSpec.java @@ -23,7 +23,7 @@ import java.util.concurrent.Executor; import org.aopalliance.aop.Advice; -import org.springframework.integration.dsl.core.Spec; +import org.springframework.integration.dsl.core.IntegrationComponentSpec; import org.springframework.integration.scheduling.PollerMetadata; import org.springframework.integration.transaction.TransactionSynchronizationFactory; import org.springframework.scheduling.Trigger; @@ -36,7 +36,7 @@ import org.springframework.util.ErrorHandler; * @author Artem Bilan * @since 4.0 */ -public final class PollerSpec extends Spec { +public final class PollerSpec extends IntegrationComponentSpec { private final PollerMetadata pollerMetadata = new PollerMetadata(); diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple.java new file mode 100644 index 0000000..e76ebc3 --- /dev/null +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2011-2013 GoPivotal, Inc. All Rights Reserved. + * + * 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.integration.dsl.tuple; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +import org.springframework.util.Assert; + +/** + * A {@literal Tuple} is an immutable {@link java.util.Collection} of objects, each of which can be of an arbitrary type. + * + * @author Jon Brisbin + * @author Stephane Maldini + */ +@SuppressWarnings({"rawtypes"}) +public class Tuple implements Iterable, Serializable { + + private static final long serialVersionUID = 8777121214502020842L; + + protected final Object[] entries; + + protected final int size; + + /** + * Creates a new {@code Tuple} that holds the given {@code values}. + * + * @param values The values to hold + */ + public Tuple(Collection values) { + Assert.notEmpty(values); + this.entries = values.toArray(); + this.size = entries.length; + } + + /** + * Creates a new {@code Tuple} that holds the given {@code values}. + * + * @param values The values to hold + */ + public Tuple(Object... values) { + this.entries = Arrays.copyOf(values, values.length); + this.size = values.length; + } + + /** + * Create a {@link Tuple1} with the given object. + * + * @param t1 The first value in the tuple. + * @param The type of the first value. + * @return The new {@link Tuple1}. + */ + public static Tuple1 of(T1 t1) { + return new Tuple1(t1); + } + + /** + * Create a {@link Tuple2} with the given objects. + * + * @param t1 The first value in the tuple. + * @param t2 The second value in the tuple. + * @param The type of the first value. + * @param The type of the second value. + * @return The new {@link Tuple2}. + */ + public static Tuple2 of(T1 t1, T2 t2) { + return new Tuple2(t1, t2); + } + + + /** + * Get the object at the given index. + * + * @param index The index of the object to retrieve. Starts at 0. + * @return The object. Might be {@literal null}. + */ + public Object get(int index) { + return (size > 0 && size > index ? entries[index] : null); + } + + /** + * Turn this {@literal Tuple} into a plain Object array. + * + * @return A new Object array. + */ + public Object[] toArray() { + return entries; + } + + /** + * Return the number of elements in this {@literal Tuple}. + * + * @return The size of this {@literal Tuple}. + */ + public int size() { + return size; + } + + @Override + public Iterator iterator() { + return Arrays.asList(entries).iterator(); + } + + + @Override + public int hashCode() { + if (this.size == 0) { + return 0; + } + else if (this.size == 1) { + return this.entries[0].hashCode(); + } + else { + int hashCode = 1; + for (Object entry : this.entries) { + hashCode = hashCode ^ entry.hashCode(); + } + return hashCode; + } + } + + @Override + public boolean equals(Object o) { + if (o == null) return false; + + if (!(o instanceof Tuple)) return false; + + Tuple cast = (Tuple) o; + + if (this.size != cast.size) return false; + + for (int i = 0; i < this.size; i++) { + if (!this.entries[i].equals(cast.entries[i])) { + return false; + } + } + return true; + } + +} diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple1.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple1.java new file mode 100644 index 0000000..9bb3c07 --- /dev/null +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple1.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011-2013 GoPivotal, Inc. All Rights Reserved. + * + * 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.integration.dsl.tuple; + +/** + * A tuple that holds a single value + * + * @param The type held by this tuple + * + * @author Jon Brisbin + */ +public class Tuple1 extends Tuple { + + private static final long serialVersionUID = -1467756857377152573L; + + Tuple1(Object... values) { + super(values); + } + + /** + * Type-safe way to get the first object of this {@link Tuple}. + * + * @return The first object, cast to the correct type. + */ + @SuppressWarnings("unchecked") + public T1 getT1() { + return (T1) get(0); + } + +} diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple2.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple2.java new file mode 100644 index 0000000..fa844a8 --- /dev/null +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/Tuple2.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011-2013 GoPivotal, Inc. All Rights Reserved. + * + * 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.integration.dsl.tuple; + +/** + * A tuple that holds two values + * + * @param The type of the first value held by this tuple + * @param The type of the second balue held by this tuple + * + * @author Jon Brisbin + */ +public class Tuple2 extends Tuple1 { + + private static final long serialVersionUID = -565933838909569191L; + + Tuple2(Object... values) { + super(values); + } + + /** + * Type-safe way to get the second object of this {@link Tuple}. + * + * @return The second object, cast to the correct type. + */ + @SuppressWarnings("unchecked") + public T2 getT2() { + return (T2) get(1); + } + +} diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/package-info.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/package-info.java new file mode 100644 index 0000000..a55a4a2 --- /dev/null +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/tuple/package-info.java @@ -0,0 +1,4 @@ +/** + * Tuples provide a type-safe way to specify multiple parameters. + */ +package org.springframework.integration.dsl.tuple; diff --git a/spring-integration-java-dsl/src/main/resources/META-INF/spring.factories b/spring-integration-java-dsl/src/main/resources/META-INF/spring.factories index 52182ce..4c31c0a 100644 --- a/spring-integration-java-dsl/src/main/resources/META-INF/spring.factories +++ b/spring-integration-java-dsl/src/main/resources/META-INF/spring.factories @@ -1,2 +1,2 @@ org.springframework.integration.config.IntegrationConfigurationInitializer=\ -org.springframework.integration.dsl.DslIntegrationConfigurationInitializer +org.springframework.integration.dsl.core.DslIntegrationConfigurationInitializer diff --git a/spring-integration-java-dsl/src/test/java/org/springframework/integration/dsl/test/IntegrationFlowTests.java b/spring-integration-java-dsl/src/test/java/org/springframework/integration/dsl/test/IntegrationFlowTests.java index c0af239..dbc9d07 100644 --- a/spring-integration-java-dsl/src/test/java/org/springframework/integration/dsl/test/IntegrationFlowTests.java +++ b/spring-integration-java-dsl/src/test/java/org/springframework/integration/dsl/test/IntegrationFlowTests.java @@ -134,7 +134,7 @@ public class IntegrationFlowTests { @Bean public IntegrationFlow flow1() { - return IntegrationFlows.from(this.integerMessageSource(), Pollers.fixedRate(100)) + return IntegrationFlows.from(this.integerMessageSource(), c -> c.poller(Pollers.fixedRate(100))) .transform("payload.toString()") .channel(MessageChannels.queue("flow1QueueChannel")) .get();