View Javadoc

1   /*$Id: DefaultParameterAdapter.java,v 1.13 2006/03/17 17:50:58 clq2 Exp $
2    * Created on 04-Jun-2004
3    *
4    * Copyright (C) AstroGrid. All rights reserved.
5    *
6    * This software is published under the terms of the AstroGrid 
7    * Software License version 1.2, a copy of which has been included 
8    * with this distribution in the LICENSE.txt file.  
9    *
10  **/
11  package org.astrogrid.applications.parameter;
12  
13  import org.apache.commons.logging.Log;
14  import org.apache.commons.logging.LogFactory;
15  
16  import org.astrogrid.applications.CeaException;
17  import org.astrogrid.applications.beans.v1.parameters.ParameterValue;
18  import org.astrogrid.applications.description.ParameterDescription;
19  import org.astrogrid.applications.parameter.protocol.ExternalValue;
20  import org.astrogrid.io.Piper;
21  import java.io.ByteArrayOutputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.InputStreamReader;
25  import java.io.OutputStream;
26  import java.io.OutputStreamWriter;
27  import java.io.PrintWriter;
28  import java.io.Reader;
29  import java.io.StringWriter;
30  
31  
32  /*** The default implementation of {@link org.astrogrid.applications.parameter.ParameterAdapter}
33   * <p/>
34   * Handles both direct and indirect parameters, returing them as an in-memory string.
35   * @see org.astrogrid.applications.parameter.protocol.ProtocolLibrary#getExternalValue(ParameterValue)
36   * @author Noel Winstanley (nw@jb.man.ac.uk)
37   * @author Paul Harrison (pah@jb.man.ac.uk)
38   * @todo should really do different things according to what the type of the parameter is.
39   * @todo check whether it is really appropriate use Readers and Writers to access the indirect parameters
40   */
41  public class DefaultParameterAdapter extends AbstractParameterAdapter {
42      /***
43       * Constructor.
44      * @param val
45      * @param description
46      * @param externalVal
47      */
48     public DefaultParameterAdapter(ParameterValue val, ParameterDescription description, ExternalValue externalVal) {
49        super(val, description, externalVal);
50        
51     }
52  
53     /***
54       * Commons Logger for this class
55       */
56      private static final Log logger = LogFactory
57              .getLog(DefaultParameterAdapter.class);
58  
59       /***
60       * retreives the value for this paramter
61       * if the parameter is direct, just return the value of the parameter value itself, 
62       * if indirect, retreive the value from the {@link #externalVal}
63       * @return always returns the string value of this parameter
64       *  */
65      public Object process() throws CeaException {
66          if (externalVal == null) {
67              return val.getValue();
68          } else {
69              Reader r = null;
70              StringWriter sw = null;
71              try {
72                  sw = new StringWriter();
73                  r = new InputStreamReader(externalVal.read());                
74                  Piper.pipe(r, sw);
75  
76                  return sw.toString();                
77              }
78              catch (IOException e) {
79                  throw new CeaException("Could not process parameter " + val.getName());
80              } finally {
81                  if (r != null) {
82                      try {
83                          r.close();
84                      } catch (IOException e) {
85                          logger.warn("could not close reader",e);
86                      }
87                  }
88                  if (sw != null) {
89                      try {
90                          sw.close();
91                      } catch (IOException e) {
92                          logger.warn("could not close writer",e);
93                      }
94                  }
95              }
96  
97          }
98      }
99  
100   /*** 
101    * Writes the value of an output parameter back to the parameter storage.
102    * That storage may be an internal buffer (a "direct" parameter) or 
103    * an external location (an "indirect" parameter). 
104    * Various forms of the value are supported: null object reference;
105    * byte array; InputStream; any other object. Binary values, such
106    * as the contents of FITS files, should be given as byte arrays or
107    * streams. Other values can be given as any object for which the
108    * toString() method produces a valid copy of the value. Note that
109    * the bit pattern of binary values is only sure to be preserved
110    * for an indirect parameter. In a direct parameter, the value is
111    * forced into a String object and may be corrupted in the process.
112    */
113   public void writeBack(Object o) throws CeaException {
114     if (this.externalVal == null) {
115       this.writeBackToParameterValue(o);
116     }
117     else {
118       this.writeBackToExternalValue(o);
119     }
120   }
121     
122   /***
123    * Writes a parameter value to a local ParameterValue object.  The value
124    * is always sent as a String, since ParameterValue requires this.
125    * Binary values (e.g. FITS files) are expected to arrive as byte arrays;
126    * these don't have an effective toString() method and are treated specially.
127    *
128    * @param o The object to be written out.
129    */
130   private void writeBackToParameterValue(Object o) throws CeaException {
131     try {
132       if (o == null) {
133         this.val.setValue("<null>");
134       }
135       else if (o instanceof byte[]) {
136         this.val.setValue(new String((byte[])o));
137       }
138       else if (o instanceof InputStream) {
139         InputStream is = (InputStream)o;
140         ByteArrayOutputStream os = new ByteArrayOutputStream();
141         this.pipe(is, os);
142         this.val.setValue(new String(os.toByteArray()));
143       }
144       else {
145         this.val.setValue(o.toString());
146       }
147     }
148     catch (Exception e) {
149       throw new CeaException("Failed to write back a value to a direct parameter.", e);
150     }
151   }
152    
153   /***
154    * Writes a parameter value to an ExternalValue object. 
155    *
156    * @param o The object to be written out.
157    */
158   private void writeBackToExternalValue(Object o) throws CeaException {
159     try {
160       if (o == null) {
161         PrintWriter pw = new PrintWriter(new OutputStreamWriter(externalVal.write()));
162         pw.println("<null>");
163         pw.close();
164       }
165       else if (o instanceof byte[]) {
166         OutputStream os = this.externalVal.write();
167         os.write((byte[])o);
168         os.close();
169       }
170       else if (o instanceof InputStream) {
171         InputStream is = (InputStream)o;
172         OutputStream os = this.externalVal.write();
173         this.pipe(is, os);
174         os.close();
175       }
176       else {
177         PrintWriter pw = new PrintWriter(new OutputStreamWriter(externalVal.write()));
178         pw.print(o);
179         pw.close();
180       }
181     }
182     catch (Exception e) {
183       throw new CeaException("Failed to write back a value to an indirect parameter.", e);
184     }
185     
186   }
187   
188   /***
189    * Copies an input stream onto an output stream.
190    */
191   private void pipe(InputStream is, OutputStream os) throws IOException {
192     byte[] block = new byte[65536];
193     int read = is.read(block);
194     while (read > -1) {
195       os.write(block, 0, read);
196       read = is.read(block);
197     }
198   }
199 }
200 
201 /* 
202 $Log: DefaultParameterAdapter.java,v $
203 Revision 1.13  2006/03/17 17:50:58  clq2
204 gtr_1489_cea correted version
205 
206 Revision 1.11  2006/03/07 21:45:26  clq2
207 gtr_1489_cea
208 
209 Revision 1.10.118.2  2006/02/07 18:45:06  gtr
210 This class now support parameter values written back via InputStreams. This allows some major optimizations.
211 
212 Revision 1.10.118.1  2006/02/07 16:34:22  gtr
213 Binary output parameters are now delivered to the ParameterAdapter as byte[] and treated accordingly.
214 
215 Revision 1.10  2004/11/27 13:20:02  pah
216 result of merge of pah_cea_bz561 branch
217 
218 Revision 1.9.10.1  2004/10/27 16:04:05  pah
219 pulled up an AbstractParameterAdapter
220 
221 Revision 1.9  2004/09/22 10:52:51  pah
222 getting rid of some unused imports
223 
224 Revision 1.8  2004/09/17 11:39:07  nw
225 made sure streams are closed
226 
227 Revision 1.7  2004/08/28 07:17:34  pah
228 commandline parameter passing - unit tests ok
229 
230 Revision 1.6  2004/07/30 14:54:47  jdt
231 merges in from case3 branch
232 
233 Revision 1.5.2.1  2004/07/30 13:11:59  jdt
234 typo
235 
236 Revision 1.5  2004/07/26 12:07:38  nw
237 renamed indirect package to protocol,
238 renamed classes and methods within protocol package
239 javadocs
240 
241 Revision 1.4  2004/07/22 16:33:48  nw
242 reads in values fully now.
243 
244 Revision 1.3  2004/07/20 02:03:23  nw
245 doc
246 
247 Revision 1.2  2004/07/01 11:16:22  nw
248 merged in branch
249 nww-itn06-componentization
250 
251 Revision 1.1.2.2  2004/07/01 01:42:46  nw
252 final version, before merge
253 
254 Revision 1.1.2.1  2004/06/17 09:21:23  nw
255 finished all major functionality additions to core
256 
257 Revision 1.1.2.1  2004/06/14 08:56:58  nw
258 factored applications into sub-projects,
259 got packaging of wars to work again
260  
261 */