1 19 23 24 package org.netbeans.modules.xml.xam.dom; 25 26 import java.util.ArrayList ; 27 import java.util.Collections ; 28 import java.util.HashMap ; 29 import java.util.HashSet ; 30 import java.util.List ; 31 import java.util.Map ; 32 import org.w3c.dom.Attr ; 33 import org.w3c.dom.Element ; 34 import org.w3c.dom.Node ; 35 import org.w3c.dom.Text ; 36 37 public class SyncUnit { 38 private final DocumentComponent target; 39 private List <ChangeInfo> changes = new ArrayList <ChangeInfo>(); 40 private List <DocumentComponent> toRemove = new ArrayList <DocumentComponent>(); 41 private List <DocumentComponent> toAdd = new ArrayList <DocumentComponent>(); 42 private Map <String , Attr > removedAttributes = new HashMap <String , Attr >(); 43 private Map <String , Attr > addedAttributes = new HashMap <String , Attr >(); 44 private boolean componentChanged; 45 private boolean hasTextContentChanges = false; 46 47 public SyncUnit(DocumentComponent syncTarget) { 48 if (syncTarget == null) { 49 throw new IllegalArgumentException ("Null syncTarget"); 50 } 51 target = syncTarget; 52 } 53 54 public void addChange(ChangeInfo change) { 55 if (! target.referencesSameNode(change.getParent())) { 56 throw new IllegalArgumentException ("ChangeInfo does not match target id"); 57 } 58 changes.add(change); 59 if (change.getChangedNode() instanceof Attr ) { 60 Attr attr = (Attr ) change.getChangedNode(); 61 if (change.isAdded()) { 62 addToAddedAttributes(attr); 63 } else { 64 addToRemovedAttributes(attr); 65 } 66 } else { 67 Node actualChanged = change.getActualChangedNode(); 68 if (! (actualChanged instanceof Attribute || actualChanged instanceof Element )) { 69 if (actualChanged.getNodeType() != Node.TEXT_NODE || 71 ((Text )actualChanged).getNodeValue().trim().length() != 0) { 72 setHasTextContentChanges(true); 73 } 74 } 75 } 76 } 77 78 public List <ChangeInfo> getChanges() { return changes; } 79 public DocumentComponent getTarget() { return target; } 80 public List <DocumentComponent> getToRemoveList() { return toRemove; } 81 public void addToRemoveList(DocumentComponent c) { 82 if (c == null) { 83 throw new IllegalArgumentException ("Null component"); 84 } 85 toRemove.add(c); 86 } 87 public List <DocumentComponent> getToAddList() { return toAdd; } 88 public void addToAddList(DocumentComponent c) { 89 if (c == null) { 90 throw new IllegalArgumentException ("Null component"); 91 } 92 toAdd.add(c); 93 } 94 public void setComponentChanged(boolean v) { componentChanged = v; } 95 public boolean isComponentChanged() { return componentChanged; } 96 public void addToAddedAttributes(Attr attr) { 97 addedAttributes.put(attr.getName(), attr); 98 } 99 public Map <String ,Attr > getAddedAttributes() { 100 return addedAttributes; 101 } 102 103 public Map <String ,Attr > getRemovedAttributes() { 104 return removedAttributes; 105 } 106 107 public void addToRemovedAttributes(Attr attr) { 108 removedAttributes.put(attr.getName(), attr); 109 } 110 111 public void merge(SyncUnit su) { 112 if (target != su.getTarget()) { 113 throw new IllegalArgumentException ("Invalid sync unit for merge"); 114 } 115 changes.addAll(su.getChanges()); 116 for (String name : su.getRemovedAttributes().keySet()) { 117 addToRemovedAttributes(su.getRemovedAttributes().get(name)); 118 } 119 for (String name : su.getAddedAttributes().keySet()) { 120 addToAddedAttributes(su.getAddedAttributes().get(name)); 121 } 122 123 if (! su.getToAddList().isEmpty()) { 124 HashSet <Element > addSet = new HashSet <Element >(); 125 for (DocumentComponent component : toAdd) { 126 addSet.add(component.getPeer()); 127 } 128 for (DocumentComponent component : su.getToAddList()) { 129 if (! addSet.contains(component.getPeer())) { 130 toAdd.add(component); 131 } 132 } 133 } 134 135 for (DocumentComponent component : su.getToRemoveList()) { 136 if (! toRemove.contains(component)) { 137 toRemove.add(component); 138 } 139 } 140 } 141 142 public void updateTargetReference() { 143 AbstractDocumentComponent component = (AbstractDocumentComponent) target; 144 if (component != null) { 145 component.updateReference(getParentToRootPath()); 146 } 147 } 148 149 public ChangeInfo getLastChange() { 150 if (changes.size() > 0) { 151 return changes.get(changes.size()-1); 152 } else { 153 return null; 154 } 155 } 156 157 public List <Element > getParentToRootPath() { 158 if (getLastChange() == null) { 159 return Collections.emptyList(); 160 } else { 161 return getLastChange().getParentToRootPath(); 162 } 163 } 164 165 public boolean hasTextContentChanges() { 166 return hasTextContentChanges; 167 } 168 169 public void setHasTextContentChanges(boolean val) { 170 hasTextContentChanges = val; 171 } 172 173 public boolean hasWhitespaceChangeOnly() { 174 for (ChangeInfo ci : getChanges()) { 175 if (ci.isDomainElement()) { 176 continue; 177 } 178 Node n = ci.getActualChangedNode(); 179 if (n.getNodeType() == Node.TEXT_NODE) { 180 String text = ((Text )n).getNodeValue(); 181 if (text != null && text.trim().length() > 0) { 182 return false; 183 } 184 } else if (n.getNodeType() == Node.ATTRIBUTE_NODE) { 185 String name = ((Attr ) n).getName(); 186 Attr removed = getRemovedAttributes().get(name); 187 if (removed == null) { 188 return false; 189 } 190 Attr added = getAddedAttributes().get(name); 191 if (added == null) { 192 return false; 193 } 194 if (removed.getValue() == null || 195 ! removed.getValue().equals(added.getValue())) { 196 return false; 197 } 198 } else { 199 return false; 201 } 202 } 203 return true; 204 } 205 } 206 | Popular Tags |