]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/method/AsyncResultImpl.java
Added addFirst/After/Before + remove SCL functions for Ordered Sets
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / method / AsyncResultImpl.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  Industry THTH ry.
4  *  All rights reserved. This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License v1.0
6  *  which accompanies this distribution, and is available at
7  *  http://www.eclipse.org/legal/epl-v10.html
8  *
9  *  Contributors:
10  *      VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.databoard.method;
13
14 import java.util.concurrent.Semaphore;
15 import java.util.concurrent.TimeUnit;
16 import java.util.logging.Level;
17 import java.util.logging.Logger;
18
19 import org.simantics.databoard.adapter.AdaptException;
20 import org.simantics.databoard.adapter.Adapter;
21 import org.simantics.databoard.method.MethodInterface.AsyncRequestStatus;
22 import org.simantics.databoard.method.MethodInterface.AsyncResult;
23 import org.simantics.databoard.method.MethodInterface.ExecutionError;
24 import org.simantics.databoard.method.MethodInterface.InvokeListener;
25
26 public class AsyncResultImpl implements AsyncResult {
27         
28         /**
29          * Log4J Error logger. 
30          * Security settings are logged with DEBUG level.
31          * Unexpected errors are logged with ERROR level. 
32          */
33         static Logger LOGGER = Logger.getLogger("AsyncResultImpl");
34         
35         InvokeException invokeException;
36         Object executionError;
37         
38         Object response;
39                         
40         InvokeListener listener;
41         
42         // Optional adapters
43         Adapter responseAdapter, errorAdapter;
44         
45         Semaphore sleeper = new Semaphore(0);
46
47         public AsyncResultImpl() {
48         }       
49         
50         @Override
51         public Object getExecutionError() {
52                 return executionError;
53         }
54
55         @Override
56         public InvokeException getInvokeException() {
57                 return invokeException;
58         }
59         
60         public void setInvokeException(final InvokeException error)
61         {
62                 this.invokeException = error;
63                 final InvokeListener l = listener;                      
64                 sleeper.release(Integer.MAX_VALUE);
65                 
66                 if (l != null) {
67                         // TODO use executor instead
68                         new Thread() {
69                                 public void run() {
70                                         try {
71                                                 l.onException((Exception) error.getCause());
72                                         } catch (RuntimeException e) {
73                                                 LOGGER.log(Level.SEVERE, "Unexpected runtime exception", e);
74                                         }
75                                 };
76                         }.start();
77                 }
78                 
79         }
80
81         public void setResponse(Object response) {              
82                 if (responseAdapter!=null) {
83                         try {
84                                 response = responseAdapter.adapt(response);
85                         } catch (AdaptException e) {
86                                 setInvokeException( new InvokeException("Failed to adapt the respose "+response, e) );
87                                 return;
88                         }
89                 }
90                         
91                 this.response = response;
92                 final InvokeListener l = listener;                      
93                 sleeper.release(Integer.MAX_VALUE);
94
95                 if (l != null) {
96                         // TODO use executor instead
97                         new Thread() {
98                                 public void run() {
99                                         try {
100                                                 l.onCompleted(AsyncResultImpl.this.response);
101                                         } catch (RuntimeException e) {
102                                                 LOGGER.log(Level.SEVERE, "Unexpected runtime exception", e);
103                                         }
104                                 };
105                         }.start();
106                 }
107         }
108         
109         public void setExecutionError(Object executionError) {
110                 
111                 if (errorAdapter!=null) {
112                         // Adapt execution error using adapter
113                         try {
114                                 executionError = errorAdapter.adapt(executionError);
115                         } catch (AdaptException e) {
116                                 // Unable to adapt execution error. This is now an invokcation error
117                                 setInvokeException(new InvokeException("Execution and Invoke failed. Failed to adapt executionError ("+executionError+")", e));
118                                 return;
119                         }
120                 }
121                 
122                 this.executionError = executionError;
123                 final InvokeListener l = listener;                      
124                 sleeper.release(Integer.MAX_VALUE);
125                 
126                 if (l != null) {
127                         // TODO use executor instead
128                         new Thread() {
129                                 public void run() {
130                                         l.onExecutionError(AsyncResultImpl.this.executionError);
131                                         // TODO Capture runtimeException, push to log4j
132                                 };
133                         }.start();
134                 }
135         }
136         
137         
138         @Override
139         public Object getResponse() {
140                 return response;
141         }
142
143         @Override
144         public AsyncRequestStatus getStatus() {
145                 if (invokeException!=null || executionError!=null)
146                         return AsyncRequestStatus.Failed;
147                 if (response!=null)
148                         return AsyncRequestStatus.Succeed;
149                 return AsyncRequestStatus.Waiting;
150         }
151
152         @Override
153         public void setListener(InvokeListener listener) {
154                 // FIXME event is lost if error/result is set at the same time
155                 if (listener!=null) {
156                         if (response!=null) listener.onCompleted(response);
157                         if (invokeException!=null) listener.onException((Exception)invokeException.getCause());
158                         if (executionError!=null) listener.onExecutionError(executionError);
159                 }
160                 this.listener = listener;
161         }
162
163         @Override
164         public Object waitForResponse() throws InvokeException, ExecutionError, InterruptedException {
165                 sleeper.acquire();
166                 if (response!=null) return response;
167                 if (invokeException!=null) throw invokeException;
168                 if (executionError!=null) throw new ExecutionError(executionError);                             
169                 return null;
170         }
171
172         @Override
173         public Object waitForResponse(long timeout, TimeUnit unit)
174                         throws InvokeException, ExecutionError, InterruptedException {
175                 sleeper.tryAcquire(timeout, unit);
176                 if (response!=null) return response;
177                 if (invokeException!=null) throw invokeException;
178                 if (executionError!=null) throw new ExecutionError(executionError);                             
179                 return null;
180         }
181
182         public void setResponseAdapter(Adapter responseAdapter) {
183                 this.responseAdapter = responseAdapter;
184         }
185
186         public void setErrorAdapter(Adapter errorAdapter) {
187                 this.errorAdapter = errorAdapter;
188         }
189                 
190 }
191