Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
AbstractChAL |
|
| 2.1666666666666665;2,167 |
1 | 0 | /** |
2 | * - Digitalis Internal Framework v2.0 - (C) 2007, Digitalis Informatica. Distribuicao e Gestao de Informatica, Lda. | |
3 | * Estrada de Paco de Arcos num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999 | |
4 | * http://www.digitalis.pt | |
5 | */ | |
6 | package pt.digitalis.dif.controller; | |
7 | ||
8 | import pt.digitalis.dif.controller.interfaces.IChAL; | |
9 | import pt.digitalis.dif.controller.interfaces.IDIFDispatcher; | |
10 | import pt.digitalis.dif.controller.interfaces.IDIFRequest; | |
11 | import pt.digitalis.dif.controller.interfaces.IDIFResponse; | |
12 | import pt.digitalis.dif.controller.interfaces.IDispatcherErrorHandler; | |
13 | import pt.digitalis.dif.controller.objects.ClientDescriptor; | |
14 | import pt.digitalis.dif.controller.objects.RESTAction; | |
15 | import pt.digitalis.dif.dem.annotations.controller.Channel; | |
16 | import pt.digitalis.dif.dem.managers.IMessageManager; | |
17 | import pt.digitalis.dif.exception.controller.BusinessFlowException; | |
18 | import pt.digitalis.dif.exception.controller.ControllerException; | |
19 | import pt.digitalis.dif.ioc.DIFIoCRegistry; | |
20 | ||
21 | import com.newrelic.api.agent.Trace; | |
22 | ||
23 | /** | |
24 | * Base implementation for all ChALs The API exposed to the Listener entities is the <code>serve()</code> method. All | |
25 | * the communication between AbstractChAL and Listener is done through this API. | |
26 | * | |
27 | * @param <RequestType> | |
28 | * type original request type | |
29 | * @param <ResponseType> | |
30 | * the original response type | |
31 | * @author Rodrigo Gonçalves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a> | |
32 | * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a> | |
33 | * @created 2007/03/27 | |
34 | */ | |
35 | 0 | abstract public class AbstractChAL<RequestType, ResponseType> implements IChAL<RequestType, ResponseType> { |
36 | ||
37 | /** The channel ID */ | |
38 | 0 | private String channelID = null; |
39 | ||
40 | /** The message manager. */ | |
41 | 0 | protected IMessageManager messageManager = DIFIoCRegistry.getRegistry().getImplementation(IMessageManager.class); |
42 | ||
43 | /** | |
44 | * Get the id of the channel associated to the ChAL. If the id is unset the method reads the channel id from the | |
45 | * annotation. | |
46 | * | |
47 | * @return the channel ID read from the {@link Channel} annotation | |
48 | */ | |
49 | public String getChannelID() | |
50 | { | |
51 | 0 | if (channelID == null) |
52 | 0 | channelID = this.getClass().getAnnotation(Channel.class).value(); |
53 | ||
54 | 0 | return channelID; |
55 | } | |
56 | ||
57 | /** | |
58 | * Creates a client descriptor object identifying the client agent who issued the request | |
59 | * | |
60 | * @param originalRequest | |
61 | * the original request object | |
62 | * @return the client descriptor for the current request | |
63 | * @throws ControllerException | |
64 | * when any runtime exception is thrown | |
65 | */ | |
66 | abstract protected ClientDescriptor getClientDescriptor(RequestType originalRequest) throws ControllerException; | |
67 | ||
68 | /** | |
69 | * Inspector of the dispatcher assigned to this channel. | |
70 | * | |
71 | * @return theDispatcher attribute | |
72 | */ | |
73 | protected IDIFDispatcher getDispatcher() | |
74 | { | |
75 | 0 | return DIFIoCRegistry.getRegistry().getImplementation(IDIFDispatcher.class, getChannelID()); |
76 | } | |
77 | ||
78 | /** | |
79 | * Inspector of the dispatcher assigned to this channel. | |
80 | * | |
81 | * @return theDispatcher attribute | |
82 | */ | |
83 | protected IDispatcherErrorHandler getErrorHandler() | |
84 | { | |
85 | 0 | return DIFIoCRegistry.getRegistry().getImplementation(IDispatcherErrorHandler.class, getChannelID()); |
86 | } | |
87 | ||
88 | /** | |
89 | * @see pt.digitalis.dif.controller.interfaces.IChAL#serve(java.lang.Object, java.lang.Object, | |
90 | * pt.digitalis.dif.controller.objects.RESTAction) | |
91 | * @param originalRequest | |
92 | * the original request object | |
93 | * @param finalResponse | |
94 | * the final response object | |
95 | * @param restAction | |
96 | * the REST action, if specified | |
97 | * @return the processed DIFResponse | |
98 | */ | |
99 | @Trace(metricName = "DIF:ChAL:Serve", dispatcher = true) | |
100 | public IDIFResponse serve(RequestType originalRequest, ResponseType finalResponse, RESTAction restAction) | |
101 | { | |
102 | ||
103 | 0 | IDIFResponse difResponse = null; |
104 | 0 | IDIFRequest difRequest = null; |
105 | ||
106 | try | |
107 | { | |
108 | 0 | difRequest = translateRequest(originalRequest); |
109 | 0 | difRequest.setRestAction(restAction); |
110 | ||
111 | // Initializes the client descriptor if ins't filled. The translateRequest is responsible for filling it. | |
112 | 0 | if (difRequest.getClient() == null) |
113 | 0 | difRequest.setClient(getClientDescriptor(originalRequest)); |
114 | ||
115 | 0 | if (validateRequest(originalRequest)) |
116 | { | |
117 | ||
118 | 0 | difResponse = getDispatcher().dispatch(difRequest); |
119 | ||
120 | // Fail-over. Should never return null. | |
121 | 0 | if (difResponse == null) |
122 | 0 | difResponse = getErrorHandler().getDefaultErrorResponse(difRequest, null); |
123 | ||
124 | } | |
125 | else | |
126 | 0 | difResponse = getErrorHandler().getDefaultErrorResponse(difRequest, null); |
127 | ||
128 | } | |
129 | 0 | catch (BusinessFlowException exception) |
130 | { | |
131 | 0 | difResponse = getErrorHandler().processException(difRequest, exception); |
132 | } | |
133 | 0 | catch (RuntimeException exception) |
134 | { | |
135 | 0 | difResponse = getErrorHandler().processException(difRequest, exception); |
136 | } | |
137 | 0 | catch (ControllerException exception) |
138 | { | |
139 | 0 | difResponse = getErrorHandler().processException(difRequest, exception); |
140 | } | |
141 | ||
142 | 0 | this.publish(difResponse, originalRequest, finalResponse); |
143 | ||
144 | 0 | return difResponse; |
145 | } | |
146 | ||
147 | /** | |
148 | * Validates the original request. It can be used to check if a particular request is valid for the channel. It may | |
149 | * also perform other validations, as the request parameters integrity. | |
150 | * | |
151 | * @param originalRequest | |
152 | * The original request received from the client. | |
153 | * @return T case the request is well formed, F otherwise | |
154 | * @throws ControllerException | |
155 | * when any runtime exception is thrown | |
156 | */ | |
157 | abstract protected boolean validateRequest(RequestType originalRequest) throws ControllerException; | |
158 | } |