001: /*
002: ItsNat Java Web Application Framework
003: Copyright (C) 2007 Innowhere Software Services S.L., Spanish Company
004: Author: Jose Maria Arranz Santamaria
005:
006: This program is free software: you can redistribute it and/or modify
007: it under the terms of the GNU Affero General Public License as published by
008: the Free Software Foundation, either version 3 of the License, or
009: (at your option) any later version. See the GNU Affero General Public
010: License for more details. See the copy of the GNU Affero General Public License
011: included in this program. If not, see <http://www.gnu.org/licenses/>.
012: */
013:
014: package org.itsnat.impl.core.domutil;
015:
016: import java.util.ArrayList;
017: import org.itsnat.core.domutil.ItsNatTreeWalker;
018: import org.itsnat.impl.core.ItsNatDocumentImpl;
019: import org.w3c.dom.Element;
020:
021: /**
022: * Manda sobre el DOM, NO debería modificarse el DOM directamente sin la lista
023: * pues ésta quedaría desincronizada. Es más rápida que la versión "slave"
024: *
025: * @author jmarranz
026: */
027: public class ElementListFreeMasterImpl extends ElementListFreeImpl {
028: protected ArrayList elements = new ArrayList();
029:
030: /**
031: * Creates a new instance of ElementListDOMMasterImpl
032: */
033: public ElementListFreeMasterImpl(Element parentElement,
034: ItsNatDocumentImpl itsNatDoc) {
035: super (parentElement, itsNatDoc);
036:
037: initialSync();
038: }
039:
040: public boolean isMaster() {
041: return true;
042: }
043:
044: public void initialSync() {
045: elements.clear(); // Por si acaso
046:
047: Element child = ItsNatTreeWalker
048: .getFirstChildElement(parentElement);
049: while (child != null) {
050: addListElementInfo(child);
051:
052: child = ItsNatTreeWalker.getNextSiblingElement(child);
053: }
054:
055: // A partir de ahora NO debería modificarse el DOM directamente,
056: // usar esta lista
057: }
058:
059: public ListElementInfoImpl getListElementInfo(int index,
060: Element elem) {
061: return getListElementInfo(index);
062: }
063:
064: public ListElementInfoImpl getListElementInfo(int index) {
065: return (ListElementInfoMasterImpl) elements.get(index);
066: }
067:
068: public ListElementInfoImpl addListElementInfo(Element elem) {
069: ListElementInfoMasterImpl elemInfo = new ListElementInfoMasterImpl(
070: elements.size(), elem, this );
071: elements.add(elemInfo);
072: return elemInfo;
073: }
074:
075: public ListElementInfoImpl insertListElementInfo(int index,
076: Element elem) {
077: ListElementInfoMasterImpl elemInfo = new ListElementInfoMasterImpl(
078: index, elem, this );
079: elements.add(index, elemInfo);
080: for (int i = index + 1; i < elements.size(); i++) {
081: ListElementInfoMasterImpl currElemInfo = (ListElementInfoMasterImpl) elements
082: .get(i);
083: currElemInfo.setIndex(currElemInfo.getIndex() + 1);
084: }
085: return elemInfo;
086: }
087:
088: public void removeListElementInfo(int index) {
089: elements.remove(index);
090: for (int i = index; i < elements.size(); i++) {
091: ListElementInfoMasterImpl currElemInfo = (ListElementInfoMasterImpl) elements
092: .get(i);
093: currElemInfo.setIndex(currElemInfo.getIndex() - 1);
094: }
095: }
096:
097: public void removeListElementInfoRange(int fromIndex, int toIndex) {
098: int count = toIndex - fromIndex + 1;
099: for (int i = 1; i <= count; i++)
100: elements.remove(fromIndex);
101:
102: for (int i = fromIndex; i < elements.size(); i++) {
103: ListElementInfoMasterImpl currElemInfo = (ListElementInfoMasterImpl) elements
104: .get(i);
105: currElemInfo.setIndex(currElemInfo.getIndex() - count);
106: }
107: }
108:
109: public ListElementInfoImpl getListElementInfo(Element elem) {
110: if (elem == null)
111: return null;
112:
113: int len = getLength();
114: for (int i = 0; i < len; i++) {
115: ListElementInfoImpl elemInfo = getListElementInfo(i);
116: Element currElem = elemInfo.getElement();
117: if (currElem == elem)
118: return elemInfo;
119: }
120: return null; // El nodo no forma parte de la lista
121: }
122:
123: public boolean isEmpty() {
124: return elements.isEmpty();
125: }
126:
127: public int getLength() {
128: return elements.size();
129: }
130:
131: public boolean isOutOfRange(int index) {
132: return (index < 0) || (index >= elements.size());
133: }
134:
135: public Element getElementAt(int index) {
136: if (isOutOfRange(index))
137: return null;
138:
139: ListElementInfoImpl elemInfo = getListElementInfo(index);
140: return elemInfo.getElement();
141: }
142:
143: public Element getFirstElement() {
144: return getElementAt(0);
145: }
146:
147: public Element getLastElement() {
148: return getElementAt(getLength() - 1);
149: }
150:
151: public int indexOfElement(Element node) {
152: if (node == null)
153: return -1;
154:
155: int len = getLength();
156: for (int i = 0; i < len; i++) {
157: Element child = getElementAt(i);
158: if (child == node)
159: return i;
160: }
161: return -1; // El nodo no forma parte de la lista
162: }
163:
164: public int lastIndexOfElement(Element node) {
165: if (node == null)
166: return -1;
167:
168: int len = getLength();
169: for (int i = len - 1; i >= 0; i--) {
170: Element child = getElementAt(i);
171: if (child == node)
172: return i;
173: }
174: return -1; // El nodo no forma parte de la lista
175: }
176:
177: public void fillElements(Element[] elemList) {
178: for (int i = 0; i < elemList.length; i++) {
179: Element elem = getElementAt(i);
180: elemList[i] = elem;
181: }
182: }
183:
184: protected void addElementInternal(Element newNode) {
185: super .addElementInternal(newNode);
186:
187: addListElementInfo(newNode);
188: }
189:
190: protected void insertBeforeElementInternal(int index,
191: Element newNode, Element refNode) {
192: super .insertBeforeElementInternal(index, newNode, refNode); // Si refNode es nulo se inserta al final
193:
194: insertListElementInfo(index, newNode);
195: }
196:
197: protected void insertElementAtInternal(int index, Element newNode) {
198: super .insertElementAtInternal(index, newNode);
199:
200: insertListElementInfo(index, newNode);
201: }
202:
203: protected Element setElementAtInternal(int index, Element currNode,
204: Element newNode) {
205: Element res = super .setElementAtInternal(index, currNode,
206: newNode);
207:
208: updateListElementInfo(index, newNode);
209:
210: return res;
211: }
212:
213: public ListElementInfoImpl updateListElementInfo(int index,
214: Element elem) {
215: ListElementInfoMasterImpl elemInfo = (ListElementInfoMasterImpl) getListElementInfo(index);
216: elemInfo.setElement(elem);
217: return elemInfo;
218: }
219:
220: public void removeElement(int index, Element node) {
221: super .removeElement(index, node);
222:
223: removeListElementInfo(index);
224: }
225:
226: public Element removeElementAt(int index) {
227: Element child = super .removeElementAt(index);
228: if (child == null)
229: return null; // No existe
230:
231: removeListElementInfo(index);
232:
233: return child;
234: }
235:
236: public void removeElementRange(int fromIndex, int toIndex) {
237: super .removeElementRange(fromIndex, toIndex);
238:
239: removeListElementInfoRange(fromIndex, toIndex);
240: }
241:
242: public Element getNextSiblingElement(int index, Element ref) {
243: return getElementAt(index + 1);
244: }
245:
246: public Element getPreviousSiblingElement(int index, Element ref) {
247: return getElementAt(index - 1);
248: }
249: }
|