View Javadoc

1   /*
2    * Copyright 2010-2013 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.callbackparams.internal.template;
18  
19  import java.lang.reflect.InvocationHandler;
20  import java.lang.reflect.InvocationTargetException;
21  import java.lang.reflect.Method;
22  import java.util.IdentityHashMap;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  import org.callbackparams.CallbackControlPanel;
27  
28  /**
29   * Wraps an array of all combined values that are to be used for a
30   * single test-run. This array is also referred to as a callback-record
31   * throughout the CallbackParams documentation - hence the name of this class.
32   *
33   * @author Henrik Kaipe
34   */
35  public class CallbackRecord {
36  
37      private final List callbackRecord;
38      private final Map latestCallbackResults = new IdentityHashMap();
39      private final CallbackControlPanel ccp = new CallbackControlPanel() {
40          public List getCurrentCallbackRecord() {
41              return callbackRecord;
42          }
43          public Map getLatestCallbackResults() {
44              return latestCallbackResults;
45          }
46      };
47  
48      public CallbackRecord(List callbackRecord) {
49          this.callbackRecord = callbackRecord;
50      }
51  
52      public CallbackControlPanel getCallbackControlPanel() {
53          return ccp;
54      }
55  
56      public InvocationHandler newCallbackInvoker(final CallbackRef callbackRef) {
57          return new InvocationHandler() {
58              
59              public Object invoke(Object o, Method m, Object[] args)
60              throws Throwable {
61                  if (false == m.isAccessible()) {
62                      m.setAccessible(true);
63                  }
64  
65                  final ReturnValueDigester returnValueDigester =
66                          ReturnValueDigester.newInstance(m, args);
67                  for (Iterator i = callbackRecord.iterator(); i.hasNext();) {
68                      final Object callbackRecordElement = i.next();
69                      if (null == callbackRecordElement) {
70                          continue;
71                      }
72                      final Object targetCallbackInstance =
73                              callbackRef.asCallback(callbackRecordElement);
74                      if (null == targetCallbackInstance) {
75                          continue;
76                      }
77  
78                      try {
79                          Object returnValue = m.invoke(
80                                  targetCallbackInstance,
81                                  returnValueDigester.getArguments());                                
82                          returnValueDigester.digestNext(
83                                  callbackRecordElement, returnValue);
84  
85                      } catch (final InvocationTargetException ite) {
86                          final Throwable targetProblem = ite.getTargetException();
87                          try {
88                              returnValueDigester
89                                      .updateLatestCallbackResultsInCallbackControlPanel(
90                                      latestCallbackResults);
91                              latestCallbackResults
92                                      .put(callbackRecordElement, new Object() {
93                                  public String toString() {
94                                      return targetProblem.getClass().getName()
95                                              + " was thrown from "
96                                              + targetCallbackInstance
97                                              + ": " + targetProblem.getMessage();
98                                  }
99                              });
100                         } finally {
101                             throw targetProblem;
102                         }
103                     }
104                 }
105 
106                 returnValueDigester
107                         .updateLatestCallbackResultsInCallbackControlPanel(
108                         latestCallbackResults);
109                 return returnValueDigester.returnValue();
110             }
111         };
112     }
113 }