01: package com.icesoft.faces.context;
02:
03: import com.icesoft.faces.util.DOMUtils;
04: import com.icesoft.faces.webapp.command.CommandQueue;
05: import com.icesoft.faces.webapp.command.UpdateElements;
06: import org.w3c.dom.Document;
07: import org.w3c.dom.Element;
08: import org.w3c.dom.Node;
09:
10: import java.io.IOException;
11: import java.util.ArrayList;
12:
13: public class PushModeSerializer implements DOMSerializer {
14: private Document oldDocument;
15: private CommandQueue commandQueue;
16:
17: public PushModeSerializer(Document currentDocument,
18: CommandQueue commandQueue) {
19: this .oldDocument = currentDocument;
20: this .commandQueue = commandQueue;
21: }
22:
23: public void serialize(Document document) throws IOException {
24: Node[] changed = DOMUtils.domDiff(oldDocument, document);
25: for (int i = 0; i < changed.length; i++) {
26: Element changeRoot = DOMUtils
27: .ascendToNodeWithID(changed[i]);
28: for (int j = 0; j < i; j++) {
29: if (changed[j] == null)
30: continue;
31: // If new is already in, then discard new
32: if (changeRoot == changed[j]) {
33: changeRoot = null;
34: break;
35: }
36: // If new is parent of old, then replace old with new
37: else if (isAncestor(changeRoot, changed[j])) {
38: changed[j] = null;
39: }
40: // If new is a child of old, then discard new
41: else if (isAncestor(changed[j], changeRoot)) {
42: changeRoot = null;
43: break;
44: }
45: }
46: changed[i] = changeRoot;
47: }
48:
49: ArrayList elementList = new ArrayList(changed.length);
50: for (int i = 0; i < changed.length; i++) {
51: Element element = (Element) changed[i];
52: if (null != element) {
53: elementList.add(element);
54: }
55: }
56: if (!elementList.isEmpty()) {
57: Element[] elements = (Element[]) elementList
58: .toArray(new Element[elementList.size()]);
59: commandQueue.put(new UpdateElements(elements));
60: }
61:
62: oldDocument = document;
63: }
64:
65: private boolean isAncestor(Node test, Node child) {
66: if (test == null || child == null)
67: return false;
68: if (!test.hasChildNodes()) {
69: return false;
70: }
71: Node parent = child;
72: while ((parent = parent.getParentNode()) != null) {
73: if (test.equals(parent)) {
74: return true;
75: }
76: }
77: return false;
78: }
79: }
|