1
2
3
4
5
6
7
8
9
10
11 package org.astrogrid.applications.apps;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15
16 import java.io.ByteArrayInputStream;
17 import java.io.ByteArrayOutputStream;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import org.astrogrid.applications.AbstractApplication;
26 import org.astrogrid.applications.Application;
27 import org.astrogrid.applications.CeaException;
28 import org.astrogrid.applications.DefaultIDs;
29 import org.astrogrid.applications.Status;
30 import org.astrogrid.applications.beans.v1.parameters.ParameterValue;
31 import org.astrogrid.applications.beans.v1.parameters.types.ParameterTypes;
32 import org.astrogrid.applications.description.ApplicationInterface;
33 import org.astrogrid.applications.description.Cardinality;
34 import org.astrogrid.applications.description.ParameterDescription;
35 import org.astrogrid.applications.description.base.AbstractApplicationDescription;
36 import org.astrogrid.applications.description.base.ApplicationDescriptionEnvironment;
37 import org.astrogrid.applications.description.base.BaseApplicationInterface;
38 import org.astrogrid.applications.description.base.BaseParameterDescription;
39 import org.astrogrid.applications.description.exception.ParameterDescriptionNotFoundException;
40 import org.astrogrid.applications.parameter.DefaultParameterAdapter;
41 import org.astrogrid.applications.parameter.ParameterAdapter;
42 import org.astrogrid.applications.parameter.protocol.ExternalValue;
43 import org.astrogrid.applications.parameter.protocol.ProtocolLibrary;
44 import org.astrogrid.community.User;
45 import org.astrogrid.component.descriptor.ComponentDescriptor;
46 import org.astrogrid.io.Piper;
47 import org.astrogrid.workflow.beans.v1.Tool;
48
49 import junit.framework.Test;
50
51 /*** Simple application that behaves a bit like unix 'cat' - concatenates a bunch of files together.
52 * @author Noel Winstanley nw@jb.man.ac.uk 16-Aug-2004
53 *
54 */
55 public class CatApplicationDescription extends AbstractApplicationDescription
56 implements ComponentDescriptor {
57 /***
58 * Commons Logger for this class
59 */
60 private static final Log logger = LogFactory
61 .getLog(CatApplicationDescription.class);
62
63 /*** Construct a new CatApplicationDescription
64 * @param env
65 */
66 public CatApplicationDescription(ApplicationDescriptionEnvironment env) {
67 super(env);
68 this.setMetaData();
69 }
70
71 /*** set up metadata for this instance */
72 private final void setMetaData() {
73 StringBuffer thename = new StringBuffer(env.getAuthIDResolver().getAuthorityID());
74 thename.append("/concat");
75 setName(thename.toString());
76 BaseParameterDescription result = new BaseParameterDescription();
77 result.setName("result");
78 result.setDisplayName("Result");
79 result.setDisplayDescription("result of concatenating data together");
80 result.setType(ParameterTypes.BINARY);
81 this.addParameterDescription(result);
82
83 BaseParameterDescription src = new BaseParameterDescription();
84 src.setName("src");
85 src.setDisplayName("Source");
86 src.setDisplayDescription("an input to concatenate");
87 src.setType(ParameterTypes.BINARY);
88 this.addParameterDescription(src);
89
90 BaseApplicationInterface intf = new BaseApplicationInterface("basic",this);
91 try {
92 intf.addInputParameter(src.getName(),Cardinality.MANDATORY_REPEATED);
93 intf.addOutputParameter(result.getName());
94
95 } catch (ParameterDescriptionNotFoundException e) {
96 logger.fatal("Programming error",e);
97 throw new RuntimeException("Programming Error",e);
98 }
99 this.addInterface(intf);
100
101 }
102
103 /***
104 * @see org.astrogrid.component.descriptor.ComponentDescriptor#getDescription()
105 */
106 public String getDescription() {
107 return "Cat application\n" + this.toString();
108 }
109
110 /***
111 * @see org.astrogrid.component.descriptor.ComponentDescriptor#getInstallationTest()
112 */
113 public Test getInstallationTest() {
114 return null;
115 }
116
117 /***
118 * @see org.astrogrid.applications.description.ApplicationDescription#initializeApplication(java.lang.String, org.astrogrid.community.User, org.astrogrid.workflow.beans.v1.Tool)
119 */
120 public Application initializeApplication(String callerAssignedID,
121 User user, Tool tool) throws Exception {
122 String newID = env.getIdGen().getNewID();
123 final DefaultIDs ids = new DefaultIDs(callerAssignedID,newID,user);
124 ApplicationInterface iface = this.getInterface(tool.getInterface());
125 return new CatApplication(ids,tool,iface,env.getProtocolLib());
126
127 }
128
129 public static class CatApplication extends AbstractApplication {
130
131 /*** Construct a new CatApplication
132 * @param ids
133 * @param tool
134 * @param applicationInterface
135 * @param lib
136 */
137 public CatApplication(IDs ids, Tool tool, ApplicationInterface applicationInterface, ProtocolLibrary lib) {
138 super(ids, tool, applicationInterface, lib);
139 }
140 public Runnable createExecutionTask() throws CeaException {
141 createAdapters();
142 setStatus(Status.INITIALIZED);
143 Runnable r = new Runnable() {
144 public void run() {
145 try {
146 setStatus(Status.RUNNING);
147 List streams = new ArrayList();
148 for (Iterator i = inputParameterAdapters(); i.hasNext();) {
149 ParameterAdapter input = (ParameterAdapter)i.next();
150 reportMessage("reading in parameter " + input.getWrappedParameter().getValue());
151 streams.add(input.process());
152 }
153 setStatus(Status.WRITINGBACK);
154 ParameterAdapter out= (ParameterAdapter)outputParameterAdapters().next();
155 out.writeBack(streams);
156 setStatus(Status.COMPLETED);
157 } catch (CeaException e) {
158 reportError("something failed",e);
159 }
160 }
161 };
162 return r;
163 }
164 protected ParameterAdapter instantiateAdapter(ParameterValue pval,
165 ParameterDescription descr, ExternalValue indirectVal) {
166 return new StreamParameterAdapter(pval, descr, indirectVal);
167 }
168
169 }
170
171 /*** parameter adapter that produces and consumes streams, rather than string values - for efficiency when handling large amounts of data.
172 * @todo maybe a candidate for factoring out into a package of useful parameter adapters later.*/
173 public static class StreamParameterAdapter extends DefaultParameterAdapter {
174 /*** always returns an InputStream */
175 public Object process() throws CeaException {
176 if (externalVal == null) {
177 return new ByteArrayInputStream(val.getValue().getBytes());
178 } else {
179 return externalVal.read();
180 }
181 }
182
183 /*** expects a list of input streams */
184 public void writeBack(Object o) throws CeaException {
185 if (! (o instanceof List)) {
186 throw new CeaException("Programming error - expected List of Streams, got " + o.getClass().getName());
187 }
188 OutputStream os = null;
189 if (externalVal == null) {
190 os = new ByteArrayOutputStream();
191 } else {
192 os = externalVal.write();
193 }
194 try {
195 InputStream is = null;
196 for (Iterator i = ((List)o).iterator(); i.hasNext(); ) {
197 try {
198 is = (InputStream)i.next();
199 Piper.pipe(is,os);
200 } finally {
201 if (is != null) {
202 try {
203 is.close();
204 } catch (IOException e) {
205 logger.warn("failed to close input stream",e);
206 }
207 }
208 }
209 }
210 } catch (IOException e) {
211 throw new CeaException("Faled to write back",e);
212 } finally {
213 if (os != null) {
214 try {
215 os.close();
216 } catch (IOException e) {
217 logger.warn("failed to close output stream",e);
218 }
219 }
220 }
221 if (externalVal == null) {
222 val.setValue(os.toString());
223 }
224 }
225 public StreamParameterAdapter(ParameterValue val, ParameterDescription description, ExternalValue externalVal) {
226 super(val, description, externalVal);
227 }
228
229
230 }
231
232 }
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267