1   package com.lexicalscope.fluentreflection.usecases;
2   
3   import static ch.lambdaj.Lambda.forEach;
4   import static com.lexicalscope.fluentreflection.FluentReflection.object;
5   import static com.lexicalscope.fluentreflection.ReflectionMatchers.annotatedWith;
6   import static org.hamcrest.MatcherAssert.assertThat;
7   import static org.hamcrest.Matchers.contains;
8   
9   import java.util.ArrayList;
10  import java.util.Collections;
11  import java.util.List;
12  
13  import javax.annotation.PostConstruct;
14  import javax.annotation.PreDestroy;
15  
16  import org.junit.Test;
17  
18  import com.lexicalscope.fluentreflection.FluentMethod;
19  
20  /*
21   * Copyright 2011 Tim Wood
22   *
23   * Licensed under the Apache License, Version 2.0 (the "License");
24   * you may not use this file except in compliance with the License.
25   * You may obtain a copy of the License at
26   *
27   * http://www.apache.org/licenses/LICENSE-2.0
28   *
29   * Unless required by applicable law or agreed to in writing, software
30   * distributed under the License is distributed on an "AS IS" BASIS,
31   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32   * See the License for the specific language governing permissions and
33   * limitations under the License. 
34   */
35  
36  public class TestCanCallAnnotatedMethodsInTheRightOrder {
37      interface TopInterface {
38          void afterConstruction();
39  
40          void beforeDestruction();
41      }
42  
43      static class AfterConstruction implements TopInterface {
44          List<String> result = new ArrayList<String>();
45  
46          @Override
47          @PostConstruct
48          public void afterConstruction() {
49              result.add("afterConstruction");
50          }
51  
52          @Override
53          @PreDestroy
54          public void beforeDestruction() {
55              result.add("beforeDestruction");
56          }
57      }
58  
59      static class AfterConstructionExtension extends AfterConstruction {
60          @PostConstruct
61          public void afterConstructionExtension() {
62              result.add("afterConstructionExtension");
63          }
64  
65          @PreDestroy
66          public void beforeDestructionExtension() {
67              result.add("beforeDestructionExtension");
68          }
69      }
70  
71      @Test
72      public void canCallPostConstructMethodsInTheCorrectOrder() throws Exception {
73          final AfterConstructionExtension subject = new AfterConstructionExtension();
74  
75          forEach(
76                  object(subject).methods(annotatedWith(PostConstruct.class)),
77                  FluentMethod.class).callRaw();
78  
79          assertThat(subject.result, contains("afterConstruction", "afterConstructionExtension"));
80      }
81  
82      @Test
83      public void canCallPreDestroyMethodsInTheCorrectOrder() throws Exception {
84          final AfterConstructionExtension subject = new AfterConstructionExtension();
85  
86          forEach(
87                  reverse(object(subject).methods(annotatedWith(PreDestroy.class))),
88                  FluentMethod.class).callRaw();
89  
90          assertThat(subject.result, contains("beforeDestructionExtension", "beforeDestruction"));
91      }
92  
93      private <T> List<T> reverse(final List<T> list) {
94          final ArrayList<T> result = new ArrayList<T>(list);
95          Collections.reverse(result);
96          return result;
97      }
98  }