1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.astrogrid.applications.description.registry;
15
16 import org.astrogrid.applications.beans.v1.ApplicationBase;
17 import org.astrogrid.applications.beans.v1.ApplicationList;
18 import org.astrogrid.applications.component.ProvidesVODescription;
19 import org.astrogrid.applications.description.ApplicationDescription;
20 import org.astrogrid.applications.description.ApplicationDescriptionLibrary;
21 import org.astrogrid.applications.description.DescriptionUtils;
22 import org.astrogrid.applications.description.exception.ApplicationDescriptionNotFoundException;
23 import org.astrogrid.component.descriptor.ComponentDescriptor;
24 import org.astrogrid.registry.beans.cea.ApplicationDefinition;
25 import org.astrogrid.registry.beans.cea.CeaApplicationType;
26 import org.astrogrid.registry.beans.cea.CeaServiceType;
27 import org.astrogrid.registry.beans.cea.ManagedApplications;
28 import org.astrogrid.registry.beans.cea.Parameters;
29 import org.astrogrid.registry.beans.resource.AccessURLType;
30 import org.astrogrid.registry.beans.resource.VODescription;
31 import org.astrogrid.registry.beans.resource.types.AccessURLTypeUseType;
32
33 import org.apache.axis.utils.XMLUtils;
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.exolab.castor.xml.CastorException;
37 import org.exolab.castor.xml.MarshalException;
38 import org.exolab.castor.xml.Marshaller;
39 import org.exolab.castor.xml.Unmarshaller;
40 import org.exolab.castor.xml.ValidationException;
41 import org.w3c.dom.Document;
42 import org.xml.sax.InputSource;
43
44 import java.io.IOException;
45 import java.io.InputStreamReader;
46 import java.io.StringReader;
47 import java.io.StringWriter;
48 import java.net.URL;
49
50 import junit.framework.Test;
51 import junit.framework.TestCase;
52
53 /***
54 * Creates a VODescription based on the contents of an ApplicationDescriptionLibrary.
55 *
56 * Requires a template file of the VODescription that contains the basic CeaApplication and CeaService entries to fill in.
57 * @author Noel Winstanley
58 * @author Paul Harrison (pah@jb.man.ac.uk) 22-Mar-2004
59 * @version $Name: $
60 * @since iteration5
61 * @see org.astrogrid.applications.component.ProvidesVODescription
62 * @todo this could do with a bit of a refactor - its quite messy still. Probably best to wait until the registry schema changes anyway..
63 */
64 public class RegistryEntryBuilder implements ProvidesVODescription , ComponentDescriptor{
65 /***
66 * Commons Logger for this class
67 */
68 private static final Log logger = LogFactory.getLog(RegistryEntryBuilder.class);
69 /*** configuration settings */
70 private URLs urls;
71
72 /*** library to generate description for */
73 private final ApplicationDescriptionLibrary lib;
74 private VODescription template;
75 private String serverID;
76 private String authorityID;
77
78 /*** Configuration interface - specifies location of resources required by {@link RegistryEntryBuilder}
79 * @author Noel Winstanley nw@jb.man.ac.uk 26-Jul-2004
80 *
81 */
82 public interface URLs {
83 /*** url of the template registry entry to use */
84 URL getRegistryTemplate();
85 /*** url of the endpoint of the current cea service */
86 URL getServiceEndpoint();
87 }
88
89
90 /***
91 * Construct a new RegistryEntryBuilder
92 * @param lib the library of descriptions to build a registry entry for
93 * @param urls configuration urls
94 */
95 public RegistryEntryBuilder(ApplicationDescriptionLibrary lib, URLs urls) {
96 this.lib = lib;
97 this.urls = urls;
98 try {
99
100 template = makeTemplate();
101 }
102 catch (Exception e) {
103 logger.error("error with template", e);
104 }
105 }
106
107 /***
108 * Create the registry entry....
109 * @return a vodescription.
110 */
111 public VODescription makeEntry() throws MarshalException, ValidationException, IOException, ApplicationDescriptionNotFoundException {
112 VODescription vodesc = new VODescription();
113 CeaApplicationType applicationTemplate =
114 (CeaApplicationType)template.getResource(0);
115 CeaServiceType serviceTemplate = (CeaServiceType)template.getResource(1);
116
117 CeaServiceType service = cloneTemplate(serviceTemplate);
118
119 service.getIdentifier().setAuthorityID(getAuthorityID());
120 service.getIdentifier().setResourceKey(serverID);
121 ManagedApplications managedApplications = new ManagedApplications();
122 service.setManagedApplications(managedApplications);
123 ApplicationList applist = makeApplist(lib);
124
125 for (int i = 0; i < applist.getApplicationDefnCount(); i++) {
126
127 ApplicationBase theapp = applist.getApplicationDefn(i);
128 ApplicationDescription theAppDesc = lib.getDescription(theapp.getName());
129
130 if (theapp.getName() != null) {
131 CeaApplicationType appentry = makeApplicationEntry(
132 applicationTemplate, theapp);
133 appentry.getSummary().setDescription(theAppDesc.getAppDescription());
134 appentry.getSummary().setReferenceURL(theAppDesc.getReferenceURL());
135 appentry.setTitle(theAppDesc.getUIName());
136 appentry.setShortName(theAppDesc.getUIName());
137 vodesc.addResource(appentry);
138
139 managedApplications.addApplicationReference(appentry
140 .getIdentifier());
141 }
142
143 }
144
145 AccessURLType accessurl = new AccessURLType();
146 accessurl.setContent(urls.getServiceEndpoint().toString()) ;
147 accessurl.setUse(AccessURLTypeUseType.BASE);
148 service.getInterface().setAccessURL(accessurl);
149 vodesc.addResource(service);
150 return vodesc;
151
152 }
153
154 /***
155 * Create and populate a new application entry.
156 * @param template The template on which the general application information in the entry is based.
157 * @param app Specific application information to be added to the entry.
158 * @return
159 * @throws MarshalException
160 * @throws ValidationException
161 */
162 private CeaApplicationType makeApplicationEntry(
163 CeaApplicationType template,
164 ApplicationBase app)
165 throws MarshalException, ValidationException {
166
167 CeaApplicationType entry = cloneTemplate(template);
168 entry.getIdentifier().setResourceKey(stripAuthorityFragment(app.getName()));
169 entry.getIdentifier().setAuthorityID(getAuthorityFragment(app.getName()));
170
171 ApplicationDefinition applicationDefinition = new ApplicationDefinition();
172
173 applicationDefinition.setInterfaces(app.getInterfaces());
174
175
176 Parameters regpar = new Parameters();
177 regpar.setParameterDefinition(app.getParameters().getParameter());
178 applicationDefinition.setParameters(regpar);
179
180
181 entry.setApplicationDefinition(applicationDefinition);
182 return entry;
183 }
184
185 /*** strips authority fragment, if present */
186 private String stripAuthorityFragment(String s) {
187 if (s.indexOf('/') != -1) {
188 return s.substring(s.indexOf('/') + 1);
189 } else {
190 return s;
191 }
192 }
193 private String getAuthorityFragment(String s)
194 {
195 if (s.indexOf('/') != -1) {
196 return s.substring(0, s.indexOf('/'));
197 } else {
198 return null;
199 }
200
201 }
202
203 /***
204 * Create a clone of the given object. Does this by using the castor marshalling/unmarshalling on the object.
205 * @param app
206 * @return
207 * @throws MarshalException
208 * @throws ValidationException
209 */
210 private CeaApplicationType cloneTemplate(CeaApplicationType app)
211 throws MarshalException, ValidationException {
212 StringWriter sw = new StringWriter();
213 CeaApplicationType newapp = null;
214 app.marshal(sw);
215 StringReader sr = new StringReader(sw.toString());
216 InputSource is = new InputSource(sr);
217 Unmarshaller um = new Unmarshaller(CeaApplicationType.class);
218 newapp = (CeaApplicationType)um.unmarshal(is);
219
220 return newapp;
221
222 }
223
224 /***
225 * Create a clone of the given object. Does this by using the castor marshalling/unmarshalling on the object.
226 * @param serv
227 * @return
228 * @throws MarshalException
229 * @throws ValidationException
230 */
231 private CeaServiceType cloneTemplate(CeaServiceType serv)
232 throws MarshalException, ValidationException {
233 CeaServiceType newserv = null;
234 StringWriter sw = new StringWriter();
235 serv.marshal(sw);
236 StringReader sr = new StringReader(sw.toString());
237 InputSource is = new InputSource(sr);
238 Unmarshaller um = new Unmarshaller(CeaServiceType.class);
239 newserv = (CeaServiceType)um.unmarshal(is);
240
241 return newserv;
242 }
243
244 /***
245 * Make an ApplicationList from a full configuration. This is a deep copy - new instances of the ApplicationBase objecst are created.
246 * @param clecConfig a configuration for a command line execution controller
247 * @return
248 * @TODO might be better to refactor the original schema so that there was a base type for the common execution contoller configs...
249 */
250 private ApplicationList makeApplist(ApplicationDescriptionLibrary lib) throws ApplicationDescriptionNotFoundException {
251 ApplicationList result = new ApplicationList();
252 String names[] = lib.getApplicationNames();
253 for (int i = 0; i < names.length; i++) {
254 ApplicationDescription descr = lib.getDescription(names[i]);
255 ApplicationBase base = DescriptionUtils.applicationDescription2ApplicationBase(descr);
256 result.addApplicationDefn(base);
257 }
258 return result;
259 }
260
261
262
263 /***
264 * Create a clone of an ApplicationBase object. This is done via the castor marshalling framework. In most cases this will be a downcast copy.
265 * @param in This can (and in most cases will) be one of the derived classes from ApplicationBase
266 * @return
267 */
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 /***
294 * @see org.astrogrid.applications.component.ProvidesVODescription#getDescription()
295 * @todo could cache the result.
296 */
297 public VODescription getVODescription() throws CastorException, ApplicationDescriptionNotFoundException, IOException {
298 return makeEntry();
299 }
300 /*** loads template fron url, builds objects from it */
301 private VODescription makeTemplate() throws IOException, MarshalException, ValidationException {
302 logger.info("using " + urls.getRegistryTemplate() + " as registry template");
303 InputStreamReader iStream = new InputStreamReader(urls.getRegistryTemplate().openStream());
304 VODescription temp = VODescription.unmarshalVODescription(iStream);
305
306 if( temp.getResource(1) instanceof CeaServiceType )
307 {
308 CeaServiceType service = (CeaServiceType)temp.getResource(1);
309 authorityID = service.getIdentifier().getAuthorityID();
310 serverID = service.getIdentifier().getResourceKey();
311 logger.info("from template the service is called "+service.getIdentifier().toString());
312 }
313 else
314 {
315 logger.error("template not in expected format - resulting VODescriptions may be wrong");
316 }
317 return temp;
318 }
319
320 public void reloadTemplate() throws MarshalException, ValidationException, IOException
321 {
322 template=makeTemplate();
323 }
324
325
326
327
328 public String getAuthorityID() {
329 return authorityID;
330 }
331
332
333
334 public String setServerID(String id) {
335 serverID = id;
336 return serverID;
337 }
338 /***
339 * @see org.astrogrid.component.descriptor.ComponentDescriptor#getName()
340 */
341 public String getName() {
342 return "Default VODescription Provider";
343 }
344
345 /***
346 * @see org.astrogrid.component.descriptor.ComponentDescriptor#getDescription()
347 */
348 public String getDescription() {
349 try {
350 VODescription desc = this.getVODescription();
351 Document doc = XMLUtils.newDocument();
352 Marshaller.marshal(desc,doc);
353 StringWriter sw = new StringWriter();
354 XMLUtils.PrettyDocumentToWriter(doc,sw);
355 return "VODescription \n" + XMLUtils.xmlEncodeString(sw.toString());
356 } catch (Exception e) {
357 return "Could not display description: " + e.getMessage();
358 }
359
360 }
361
362 /***
363 * @see org.astrogrid.component.descriptor.ComponentDescriptor#getInstallationTest()
364 */
365 public Test getInstallationTest() {
366 return new InstallationTest("testGetDescription");
367 }
368
369 /*** Installation test - checks that {@link RegistryEntryBuilder#getVODescription()} works correctly
370 * @author Noel Winstanley nw@jb.man.ac.uk 26-Jul-2004
371 *
372 */
373 public class InstallationTest extends TestCase {
374
375 public InstallationTest(String arg0) {
376 super(arg0);
377 }
378
379 public void testGetDescription() throws Exception {
380 VODescription desc = getVODescription();
381 assertNotNull(desc);
382 }
383
384 }
385
386 }