4 changed files with 144 additions and 133 deletions
@ -1,80 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2019 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.springframework.core.task; |
|
||||||
|
|
||||||
import org.springframework.util.Assert; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Arrays; |
|
||||||
import java.util.Collection; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
/** |
|
||||||
* Composite {@link TaskDecorator} that delegates to other task decorators. |
|
||||||
* |
|
||||||
* @author Tadaya Tsuyukubo |
|
||||||
* @since 5.2 |
|
||||||
*/ |
|
||||||
public class CompositeTaskDecorator implements TaskDecorator { |
|
||||||
|
|
||||||
private final List<TaskDecorator> taskDecorators = new ArrayList<>(); |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a new {@link CompositeTaskDecorator}. |
|
||||||
* |
|
||||||
* @param taskDecorators the taskDecorators to delegate to |
|
||||||
* @throws IllegalArgumentException if {@code taskDecorators} is {@code null} |
|
||||||
*/ |
|
||||||
public CompositeTaskDecorator(Collection<? extends TaskDecorator> taskDecorators) { |
|
||||||
Assert.notNull(taskDecorators, "taskDecorators must not be null"); |
|
||||||
this.taskDecorators.addAll(taskDecorators); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a new {@link CompositeTaskDecorator}. |
|
||||||
* |
|
||||||
* @param taskDecorators the taskDecorators to delegate to |
|
||||||
* @throws IllegalArgumentException if {@code taskDecorators} is {@code null} |
|
||||||
*/ |
|
||||||
public CompositeTaskDecorator(TaskDecorator... taskDecorators) { |
|
||||||
Assert.notNull(taskDecorators, "taskDecorators must not be null"); |
|
||||||
this.taskDecorators.addAll(Arrays.asList(taskDecorators)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Add a delegating {@link TaskDecorator}. |
|
||||||
* |
|
||||||
* @param taskDecorator a taskDecorator to delegate to |
|
||||||
* @return {@code true} when the taskDecorator is successfully added |
|
||||||
* @throws IllegalArgumentException if {@code taskDecorator} is {@code null} |
|
||||||
*/ |
|
||||||
public boolean add(TaskDecorator taskDecorator) { |
|
||||||
Assert.notNull(taskDecorator, "taskDecorator must not be null"); |
|
||||||
return this.taskDecorators.add(taskDecorator); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Runnable decorate(Runnable runnable) { |
|
||||||
Assert.notNull(runnable, "runnable must not be null"); |
|
||||||
|
|
||||||
for (TaskDecorator taskDecorator : this.taskDecorators) { |
|
||||||
runnable = taskDecorator.decorate(runnable); |
|
||||||
} |
|
||||||
return runnable; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,54 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2023 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.springframework.core.task.support; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.springframework.core.task.TaskDecorator; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Composite {@link TaskDecorator} that delegates to other task decorators. |
||||||
|
* |
||||||
|
* @author Tadaya Tsuyukubo |
||||||
|
* @since 6.1 |
||||||
|
*/ |
||||||
|
public class CompositeTaskDecorator implements TaskDecorator { |
||||||
|
|
||||||
|
private final List<TaskDecorator> taskDecorators; |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a new instance. |
||||||
|
* @param taskDecorators the taskDecorators to delegate to |
||||||
|
*/ |
||||||
|
public CompositeTaskDecorator(Collection<? extends TaskDecorator> taskDecorators) { |
||||||
|
Assert.notNull(taskDecorators, "TaskDecorators must not be null"); |
||||||
|
this.taskDecorators = new ArrayList<>(taskDecorators); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Runnable decorate(Runnable runnable) { |
||||||
|
Assert.notNull(runnable, "Runnable must not be null"); |
||||||
|
for (TaskDecorator taskDecorator : this.taskDecorators) { |
||||||
|
runnable = taskDecorator.decorate(runnable); |
||||||
|
} |
||||||
|
return runnable; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,53 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2019 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.springframework.core.task; |
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat; |
|
||||||
|
|
||||||
/** |
|
||||||
* Test for {@link CompositeTaskDecorator}. |
|
||||||
* |
|
||||||
* @author Tadaya Tsuyukubo |
|
||||||
*/ |
|
||||||
class CompositeTaskDecoratorTests { |
|
||||||
|
|
||||||
@Test |
|
||||||
void decorate() { |
|
||||||
List<String> decorated = new ArrayList<>(); |
|
||||||
CompositeTaskDecorator compositeTaskDecorator = new CompositeTaskDecorator(runnable -> { |
|
||||||
decorated.add("foo"); |
|
||||||
return runnable; |
|
||||||
}); |
|
||||||
compositeTaskDecorator.add(runnable -> { |
|
||||||
decorated.add("bar"); |
|
||||||
return runnable; |
|
||||||
}); |
|
||||||
|
|
||||||
Runnable runnable = compositeTaskDecorator.decorate(() -> { |
|
||||||
decorated.add("baz"); |
|
||||||
}); |
|
||||||
|
|
||||||
runnable.run(); |
|
||||||
|
|
||||||
assertThat(decorated).containsExactly("foo", "bar", "baz"); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,90 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2023 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.springframework.core.task.support; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.mockito.InOrder; |
||||||
|
|
||||||
|
import org.springframework.core.task.TaskDecorator; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; |
||||||
|
import static org.mockito.ArgumentMatchers.any; |
||||||
|
import static org.mockito.BDDMockito.given; |
||||||
|
import static org.mockito.Mockito.inOrder; |
||||||
|
import static org.mockito.Mockito.mock; |
||||||
|
import static org.mockito.Mockito.verify; |
||||||
|
|
||||||
|
/** |
||||||
|
* Tests for {@link CompositeTaskDecorator}. |
||||||
|
* |
||||||
|
* @author Tadaya Tsuyukubo |
||||||
|
* @author Stephane Nicoll |
||||||
|
*/ |
||||||
|
class CompositeTaskDecoratorTests { |
||||||
|
|
||||||
|
@Test |
||||||
|
void createWithNullCollection() { |
||||||
|
assertThatIllegalArgumentException().isThrownBy(() -> new CompositeTaskDecorator(null)) |
||||||
|
.withMessage("TaskDecorators must not be null"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void decorateWithNullRunnable() { |
||||||
|
CompositeTaskDecorator taskDecorator = new CompositeTaskDecorator(List.of()); |
||||||
|
assertThatIllegalArgumentException().isThrownBy(() -> taskDecorator.decorate(null)) |
||||||
|
.withMessage("Runnable must not be null"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void decorate() { |
||||||
|
TaskDecorator first = mockNoOpTaskDecorator(); |
||||||
|
TaskDecorator second = mockNoOpTaskDecorator(); |
||||||
|
TaskDecorator third = mockNoOpTaskDecorator(); |
||||||
|
CompositeTaskDecorator taskDecorator = new CompositeTaskDecorator(List.of(first, second, third)); |
||||||
|
Runnable runnable = mock(Runnable.class); |
||||||
|
taskDecorator.decorate(runnable); |
||||||
|
InOrder ordered = inOrder(first, second, third); |
||||||
|
ordered.verify(first).decorate(runnable); |
||||||
|
ordered.verify(second).decorate(runnable); |
||||||
|
ordered.verify(third).decorate(runnable); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void decorateReuseResultOfPreviousRun() { |
||||||
|
Runnable original = mock(Runnable.class); |
||||||
|
Runnable firstDecorated = mock(Runnable.class); |
||||||
|
TaskDecorator first = mock(TaskDecorator.class); |
||||||
|
given(first.decorate(original)).willReturn(firstDecorated); |
||||||
|
Runnable secondDecorated = mock(Runnable.class); |
||||||
|
TaskDecorator second = mock(TaskDecorator.class); |
||||||
|
given(second.decorate(firstDecorated)).willReturn(secondDecorated); |
||||||
|
Runnable result = new CompositeTaskDecorator(List.of(first, second)).decorate(original); |
||||||
|
assertThat(result).isSameAs(secondDecorated); |
||||||
|
verify(first).decorate(original); |
||||||
|
verify(second).decorate(firstDecorated); |
||||||
|
} |
||||||
|
|
||||||
|
private TaskDecorator mockNoOpTaskDecorator() { |
||||||
|
TaskDecorator mock = mock(TaskDecorator.class); |
||||||
|
given(mock.decorate(any())).willAnswer(invocation -> invocation.getArguments()[0]); |
||||||
|
return mock; |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue