1
2
3
4
5
6
7
8
9
10
11
12 package org.astrogrid.applications.commandline.digester;
13
14 import java.net.URL;
15
16 import javax.xml.parsers.ParserConfigurationException;
17
18 import org.apache.commons.digester.AbstractObjectCreationFactory;
19 import org.apache.commons.digester.Digester;
20 import org.apache.commons.digester.NodeCreateRule;
21 import org.apache.commons.digester.RegexRules;
22 import org.apache.commons.digester.SimpleRegexMatcher;
23 import org.astrogrid.applications.beans.v1.ParameterRef;
24 import org.astrogrid.applications.commandline.CommandLineParameterDescription;
25 import org.astrogrid.applications.description.ApplicationDescription;
26 import org.astrogrid.applications.description.BaseApplicationDescriptionLibrary;
27 import org.astrogrid.applications.description.base.ApplicationDescriptionEnvironment;
28 import org.astrogrid.applications.description.exception.ApplicationDescriptionNotLoadedException;
29 import org.w3c.dom.Node;
30 import org.xml.sax.Attributes;
31
32 /*** ApplicationDescrptions Library for use with commandline apps.
33 * Loads the application descriptions from the description file into a set of {@link ApplicationDescription} objects. It uses the {@link org.apache.commons.digester.Digester} to parse the XML file.
34 * The schema for these definitions is located at <a href="http://www.astrogrid.org/viewcvs/%2Acheckout%2A/astrogrid/applications/schema/AGParameterDefinition.xsd?rev=HEAD&content-type=text/plain">schema</a>
35 * @author Paul Harrison (pah@jb.man.ac.uk)
36 * @version $Name: $
37 * @since iteration4
38 * @TODO make namespace aware - this is a bit of a hack with namespaces at the moment....
39 * @TODO validate the input xml
40 * @TODO really better to use castor
41 * @TODO perhaps better to refactor the schema into the commandline project.
42 */
43 public class CommandLineDescriptionsLoader extends BaseApplicationDescriptionLibrary {
44 static private org.apache.commons.logging.Log logger =
45 org.apache.commons.logging.LogFactory.getLog(CommandLineDescriptionsLoader.class);
46
47 public interface DescriptionURL {
48 URL getURL();
49 }
50
51
52 public CommandLineDescriptionsLoader(DescriptionURL finder, CommandLineApplicationDescriptionFactory appDescFactory, ApplicationDescriptionEnvironment envin)
53 throws ApplicationDescriptionNotLoadedException {
54 super(envin);
55 this.configFile = finder.getURL();
56 this.appDescFactory = appDescFactory;
57 loadDescription();
58 }
59 protected final URL configFile;
60 protected final CommandLineApplicationDescriptionFactory appDescFactory;
61
62 public final void loadDescription() throws ApplicationDescriptionNotLoadedException {
63 logger.info( "loading application descriptions from " + configFile.toString());
64
65 try {
66 Digester digester = createDigester();
67 digester.parse(configFile.openStream());
68 if(getApplicationNames().length == 0 ) {
69 throw new ApplicationDescriptionNotLoadedException("0 descriptions loaded from "+configFile.toString());
70 }
71 }
72 catch (Exception e) {
73 throw new ApplicationDescriptionNotLoadedException("failed to load descriptions from "+configFile.toString(),e);
74 }
75
76 }
77 /***
78 * Creates the digester suitable for reading the application description file. The correct funtioning ot this method is highly dependent on the details of the schema.
79 * @return
80 */
81 private Digester createDigester() throws ParserConfigurationException {
82
83 Digester digester = new Digester();
84 digester.setValidating(false);
85 digester.setNamespaceAware(false);
86 digester.setRules(new RegexRules(new SimpleRegexMatcher()));
87
88 digester.push(this);
89
90 digester.addFactoryCreate(CommandLineApplicationDescriptionsConstants.APPLICATION_ELEMENT,appDescFactory);
91
92 digester.addSetProperties(CommandLineApplicationDescriptionsConstants.APPLICATION_ELEMENT);
93 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.EXPATH_ELEMENT, "setExecutionPath", 0);
94 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.LONGNAME_ELEMENT, "setUIName", 0);
95 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.DESCRIPTION_ELEMENT, "setAppDescription", 0);
96 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.URL_ELEMENT, "setReferenceURL", 0);
97
98
99 digester.addObjectCreate(CommandLineApplicationDescriptionsConstants.PARAMETER_ELEMENT,CommandLineParameterDescription.class);
100 digester.addSetProperties(CommandLineApplicationDescriptionsConstants.PARAMETER_ELEMENT,"type","typeString");
101
102
103 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.UI_NAME_ELEMENT, "setDisplayName", 0);
104 digester.addRule(CommandLineApplicationDescriptionsConstants.UI_DESC_ELEMENT, new NodeCreateRule(Node.ELEMENT_NODE));
105 digester.addRule(CommandLineApplicationDescriptionsConstants.UI_DESC_ELEMENT, new AllBodyIncElementsRule("displayDescription", true));
106 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.UCD_ELEMENT, "setUcd", 0);
107 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.DEFVAL_ELEMENT, "setDefaultValue", 0);
108 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.UNITSL_ELEMENT, "setUnits", 0);
109
110
111
112 digester.addSetNext(CommandLineApplicationDescriptionsConstants.PARAMETER_ELEMENT, "addParameterDescription");
113
114 digester.addFactoryCreate(CommandLineApplicationDescriptionsConstants.INTERFACE_ELEMENT,new BaseApplicationInterfaceFactory());
115
116 digester.addSetProperties(CommandLineApplicationDescriptionsConstants.INTERFACE_ELEMENT);
117
118 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.INPUT_PREFS, "addInputParameterAsPref", 1, new Class[]{ParameterRef.class});
119 digester.addObjectCreate(CommandLineApplicationDescriptionsConstants.INPUT_PREFS, ParameterRef.class);
120 digester.addSetProperties(CommandLineApplicationDescriptionsConstants.INPUT_PREFS);
121 digester.addCallParam(CommandLineApplicationDescriptionsConstants.INPUT_PREFS, 0, true);
122
123
124
125 digester.addCallMethod(CommandLineApplicationDescriptionsConstants.OUTPUT_PREFS, "addOutputParameterAsPref", 1, new Class[]{ParameterRef.class});
126 digester.addObjectCreate(CommandLineApplicationDescriptionsConstants.OUTPUT_PREFS, ParameterRef.class);
127 digester.addSetProperties(CommandLineApplicationDescriptionsConstants.OUTPUT_PREFS);
128 digester.addCallParam(CommandLineApplicationDescriptionsConstants.OUTPUT_PREFS, 0, true);
129
130
131
132 digester.addSetNext(CommandLineApplicationDescriptionsConstants.INTERFACE_ELEMENT, "addInterface");
133
134
135 digester.addSetNext(CommandLineApplicationDescriptionsConstants.APPLICATION_ELEMENT, "addApplicationDescription");
136 return digester;
137
138
139 }
140
141
142
143
144 private static class BaseApplicationInterfaceFactory extends AbstractObjectCreationFactory {
145
146 public Object createObject(Attributes arg0) throws Exception {
147 String name = "**unknown";
148 if (arg0.getValue(CommandLineApplicationDescriptionsConstants.NAME_ATTR) != null) {
149 name = arg0.getValue(CommandLineApplicationDescriptionsConstants.NAME_ATTR);
150 }
151 ApplicationDescription appDescription = (ApplicationDescription)this.digester.peek();
152 return new CommandLineApplicationInterface(name,appDescription);
153 }
154 }
155
156
157
158 }