1
2
3
4
5
6
7
8
9
10
11 package com.sri.emo.controller;
12
13 import com.jcorporate.expresso.core.controller.ExpressoRequest;
14 import com.jcorporate.expresso.core.db.DBException;
15 import com.jcorporate.expresso.core.misc.StringUtil;
16 import com.sri.emo.dbobj.*;
17 import org.apache.log4j.Logger;
18 import org.dom4j.Element;
19
20 import java.util.*;
21
22 /***
23 * Reads Models from XML, nodes and all if desired.
24 *
25 * @author Michael Rimov
26 * @author Larry Hamel
27 */
28 public class ModelXMLReader {
29
30 private static Logger slog = Logger.getLogger(ModelXMLReader.class);
31
32 /***
33 * Default constructor.
34 */
35 public ModelXMLReader() {
36 }
37
38
39 /***
40 * Parses an entity and its associated parts.
41 *
42 * @param origroot Element the element in an XML document to parse.
43 * @return NodeType the instantiated NodeType that we just parsed. [It
44 * is already added or updated to the database]
45 * @throws NumberFormatException upon integer parsing error.
46 * @throws DBException upon Database exception.
47 */
48 public NodeType parseEntityAndParts(Element origroot) throws
49 NumberFormatException, DBException {
50 Element entityElm = (Element) origroot.selectSingleNode("//" + PartAction.ENTITY);
51 NodeType entity = new NodeType();
52 entity.setEntityName(entityElm.attributeValue(NodeType.NODE_TYPE_NAME));
53
54
55 entity.find();
56 entity.setEntityDescription(entityElm.attributeValue(NodeType.NODE_TYPE_DESCRIP));
57 entity.setDisplayName(entityElm.attributeValue(NodeType.DISPLAY_TITLE));
58 entity.addOrUpdate();
59
60
61 Part[] oldparts = entity.getParts();
62 HashMap map = new HashMap(oldparts.length);
63
64 for (int i = 0; i < oldparts.length; i++) {
65 Part oldpart = oldparts[i];
66 map.put(oldpart.getPartType() + oldpart.getNodeRelation(),
67 oldpart);
68 }
69
70 boolean exists = false;
71
72
73 List allParts = origroot.selectNodes("//" + PartAction.PART);
74
75 for (Iterator iterator = allParts.iterator(); iterator.hasNext();) {
76 Element partElm = (Element) iterator.next();
77 String parttype = partElm.attributeValue(Part.PART_TYPE);
78 String noderel = StringUtil.notNull(partElm.attributeValue(Part.NODE_PART_RELATION_TYPE));
79
80
81 Part part = (Part) map.remove(parttype + noderel);
82
83 if (part == null) {
84 part = new Part();
85
86
87 part.setPartType(parttype);
88
89 if ((noderel != null) && (noderel.length() > 0)) {
90 part.setNodeRelation(noderel);
91 }
92
93 part.setParentType(entity.getEntityName());
94 exists = part.find();
95 } else {
96 exists = true;
97 }
98
99 part.setPartLabel(partElm.attributeValue(Part.PART_LABEL));
100 part.setPartDescrip(partElm.attributeValue(Part.PART_DESCRIP));
101
102 int num = Integer.parseInt(partElm.attributeValue(Part.PART_NUM));
103 part.setPartNum(num);
104 part.setPartCardinality(partElm.attributeValue(Part.CARDINALITY));
105
106 boolean isOwned = Boolean.valueOf(partElm.attributeValue(Part.PART_IS_ATTRIB)).booleanValue();
107 part.isOwnedAttribute(isOwned);
108
109 String handler = partElm.attributeValue(Part.SPECIAL_HANDLER);
110
111 if (handler != null) {
112 part.setSpecialHandler(handler);
113 part.getCustomHandler();
114 }
115
116 if (exists) {
117 part.update();
118 } else {
119 part.add();
120 }
121 }
122
123
124 for (Iterator iterator = map.values().iterator();
125 iterator.hasNext();) {
126 Part delpart = (Part) iterator.next();
127 delpart.delete();
128 }
129
130
131 PartsFactory.refreshCache(entity.getEntityName());
132 return entity;
133 }
134
135
136 /***
137 * Parses and creates the appropriate nodes as received in the import.
138 *
139 * @param isFindAllIds boolean
140 * @param isExternalRefRequired boolean
141 * @param root Element the root element we're parsing.
142 * @param request ExpressoRequest the ControllerRequset.
143 * @return Map keyed by 'ident' attribute. values == the actual node.
144 * @throws DBException upon add error.
145 * @throws Exception upon exception.
146 */
147 public Map parseImportXmlAndCreateNodes(boolean isFindAllIds,
148 boolean isExternalRefRequired,
149 Element root, ExpressoRequest request,
150 String xpathSelectionPrefix) throws DBException, Exception {
151 List list = root.selectNodes(xpathSelectionPrefix
152 + Node.RELATED);
153 List referenceNodes = root.selectNodes(xpathSelectionPrefix
154 + Node.REFERENCE);
155 Node rootnode = new Node(root);
156
157
158 List pickLists = new ArrayList();
159 org.dom4j.Node picklistRoot = root.selectSingleNode(xpathSelectionPrefix
160 + AddNodeAction.PICKLISTS_TAGNAME);
161 if (picklistRoot != null) {
162 pickLists = ((Element) picklistRoot).elements();
163 }
164
165 return createNodesFromXml(isFindAllIds,
166 isExternalRefRequired, list, referenceNodes, rootnode, request, root, pickLists);
167 }
168
169
170 public Map createNodesFromXml(boolean isFindAllIds,
171 boolean isExternalRefRequired,
172 List relatedNodes,
173 List referenceNodes,
174 Node rootnode,
175 ExpressoRequest request,
176 Element root,
177 List pickLists) throws Exception {
178
179
180
181 HashMap allNodesByXML_ID = new HashMap();
182
183
184 allNodesByXML_ID.put(rootnode.getAttribute(Node.IDENT_TAG_NAME), rootnode);
185
186
187
188
189 buildRelationships(allNodesByXML_ID, relatedNodes);
190
191
192
193
194
195 checkNodesIfFindById(isFindAllIds, allNodesByXML_ID, referenceNodes);
196
197 parseAndAddNodes(isExternalRefRequired, request, allNodesByXML_ID, rootnode, pickLists);
198
199 return allNodesByXML_ID;
200 }
201
202 public void parseAndAddNodes(boolean isExternalRefRequired,
203 ExpressoRequest request,
204 HashMap allNodesByXML_ID,
205 Node rootnode,
206 List pickListElements) throws Exception {
207 try {
208
209
210
211 for (Iterator iterator = allNodesByXML_ID.values().iterator(); iterator.hasNext();) {
212 Node anode = (Node) iterator.next();
213 anode.add();
214 }
215
216
217
218
219
220 int level = 0;
221 List remaining = new ArrayList();
222 remaining.add(rootnode);
223
224
225 while (!remaining.isEmpty()) {
226 List nextlevel = new ArrayList();
227
228 for (Iterator iterator = remaining.iterator();
229 iterator.hasNext();) {
230 Node anode = (Node) iterator.next();
231
232
233 anode.setAttribute(Node.INDENT, new Integer(level));
234
235
236 List more = anode.parseXMLRelations(allNodesByXML_ID,
237 isExternalRefRequired);
238 nextlevel.addAll(more);
239 }
240
241 remaining.clear();
242 remaining = nextlevel;
243 level++;
244 }
245
246
247
248
249
250
251
252
253
254
255
256 Map translationMap = new HashMap();
257 for (Iterator iterator = pickListElements.iterator(); iterator.hasNext();) {
258 Element element = (Element) iterator.next();
259 Part part = Part.getPartFromXMLName(element.getName());
260 if (part == null) {
261 slog.error("Cannot find part for XML name: " + element.getName());
262 continue;
263 }
264
265
266 List existing = part.getPickList();
267 Map existingMap = new HashMap(existing.size());
268 for (Iterator iterator2 = existing.iterator(); iterator2.hasNext();) {
269 PickList item = (PickList) iterator2.next();
270
271
272 existingMap.put(item.getDisplayString(), item);
273 }
274
275
276 List elementItems = element.elements();
277 for (Iterator iterator1 = elementItems.iterator(); iterator1.hasNext();) {
278 Element anElmItem = (Element) iterator1.next();
279 String oldId = anElmItem.attributeValue(PickList.LIST_ID);
280 String descrip = anElmItem.attributeValue(PickList.DISPLAY_IN_PICKLIST);
281 String order = anElmItem.attributeValue(PickList.ORDER_NUM);
282
283
284 Object existingItem = existingMap.get(descrip);
285 if (existingItem != null) {
286 translationMap.put(oldId, existingItem);
287 } else {
288
289 PickList item = new PickList(part.getParentType(), part.getPartType());
290 item.setDisplayValue(descrip);
291 item.setOrderNum(Integer.parseInt(order));
292 item.add();
293 translationMap.put(oldId, item);
294 }
295 }
296
297 }
298
299
300
301 for (Iterator iterator = allNodesByXML_ID.values().iterator();
302 iterator.hasNext();) {
303 Node anode = (Node) iterator.next();
304 anode.parseXMLAttributes(allNodesByXML_ID, request, translationMap);
305 }
306 } catch (Exception e) {
307
308 for (Iterator iterator = allNodesByXML_ID.values().iterator();
309 iterator.hasNext();) {
310 Node anode = (Node) iterator.next();
311
312
313
314
315 if (!anode.isFieldNull(Node.NODE_ID) && anode.find()) {
316 anode.delete();
317
318 }
319 }
320
321 throw e;
322 }
323 }
324
325 private void checkNodesIfFindById(boolean isFindAllIds,
326 HashMap allNodesByXML_ID, List list) throws DBException {
327 for (Iterator iterator = list.iterator(); iterator.hasNext();) {
328 Element referElem = (Element) iterator.next();
329 String refid = referElem.attributeValue(Node.REF_ID);
330
331 if (allNodesByXML_ID.get(refid) == null && isFindAllIds) {
332
333 Node searchnode = new Node(refid);
334
335 if (!searchnode.find()) {
336 throw new DBException("Cannot find referenced node ID: " + refid +
337 " neither inside XML nor in this system.");
338 }
339 }
340 }
341 }
342
343 private void buildRelationships(HashMap allNodesByXML_ID, List list)
344 throws DBException {
345 Logger log = Logger.getLogger(ModelXMLReader.class);
346 for (Iterator iterator = list.iterator(); iterator.hasNext();) {
347 Element relElem = (Element) iterator.next();
348 List children = relElem.elements();
349
350 for (Iterator childiter = children.iterator(); childiter.hasNext();) {
351 Element childElem = (Element) childiter.next();
352
353 if (Node.REFERENCE.equals(childElem.getName())) {
354
355 if (log.isDebugEnabled()) {
356 log.debug("runDoImportNodeState:" +
357 "skip for first pass; see next phase");
358 }
359 } else {
360
361
362 Node relnode = new Node(childElem);
363 allNodesByXML_ID.put(relnode.getAttribute(Node.
364 IDENT_TAG_NAME), relnode);
365 }
366 }
367 }
368 }
369 }