1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package com.finalist.mmbase.wizard;
16
17 import java.io.File;
18 import java.io.FileNotFoundException;
19 import java.io.FileWriter;
20 import java.util.*;
21 import javax.xml.parsers.DocumentBuilder;
22 import javax.xml.parsers.DocumentBuilderFactory;
23 import org.apache.velocity.Template;
24 import org.apache.velocity.VelocityContext;
25 import org.apache.velocity.app.Velocity;
26 import org.jaxen.dom.DOMXPath;
27 import org.w3c.dom.Document;
28 import org.w3c.dom.Element;
29 import org.w3c.dom.Attr;
30 import org.xml.sax.helpers.DefaultHandler;
31
32 /***
33 * The com.finalist.mmbase.wizard.WizardMaker walks through all editwizards generated by uml2mmbase
34 * and adds searchlists and relations to them, as indicated by <code>conf/wizard-config.xml</code>.
35 *
36 * @author mdemare
37 * @version $Revision: 1.6 $, $Date: 2005/03/21 14:37:38 $
38 * @created Jul 15, 2003
39 */
40 public class WizardMaker extends DefaultHandler {
41
42
43 private static String applicationXML = "";
44
45
46 private static String wizardConfigXML = "";
47
48 private static String generatedDir = "";
49
50 private static String searchTemplate = "";
51
52 private static String editRelatedObjects = "";
53
54
55 private static Map typeMap = new HashMap();
56
57 /***
58 * Creates a new com.finalist.mmbase.wizard.WizardMaker.
59 */
60 private WizardMaker() {
61 }
62
63
64 /***
65 * Returns all field names defined in the load editwizard of <code>name</code>.
66 * @param name the name of the wizard.
67 * @return a Set of Strings, indicating field names.
68 * @throws java.lang.Exception if anything went wrong.
69 */
70 private static List getFieldSet(String name) throws Exception {
71 String filename = generatedDir + File.separator + "editors" + File.separator + "config" + File.separator
72 + name + File.separator + "load_" + name + ".xml";
73 Document doc = parse(filename);
74
75 return new DOMXPath("//field/@name").selectNodes(doc);
76 }
77
78 /***
79 * Creates the <code>search_NAME</code> editwizard for the specified builder.
80 * @param to the builder for which to create the file.
81 * @param type the relation type
82 * @param label the userfriendly label
83 * @param isRequired flag indicating whether this relation is required
84 * @param searchfields a List of Strings, indicating the field names on which can be searched.
85 * @param relationfields a List of Strings, indicating the relation field names on which can be searched.
86 * @throws java.lang.Exception if anything went wrong
87 */
88 private static void createZoek(String from, String to, String type, String label, boolean isRequired,
89 List searchfields, List relationfields, String cardinalityLower,
90 String cardinalityUpper, String posrelSpecialization,
91 String editRelatedObjects) throws Exception {
92 VelocityContext context = new VelocityContext();
93
94 List searchFieldValues = new ArrayList();
95 Hashtable tl;
96
97
98
99
100
101
102 for (Iterator it = searchfields.iterator(); it.hasNext(); ) {
103 Element element = (Element) it.next();
104 tl = new Hashtable();
105 tl.put("fieldname",element.getAttribute("name"));
106 tl.put("fieldtype",element.getAttribute("type"));
107 tl.put("optionlist",element.getAttribute("optionlist"));
108 tl.put("minsize",element.getAttribute("minsize"));
109 tl.put("maxsize",element.getAttribute("maxsize"));
110 tl.put("reqired",element.getAttribute("required"));
111 tl.put("prompt",element.getAttribute("prompt"));
112
113 searchFieldValues.add(tl);
114 }
115
116 List relationFieldValues = new ArrayList();
117 for (Iterator it = relationfields.iterator(); it.hasNext(); ) {
118 Element element = (Element) it.next();
119 tl = new Hashtable();
120 tl.put("fieldname",element.getAttribute("name"));
121 tl.put("fieldtype",element.getAttribute("type"));
122 tl.put("optionlist",element.getAttribute("optionlist"));
123 tl.put("minsize",element.getAttribute("minsize"));
124 tl.put("maxsize",element.getAttribute("maxsize"));
125 tl.put("reqired",element.getAttribute("required"));
126 tl.put("prompt",element.getAttribute("prompt"));
127
128 relationFieldValues.add(tl);
129 }
130
131 context.put("builder", to);
132 context.put("type", type);
133 context.put("searchfields", searchFieldValues);
134 context.put("relationfields", relationFieldValues);
135 context.put("label", label);
136 context.put("cardinalityLower", cardinalityLower);
137 context.put("cardinalityUpper", cardinalityUpper);
138 context.put("posrelSpecialization", posrelSpecialization);
139 context.put("editRelatedObjects", editRelatedObjects);
140 if (isRequired) {
141 context.put("required", Boolean.TRUE);
142 }
143 Template t = Velocity.getTemplate(searchTemplate);
144 File parent = new File(generatedDir + File.separator + "editors" + File.separator + "config" + File.separator + to);
145 parent.mkdirs();
146 File file = new File(parent, "search_" + from + "_" + type + "_" + to + ".xml");
147 System.out.println("Creating " + file);
148 try {
149 FileWriter fw = new FileWriter(file);
150 t.merge(context, fw);
151 fw.close();
152 }
153 catch (FileNotFoundException e) {
154 System.out.println("File not found(" + file + ") exception occured (does the wizard exist?), skipping generation.");
155 }
156 }
157
158 /***
159 * Parses an XML file.
160 * @param name the filename of the XML document
161 * @return the XML document
162 * @throws java.lang.Exception if parsing failed
163 */
164 private static Document parse(String name) throws Exception {
165 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
166 dbf.setValidating(false);
167 DocumentBuilder parser = dbf.newDocumentBuilder();
168 parser.setEntityResolver(new MMBaseDTDResolver());
169 return parser.parse(new File(name));
170 }
171
172
173 /***
174 * This method finds all builders and their relations, and creates the search_NAME builders for them.
175 *
176 * @param args the commandline arguments; Path to the search template can be passed. Otherwise a default is used.
177 * @throws Exception velocity might throw an exception.
178 */
179 public static void main(String[] args) throws Exception {
180 if (args.length != 3) {
181 System.out.println("Two parameters expected for WizardMaker!");
182 return;
183 }
184
185 searchTemplate = args[0];
186 generatedDir = args[1];
187 editRelatedObjects = args[2];
188
189
190 applicationXML = generatedDir + File.separator + "WEB-INF" + File.separator + "config" + File.separator
191 + "applications" + File.separator + "APPLICATION.xml";
192 wizardConfigXML = generatedDir + File.separator + "wizard-search-config.xml";
193
194
195 Velocity.setProperty(Velocity.RUNTIME_LOG, "velocity1.log");
196 Velocity.init();
197
198 Document applicationXml = parse(applicationXML);
199 List applicationRelations = new DOMXPath(".//relation").selectNodes(applicationXml);
200
201 for (Iterator it = applicationRelations.iterator(); it.hasNext(); ) {
202 Element relation = (Element) it.next();
203 String from = relation.getAttribute("from");
204 String to = relation.getAttribute("to");
205 String type = relation.getAttribute("type");
206
207 typeMap.put(from + ":" + to + ":" + type, type);
208 typeMap.put(to + ":" + from + ":" + type, type);
209 }
210
211 Document wizardXml = parse(wizardConfigXML);
212
213
214 List builderSpecList = new DOMXPath(".//builder").selectNodes(wizardXml);
215 for (Iterator it = builderSpecList.iterator(); it.hasNext(); ) {
216 Element builderSpec = (Element) it.next();
217 String builderName = builderSpec.getAttribute("name");
218
219
220 List relationSpecList = new DOMXPath(".//relation").selectNodes(builderSpec);
221
222 List fields = getFieldSet(builderName);
223
224
225
226 for (Iterator relIt = relationSpecList.iterator(); relIt.hasNext(); ) {
227 Element relation = (Element) relIt.next();
228 String destination = relation.getAttribute("name");
229 String required = relation.getAttribute("required");
230 boolean isRequired = ("true".equals(required));
231 String label = relation.getAttribute("label");
232 String typeGiven = relation.getAttribute("type");
233 String type = (String) typeMap.get(builderName + ":" + destination + ":" + typeGiven);
234 String posrelSpecialization = relation.getAttribute("posrelspecialization");
235
236 List searchFields = new DOMXPath(".//field").selectNodes(relation);
237
238 List relationFields = new DOMXPath(".//relation-field").selectNodes(relation);
239
240 String cardinalityLower = relation.getAttribute("cardinality_lower");
241 String cardinalityUpper = relation.getAttribute("cardinality_upper");
242
243
244 createZoek(builderName, destination, type, label, isRequired, searchFields, relationFields,
245 cardinalityLower, cardinalityUpper, posrelSpecialization, editRelatedObjects);
246 }
247 }
248 }
249 }