0001: /*
0002: ItsNat Java Web Application Framework
0003: Copyright (C) 2007 Innowhere Software Services S.L., Spanish Company
0004: Author: Jose Maria Arranz Santamaria
0005:
0006: This program is free software: you can redistribute it and/or modify
0007: it under the terms of the GNU Affero General Public License as published by
0008: the Free Software Foundation, either version 3 of the License, or
0009: (at your option) any later version. See the GNU Affero General Public
0010: License for more details. See the copy of the GNU Affero General Public License
0011: included in this program. If not, see <http://www.gnu.org/licenses/>.
0012: */
0013:
0014: package org.itsnat.impl.core;
0015:
0016: import java.io.IOException;
0017: import org.itsnat.core.ItsNatException;
0018: import org.itsnat.core.ItsNatDocument;
0019: import org.itsnat.core.ItsNatSession;
0020: import org.itsnat.core.script.ScriptUtil;
0021: import org.itsnat.core.DocumentTemplate;
0022: import org.itsnat.core.ItsNatTimer;
0023: import org.itsnat.impl.core.client.ClientDocumentOwnerImpl;
0024: import org.itsnat.impl.core.listener.dom.DOMEventListenerRegistryImpl;
0025: import org.itsnat.impl.core.listener.dom.DOMEventListenerWrapperImpl;
0026: import org.itsnat.impl.core.js.JScriptUtilImpl;
0027: import org.itsnat.impl.core.util.UserDataImpl;
0028: import org.itsnat.core.domutil.ElementRenderer;
0029: import org.itsnat.core.domutil.ElementList;
0030: import org.itsnat.core.domutil.ElementTable;
0031: import org.itsnat.core.domutil.ElementTreeNode;
0032: import org.itsnat.impl.core.domutil.ElementListImpl;
0033: import org.itsnat.impl.core.domutil.ElementTreeNodeNormalImpl;
0034: import org.itsnat.impl.core.domutil.ElementRendererDefaultImpl;
0035: import java.io.Writer;
0036: import java.text.DateFormat;
0037: import java.text.NumberFormat;
0038: import java.util.Date;
0039: import java.util.Enumeration;
0040: import java.util.HashMap;
0041: import java.util.HashSet;
0042: import java.util.Hashtable;
0043: import java.util.Iterator;
0044: import java.util.LinkedList;
0045: import java.util.Map;
0046: import java.util.Set;
0047: import java.util.WeakHashMap;
0048: import org.itsnat.comp.ItsNatComponentManager;
0049: import org.itsnat.core.ClientDocument;
0050: import org.itsnat.core.ItsNatNode;
0051: import org.itsnat.core.ItsNatServletRequest;
0052: import org.itsnat.core.ItsNatServletResponse;
0053: import org.itsnat.core.ItsNatVariableResolver;
0054: import org.itsnat.core.domutil.ElementLabel;
0055: import org.itsnat.core.domutil.ElementLabelRenderer;
0056: import org.itsnat.core.event.CodeToSendListener;
0057: import org.itsnat.core.event.RemoteControlEventListener;
0058: import org.itsnat.core.domutil.ElementListRenderer;
0059: import org.itsnat.core.domutil.ElementTableRenderer;
0060: import org.itsnat.core.domutil.ElementTreeNodeRenderer;
0061: import org.itsnat.core.domutil.ElementListStructure;
0062: import org.itsnat.core.domutil.ElementTableStructure;
0063: import org.itsnat.core.domutil.ElementTree;
0064: import org.itsnat.core.domutil.ElementTreeNodeStructure;
0065: import org.itsnat.impl.comp.ItsNatComponentManagerImpl;
0066: import org.itsnat.impl.core.dom.ItsNatNodeRegistry;
0067: import org.itsnat.impl.core.listener.AsyncTaskEventListenerWrapperImpl;
0068: import org.itsnat.impl.core.listener.AsyncTaskRegistry;
0069: import org.itsnat.impl.core.listener.domext.ContinueEventListenerWrapperImpl;
0070: import org.itsnat.impl.core.event.client2serv.CodeToSendEventImpl;
0071: import org.itsnat.impl.core.listener.domext.UserEventListenerRegistryImpl;
0072: import org.itsnat.impl.core.listener.domext.UserEventListenerWrapperImpl;
0073: import org.itsnat.impl.core.listener.MutationEventListenerImpl;
0074: import org.itsnat.core.event.NodeMutationTransport;
0075: import org.itsnat.core.event.ParamTransport;
0076: import org.itsnat.core.domutil.ElementListFree;
0077: import org.itsnat.core.domutil.ElementTableFree;
0078: import org.itsnat.core.domutil.ElementTreeNodeList;
0079: import org.itsnat.core.event.ItsNatServletRequestListener;
0080: import org.itsnat.impl.core.client.ClientDocumentInvitedRemoteCtrlImpl;
0081: import org.itsnat.impl.core.dom.render.DOMRenderImpl;
0082: import org.itsnat.impl.core.domutil.ElementLabelImpl;
0083: import org.itsnat.impl.core.domutil.ElementLabelRendererDefaultImpl;
0084: import org.itsnat.impl.core.event.client2serv.RemoteControlEventImpl;
0085: import org.itsnat.impl.core.event.fromserv.dom.ServerDOMEventImpl;
0086: import org.itsnat.impl.core.http.ItsNatImpl;
0087: import org.itsnat.impl.core.js.domrender.node.JSNodeRenderImpl;
0088: import org.itsnat.impl.core.domutil.ElementListRendererDefaultImpl;
0089: import org.itsnat.impl.core.domutil.ElementTableRendererDefaultImpl;
0090: import org.itsnat.impl.core.domutil.ElementTreeNodeRendererDefaultImpl;
0091: import org.itsnat.impl.core.domutil.ElementListFreeMasterImpl;
0092: import org.itsnat.impl.core.domutil.ElementListFreeSlaveDefaultImpl;
0093: import org.itsnat.impl.core.domutil.ElementListStructureDefaultImpl;
0094: import org.itsnat.impl.core.domutil.ElementTableStructureDefaultImpl;
0095: import org.itsnat.impl.core.domutil.HTMLCollectionTableCellElementListImpl;
0096: import org.itsnat.impl.core.domutil.HTMLCollectionTableRowElementListImpl;
0097: import org.itsnat.impl.core.domutil.ElementTreeNodeStructureDefaultImpl;
0098: import org.itsnat.impl.core.domutil.ElementTableFreeMasterImpl;
0099: import org.itsnat.impl.core.domutil.ElementTableFreeSlaveImpl;
0100: import org.itsnat.impl.core.domutil.ElementTableImpl;
0101: import org.itsnat.impl.core.domutil.ElementTreeImpl;
0102: import org.itsnat.impl.core.domutil.ElementTreeNodeListImpl;
0103: import org.itsnat.impl.core.domutil.ElementTreeNormalNodeListRootImpl;
0104: import org.itsnat.impl.core.domutil.ElementTreeTableNodeListRootImpl;
0105: import org.itsnat.impl.core.domutil.ElementTreeVersatileImpl;
0106: import org.itsnat.impl.core.domutil.ElementTreeVersatileRootlessImpl;
0107: import org.itsnat.impl.core.domutil.ElementTreeVersatileWithRootImpl;
0108: import org.itsnat.impl.core.domutil.HTMLCollectionSelectOptionsElementListImpl;
0109: import org.itsnat.impl.core.event.fromserv.ServerDOMBasedEventImpl;
0110: import org.itsnat.impl.core.listener.domext.ContinueEventListenerRegistryImpl;
0111: import org.itsnat.impl.core.listener.domext.DOMExtensionEventListenerWrapperImpl;
0112: import org.itsnat.impl.core.listener.domext.TimerEventListenerRegistryImpl;
0113: import org.itsnat.impl.core.listener.domext.TimerEventListenerWrapperImpl;
0114: import org.w3c.dom.Attr;
0115: import org.w3c.dom.CDATASection;
0116: import org.w3c.dom.Comment;
0117: import org.w3c.dom.DOMConfiguration;
0118: import org.w3c.dom.DOMException;
0119: import org.w3c.dom.DOMImplementation;
0120: import org.w3c.dom.Document;
0121: import org.w3c.dom.DocumentFragment;
0122: import org.w3c.dom.DocumentType;
0123: import org.w3c.dom.Element;
0124: import org.w3c.dom.EntityReference;
0125: import org.w3c.dom.NamedNodeMap;
0126: import org.w3c.dom.Node;
0127: import org.w3c.dom.NodeList;
0128: import org.w3c.dom.ProcessingInstruction;
0129: import org.w3c.dom.Text;
0130: import org.w3c.dom.UserDataHandler;
0131: import org.w3c.dom.events.DocumentEvent;
0132: import org.w3c.dom.events.Event;
0133: import org.w3c.dom.events.EventException;
0134: import org.w3c.dom.events.EventListener;
0135: import org.w3c.dom.events.EventTarget;
0136: import org.w3c.dom.html.HTMLSelectElement;
0137: import org.w3c.dom.html.HTMLTableRowElement;
0138: import org.w3c.dom.html.HTMLTableSectionElement;
0139: import org.w3c.dom.views.AbstractView;
0140: import org.w3c.dom.views.DocumentView;
0141:
0142: /**
0143: *
0144: * @author jmarranz
0145: */
0146: public abstract class ItsNatDocumentImpl extends MarkupContainerImpl
0147: implements ItsNatDocument, Document, DocumentEvent,
0148: DocumentView, EventTarget {
0149: protected DocumentTemplateVersionImpl docTemplate; // Apuntamos al document loader usado pues si cambia el archivo cambia el loader por defecto en el DocumentTemplateImpl y perderíamos el caché al serializar
0150: protected Document doc;
0151: protected boolean loading = false;
0152: protected DOMEventListenerRegistryImpl domListenerRegistry;
0153: protected UserEventListenerRegistryImpl userListenerRegistry;
0154: protected ContinueEventListenerRegistryImpl continueListenerRegistry;
0155: protected TimerEventListenerRegistryImpl timerListenerRegistry;
0156: protected ItsNatNodeRegistry itsNatNodeRegistry;
0157: protected boolean enabledSendCode = true;
0158: protected ItsNatServletRequestImpl currentRequest;
0159: protected AbstractViewImpl view;
0160: protected UserDataImpl userData;
0161: protected ClientDocumentOwnerImpl clientDocOwner;
0162: protected WeakHashMap clientDocInvitedRemCtrlMap;
0163: protected boolean invalid = false;
0164: protected AsyncTaskRegistry asyncTaskRegistry;
0165: protected int syncMode;
0166: protected long ajaxTimeout;
0167: protected String scriptLoadCode;
0168: protected JScriptUtilImpl jsGenerator;
0169: protected Hashtable attributes;
0170: protected ItsNatComponentManagerImpl componentMgr;
0171: protected NodeCache nodeCache;
0172: protected Map artifacts;
0173: protected DateFormat dateFormat;
0174: protected NumberFormat numberFormat;
0175: protected CodeToSendListenersImpl codeToSendListeners;
0176: protected long evtDispMaxWait;
0177: protected MutationEventListenerImpl mutationListener;
0178: protected LinkedList remControlListeners;
0179: protected boolean usePatternMarkupToRender = true;
0180: protected LinkedList referrerRequestListeners;
0181: protected Set evtDispThreadSet;
0182:
0183: /**
0184: * Creates a new instance of ItsNatDocumentImpl
0185: */
0186: public ItsNatDocumentImpl(Document doc,
0187: DocumentTemplateVersionImpl docTemplate,
0188: ItsNatSessionImpl ownerSession) {
0189: this .id = ownerSession.generateUniqueId();
0190: this .doc = doc;
0191: this .docTemplate = docTemplate;
0192: // ownerSession es la sesión del propietario del documento no de los observadores
0193: this .clientDocOwner = new ClientDocumentOwnerImpl(ownerSession,
0194: this );
0195:
0196: this .syncMode = docTemplate.getDefaultSyncMode();
0197: this .ajaxTimeout = docTemplate.getAJAXTimeout();
0198:
0199: this .dateFormat = docTemplate.getDefaultDateFormat();
0200: this .numberFormat = docTemplate.getDefaultNumberFormat();
0201: this .evtDispMaxWait = docTemplate.getEventDispatcherMaxWait();
0202: this .usePatternMarkupToRender = docTemplate
0203: .isUsePatternMarkupToRender();
0204:
0205: addMarkupTemplateVersionIfCaching(docTemplate); // Además podrán añadirse los includes que haga el usuario explícitamente en cualquier momento
0206:
0207: this .mutationListener = new MutationEventListenerImpl(this );
0208: }
0209:
0210: public boolean isUniqueIdGeneratorSync() {
0211: return false;
0212: }
0213:
0214: public abstract boolean isHTMLorXHTML();
0215:
0216: public boolean isXHTML() {
0217: return getDocumentTemplateVersion().isXHTML();
0218: }
0219:
0220: public boolean isHTML() {
0221: return getDocumentTemplateVersion().isHTML();
0222: }
0223:
0224: public boolean isMSIE() {
0225: return getItsNatSessionImpl().isMSIE();
0226: }
0227:
0228: public boolean isDebugMode() {
0229: return getDocumentTemplateVersion().isDebugMode();
0230: }
0231:
0232: public int getClientErrorMode() {
0233: return getDocumentTemplateVersion().getClientErrorMode();
0234: }
0235:
0236: public boolean canSendMutationJSCode() {
0237: boolean loading = isLoading();
0238: return !loading || (loading && !isFastLoadMode());
0239: }
0240:
0241: public boolean isFastLoadMode() {
0242: return getDocumentTemplateVersion().isFastLoadMode();
0243: }
0244:
0245: public boolean isAutoBuildComponents() {
0246: return getDocumentTemplateVersion().isAutoBuildComponents();
0247: }
0248:
0249: public int getDefaultSyncMode() {
0250: return syncMode;
0251: }
0252:
0253: public void setDefaultSyncMode(int syncMode) {
0254: ItsNatServletConfigImpl.checkSyncMode(syncMode);
0255: this .syncMode = syncMode;
0256: }
0257:
0258: public long getAJAXTimeout() {
0259: return ajaxTimeout;
0260: }
0261:
0262: public void setAJAXTimeout(long timeout) {
0263: this .ajaxTimeout = timeout;
0264: }
0265:
0266: public DocumentTemplate getDocumentTemplate() {
0267: return getDocumentTemplateImpl();
0268: }
0269:
0270: public DocumentTemplateImpl getDocumentTemplateImpl() {
0271: return getDocumentTemplateVersion().getDocumentTemplate();
0272: }
0273:
0274: public String getId() {
0275: return id;
0276: }
0277:
0278: public Document getDocument() {
0279: return doc;
0280: }
0281:
0282: public Node getNode() {
0283: return doc;
0284: }
0285:
0286: public Document getOriginalDocument() {
0287: return doc;
0288: }
0289:
0290: public ItsNatSession getItsNatSession() {
0291: return getItsNatSessionImpl();
0292: }
0293:
0294: public ItsNatSessionImpl getItsNatSessionImpl() {
0295: return clientDocOwner.getItsNatSessionImpl();
0296: }
0297:
0298: public DocumentTemplateVersionImpl getDocumentTemplateVersion() {
0299: return docTemplate;
0300: }
0301:
0302: public ItsNatNodeRegistry getItsNatNodeRegistry() {
0303: if (itsNatNodeRegistry == null)
0304: this .itsNatNodeRegistry = new ItsNatNodeRegistry(this );
0305: return itsNatNodeRegistry;
0306: }
0307:
0308: public ItsNatTimer createItsNatTimer() {
0309: return new ItsNatTimerImpl(this ); // No hace falta que el programador lo "sujete" pues si registra alguna task el timer handler es el que se registra en el documento.
0310: }
0311:
0312: public AbstractView getDefaultView() {
0313: if (view == null)
0314: this .view = new AbstractViewImpl(this ); // Para ahorrar memoria si no se usa
0315: return view;
0316: }
0317:
0318: public boolean isLoading() {
0319: return loading;
0320: }
0321:
0322: public void startLoading() {
0323: this .loading = true;
0324:
0325: if (isAutoBuildComponents()) {
0326: ItsNatComponentManagerImpl compMgr = getItsNatComponentManagerImpl();
0327: compMgr.initAutoBuildComponents();
0328: }
0329: }
0330:
0331: public void endLoading() {
0332: this .loading = false;
0333: }
0334:
0335: public void serializeDocument(Writer out) {
0336: String text = serializeDocument();
0337: try {
0338: out.write(text);
0339: } catch (IOException io) {
0340: throw new ItsNatException(io);
0341: }
0342: }
0343:
0344: public String serializeDocument() {
0345: DOMRenderImpl docRender = getDocumentTemplateVersion()
0346: .getDocumentRender();
0347: return serializeDocument(getDocument(), docRender);
0348: }
0349:
0350: public void addEventListener(EventTarget nodeTarget, String type,
0351: EventListener listener, boolean useCapture) {
0352: int syncMode = getDefaultSyncMode();
0353: long ajaxTimeout = getAJAXTimeout();
0354: addEventListener(nodeTarget, type, listener, useCapture,
0355: syncMode, null, null, ajaxTimeout);
0356: }
0357:
0358: public void addEventListener(EventTarget nodeTarget, String type,
0359: EventListener listener, boolean useCapture, int syncMode) {
0360: long ajaxTimeout = getAJAXTimeout();
0361: addEventListener(nodeTarget, type, listener, useCapture,
0362: syncMode, null, null, ajaxTimeout);
0363: }
0364:
0365: public void addEventListener(EventTarget nodeTarget, String type,
0366: EventListener listener, boolean useCapture,
0367: ParamTransport extraParam) {
0368: ParamTransport[] extraParams = new ParamTransport[] { extraParam };
0369: addEventListener(nodeTarget, type, listener, useCapture,
0370: extraParams);
0371: }
0372:
0373: public void addEventListener(EventTarget nodeTarget, String type,
0374: EventListener listener, boolean useCapture,
0375: ParamTransport[] extraParams) {
0376: int syncMode = getDefaultSyncMode();
0377: long ajaxTimeout = getAJAXTimeout();
0378: addEventListener(nodeTarget, type, listener, useCapture,
0379: syncMode, extraParams, null, ajaxTimeout);
0380: }
0381:
0382: public void addEventListener(EventTarget nodeTarget, String type,
0383: EventListener listener, boolean useCapture,
0384: String preSendCode) {
0385: int syncMode = getDefaultSyncMode();
0386: long ajaxTimeout = getAJAXTimeout();
0387: addEventListener(nodeTarget, type, listener, useCapture,
0388: syncMode, null, preSendCode, ajaxTimeout);
0389: }
0390:
0391: public void addEventListener(EventTarget nodeTarget, String type,
0392: EventListener listener, boolean useCapture, int syncMode,
0393: ParamTransport[] extraParams, String preSendCode,
0394: long ajaxTimeout) {
0395: if (DOMExtensionEventListenerWrapperImpl.isExtensionType(type))
0396: addDOMExtensionEventListener(nodeTarget, type, listener,
0397: useCapture, syncMode, extraParams, preSendCode,
0398: ajaxTimeout);
0399: else
0400: addDOMEventListener(nodeTarget, type, listener, useCapture,
0401: syncMode, extraParams, preSendCode, ajaxTimeout);
0402: }
0403:
0404: public void addDOMEventListener(EventTarget nodeTarget,
0405: String type, EventListener listener, boolean useCapture,
0406: int syncMode, ParamTransport[] extraParams,
0407: String preSendCode, long ajaxTimeout) {
0408: getDOMEventListenerRegistry().addDOMEventListener(nodeTarget,
0409: type, listener, useCapture, syncMode, extraParams,
0410: preSendCode, ajaxTimeout);
0411: }
0412:
0413: public void addDOMExtensionEventListener(EventTarget nodeTarget,
0414: String type, EventListener listener, boolean useCapture,
0415: int syncMode, ParamTransport[] extraParams,
0416: String preSendCode, long ajaxTimeout) {
0417: if (useCapture)
0418: throw new ItsNatException(
0419: "Capturing is not allowed for this type:" + type);
0420:
0421: if (UserEventListenerWrapperImpl.isUserType(type)) {
0422: String name = UserEventListenerWrapperImpl.getNameFromType(
0423: type, false);
0424: addUserEventListener(nodeTarget, name, listener, syncMode,
0425: extraParams, preSendCode, ajaxTimeout);
0426: } else if (ContinueEventListenerWrapperImpl
0427: .isContinueType(type)) {
0428: addContinueEventListener(nodeTarget, listener, syncMode,
0429: extraParams, preSendCode, ajaxTimeout);
0430: } else
0431: // itsnat:timer
0432: throw new ItsNatException(
0433: "This method is not allowed to register this event listener type:"
0434: + type);
0435: }
0436:
0437: public void addMutationEventListener(EventTarget nodeTarget,
0438: EventListener mutationListener, boolean useCapture) {
0439: int syncMode = getDefaultSyncMode();
0440: long ajaxTimeout = getAJAXTimeout();
0441: addMutationEventListener(nodeTarget, mutationListener,
0442: useCapture, syncMode, null, ajaxTimeout);
0443: }
0444:
0445: public void addMutationEventListener(EventTarget target,
0446: EventListener listener, boolean useCapture, int syncMode,
0447: String preSendCode, long ajaxTimeout) {
0448: ParamTransport[] params = new ParamTransport[] { new NodeMutationTransport() };
0449: addEventListener(target, "DOMAttrModified", listener,
0450: useCapture, syncMode, params, preSendCode, ajaxTimeout);
0451: addEventListener(target, "DOMNodeInserted", listener,
0452: useCapture, syncMode, params, preSendCode, ajaxTimeout);
0453: addEventListener(target, "DOMNodeRemoved", listener,
0454: useCapture, syncMode, params, preSendCode, ajaxTimeout);
0455: addEventListener(target, "DOMCharacterDataModified", listener,
0456: useCapture, syncMode, params, preSendCode, ajaxTimeout);
0457: }
0458:
0459: public void removeMutationEventListener(EventTarget target,
0460: EventListener listener, boolean useCapture) {
0461: removeEventListener(target, "DOMAttrModified", listener,
0462: useCapture);
0463: removeEventListener(target, "DOMNodeInserted", listener,
0464: useCapture);
0465: removeEventListener(target, "DOMNodeRemoved", listener,
0466: useCapture);
0467: removeEventListener(target, "DOMCharacterDataModified",
0468: listener, useCapture);
0469: }
0470:
0471: public boolean hasDOMEventListeners() {
0472: if (domListenerRegistry == null)
0473: return false;
0474: return !domListenerRegistry.isEmpty();
0475: }
0476:
0477: public DOMEventListenerRegistryImpl getDOMEventListenerRegistry() {
0478: if (domListenerRegistry == null) // Evita instanciar si no se usa, caso de servir XML
0479: this .domListenerRegistry = new DOMEventListenerRegistryImpl(
0480: this );
0481: return domListenerRegistry;
0482: }
0483:
0484: public void removeEventListener(EventTarget target, String type,
0485: EventListener listener, boolean useCapture) {
0486: if (DOMExtensionEventListenerWrapperImpl.isExtensionType(type))
0487: removeDOMExtensionEventListener(target, type, listener,
0488: useCapture);
0489: else
0490: removeDOMEventListener(target, type, listener, useCapture,
0491: true);
0492: }
0493:
0494: public void removeDOMEventListener(EventTarget target, String type,
0495: EventListener listener, boolean useCapture,
0496: boolean updateClient) {
0497: getDOMEventListenerRegistry().removeDOMEventListener(target,
0498: type, listener, useCapture, updateClient);
0499: }
0500:
0501: public void removeDOMExtensionEventListener(EventTarget target,
0502: String type, EventListener listener, boolean useCapture) {
0503: if (useCapture)
0504: return; // Como no puede haber listeners registrados capturing no hacemos nada
0505:
0506: if (UserEventListenerWrapperImpl.isUserType(type)) {
0507: String name = UserEventListenerWrapperImpl.getNameFromType(
0508: type, false);
0509: removeUserEventListener(target, name, listener);
0510: } else
0511: // itsnat:continue y itsnat:timer , en estos tipos el desregistro se hace internamente.
0512: throw new ItsNatException(
0513: "This method is not allowed to unregister this event listener type:"
0514: + type);
0515: }
0516:
0517: public void removeAllDOMEventListeners(EventTarget target,
0518: boolean updateClient) {
0519: if (!hasDOMEventListeners())
0520: return;
0521:
0522: getDOMEventListenerRegistry().removeAllDOMEventListeners(
0523: target, updateClient);
0524: }
0525:
0526: public DOMEventListenerWrapperImpl getDOMEventListenerById(
0527: String listenerId) {
0528: return getDOMEventListenerRegistry().getDOMEventListenerById(
0529: listenerId);
0530: }
0531:
0532: public boolean hasContinueEventListeners() {
0533: if (continueListenerRegistry == null)
0534: return false;
0535: return !continueListenerRegistry.isEmpty();
0536: }
0537:
0538: public ContinueEventListenerRegistryImpl getContinueEventListenerRegistry() {
0539: if (continueListenerRegistry == null)
0540: continueListenerRegistry = new ContinueEventListenerRegistryImpl(
0541: this ); // para ahorrar memoria si no se usa
0542: return continueListenerRegistry;
0543: }
0544:
0545: public void addContinueEventListener(EventTarget target,
0546: EventListener listener, int syncMode,
0547: ParamTransport[] extraParams, String preSendCode,
0548: long ajaxTimeout) {
0549: // El propio request no será el encargado de esperar a que termine el proceso background
0550: // aunque podría, sino un nuevo request, así permitimos que el hilo que registra la tarea
0551: // no necesariamente es un hilo request y además permitimos fácilmente que puedan añadirse varias
0552: // tareas de este tipo en el mismo request. Finalmente: así encaja el modelo de event-listener con los demás tipos de eventos
0553:
0554: if (!isAJAXEnabled())
0555: return;
0556:
0557: getContinueEventListenerRegistry().addContinueEventListener(
0558: target, listener, syncMode, extraParams, preSendCode,
0559: ajaxTimeout);
0560: }
0561:
0562: public ContinueEventListenerWrapperImpl removeContinueEventListener(
0563: String id) {
0564: // Es interna es llamada por el framework
0565: return (ContinueEventListenerWrapperImpl) getContinueEventListenerRegistry()
0566: .removeContinueEventListenerByIdOnly(id);
0567: }
0568:
0569: public boolean hasUserEventListeners() {
0570: if (userListenerRegistry == null)
0571: return false;
0572: return !userListenerRegistry.isEmpty();
0573: }
0574:
0575: public UserEventListenerRegistryImpl getUserEventListenerRegistry() {
0576: if (userListenerRegistry == null)
0577: userListenerRegistry = new UserEventListenerRegistryImpl(
0578: this ); // para ahorrar memoria si no se usa
0579: return userListenerRegistry;
0580: }
0581:
0582: public void addUserEventListener(EventTarget target, String name,
0583: EventListener listener, int syncMode,
0584: ParamTransport[] extraParams, String preSendCode,
0585: long ajaxTimeout) {
0586: getUserEventListenerRegistry().addUserEventListener(target,
0587: name, listener, syncMode, extraParams, preSendCode,
0588: ajaxTimeout);
0589: }
0590:
0591: public void addUserEventListener(EventTarget target, String name,
0592: EventListener listener) {
0593: int syncMode = getDefaultSyncMode();
0594: long ajaxTimeout = getAJAXTimeout();
0595: addUserEventListener(target, name, listener, syncMode, null,
0596: null, ajaxTimeout);
0597: }
0598:
0599: public UserEventListenerWrapperImpl getUserEventListenerById(
0600: String listenerId) {
0601: return getUserEventListenerRegistry().getUserEventListenerById(
0602: listenerId);
0603: }
0604:
0605: public void removeUserEventListener(EventTarget target,
0606: String name, EventListener listener) {
0607: getUserEventListenerRegistry().removeUserEventListener(target,
0608: name, listener, true);
0609: }
0610:
0611: public void removeAllUserEventListeners(EventTarget target,
0612: boolean updateClient) {
0613: if (!hasUserEventListeners())
0614: return;
0615:
0616: getUserEventListenerRegistry().removeAllUserEventListeners(
0617: target, updateClient);
0618: }
0619:
0620: public TimerEventListenerRegistryImpl getTimerEventListenerRegistry() {
0621: // Los handler/listener pueden ser de varios ItsNatTimer, pero no hay problema porque el id de cada uno lo genera el documento
0622:
0623: if (timerListenerRegistry == null)
0624: timerListenerRegistry = new TimerEventListenerRegistryImpl(
0625: this ); // para ahorrar memoria si no se usa
0626: return timerListenerRegistry;
0627: }
0628:
0629: public TimerEventListenerWrapperImpl getTimerEventListenerById(
0630: String id) {
0631: return getTimerEventListenerRegistry()
0632: .getTimerEventListenerById(id);
0633: }
0634:
0635: public AsyncTaskRegistry getAsyncTaskRegistry() {
0636: if (asyncTaskRegistry == null)
0637: this .asyncTaskRegistry = new AsyncTaskRegistry(this ); // para ahorrar memoria si no se usa
0638: return asyncTaskRegistry;
0639: }
0640:
0641: public void addAsynchronousTask(Runnable task, boolean lockDoc) {
0642: // Si maxWait es 0 lo más coherente es que ajaxTimeout sea también -1 (indefinido, no timeout) y no el de por defecto de ItsNatDocument
0643: addAsynchronousTask(task, lockDoc, 0, -1);
0644: }
0645:
0646: public void addAsynchronousTask(Runnable task, boolean lockDoc,
0647: int maxWait, long ajaxTimeout) {
0648: getAsyncTaskRegistry().addAsynchronousTask(task, lockDoc,
0649: maxWait, ajaxTimeout);
0650: }
0651:
0652: public AsyncTaskEventListenerWrapperImpl removeAsynchronousTask(
0653: String id) {
0654: return getAsyncTaskRegistry().removeAsynchronousTask(id);
0655: }
0656:
0657: public boolean isSendCodeEnabled() {
0658: return enabledSendCode;
0659: }
0660:
0661: public void disableSendCode() {
0662: this .enabledSendCode = false;
0663: }
0664:
0665: public void enableSendCode() {
0666: this .enabledSendCode = true;
0667: }
0668:
0669: public UserDataImpl getUserData() {
0670: if (userData == null)
0671: this .userData = new UserDataImpl(); // Para ahorrar memoria si no se usa, no es necesario sincronizar pues el acceso al Document está sincronizado
0672: return userData;
0673: }
0674:
0675: public String[] getUserValueNames() {
0676: return getUserData().getUserDataNames();
0677: }
0678:
0679: public boolean containsUserValueName(String name) {
0680: return getUserData().containsName(name);
0681: }
0682:
0683: public Object getUserValue(String name) {
0684: return getUserData().getUserData(name);
0685: }
0686:
0687: public Object setUserValue(String name, Object value) {
0688: return getUserData().setUserData(name, value);
0689: }
0690:
0691: public Object removeUserValue(String name) {
0692: return getUserData().removeUserData(name);
0693: }
0694:
0695: public ItsNatServletRequestImpl getCurrentItsNatServletRequest() {
0696: return currentRequest;
0697: }
0698:
0699: public void setCurrentItsNatServletRequest(
0700: ItsNatServletRequestImpl currentRequest) {
0701: this .currentRequest = currentRequest;
0702: }
0703:
0704: /*
0705: public ItsNatServletResponseImpl getCurrentItsNatServletResponse()
0706: {
0707: return currentRequest.getItsNatServletResponseImpl();
0708: }
0709: */
0710: public boolean hasClientDocumentInvitedRemoteCtrl() {
0711: if (clientDocInvitedRemCtrlMap == null)
0712: return false;
0713: return !clientDocInvitedRemCtrlMap.isEmpty();
0714: }
0715:
0716: public Map getClientDocumentInvitedRemoteCtrlMap() {
0717: if (clientDocInvitedRemCtrlMap == null)
0718: this .clientDocInvitedRemCtrlMap = new WeakHashMap();
0719: return clientDocInvitedRemCtrlMap;
0720: }
0721:
0722: public void addClientDocumentInvitedRemoteCtrl(
0723: ClientDocumentInvitedRemoteCtrlImpl clientDoc) {
0724: getClientDocumentInvitedRemoteCtrlMap().put(clientDoc, null);
0725: }
0726:
0727: public void removeClientDocumentInvitedRemoteCtrl(
0728: ClientDocumentInvitedRemoteCtrlImpl clientDoc) {
0729: clientDoc.setInvalid();
0730: getClientDocumentInvitedRemoteCtrlMap().remove(clientDoc);
0731: }
0732:
0733: public ClientDocumentOwnerImpl getClientDocumentOwnerImpl() {
0734: return clientDocOwner;
0735: }
0736:
0737: public ClientDocument getClientDocumentOwner() {
0738: return clientDocOwner;
0739: }
0740:
0741: public boolean someClientDocumentWillReceiveCodeSended() {
0742: // Sirve para evitar la generación de código de forma inútil
0743: // pues no podrá ser enviado a nadie.
0744:
0745: if (!isSendCodeEnabled())
0746: return false; // No, pues está desactivado
0747:
0748: // Cuando isSendCodeToRequesterEnabled es false es que estamos sincronizando
0749: // un cambio ocurrido en el cliente con el servidor, y por tanto no hace falta
0750: // enviar de nuevo al cliente el cambio en el servidor, pero a los observadores sí les interesa dicho
0751: // cambio salvo que no haya observadores (caso de mutationListener count es 1, el emisor del evento)
0752: // pues dichos observadores si necesitan recibir dichos cambios
0753:
0754: ClientDocumentOwnerImpl owner = getClientDocumentOwnerImpl();
0755: if (owner.isSendCodeEnabled())
0756: return true;
0757:
0758: if (hasClientDocumentInvitedRemoteCtrl()) {
0759: Map clientDocs = getClientDocumentInvitedRemoteCtrlMap();
0760: for (Iterator it = clientDocs.keySet().iterator(); it
0761: .hasNext();) {
0762: ClientDocumentInvitedRemoteCtrlImpl client = (ClientDocumentInvitedRemoteCtrlImpl) it
0763: .next();
0764: if (client.isSendCodeEnabled())
0765: return true;
0766: }
0767: }
0768:
0769: return false; // No hay ninguno que pueda recibir código
0770: }
0771:
0772: public boolean allClientDocumentWillReceiveCodeSended() {
0773: if (!isSendCodeEnabled())
0774: return false; // No, pues está desactivado
0775:
0776: ClientDocumentOwnerImpl owner = getClientDocumentOwnerImpl();
0777: if (!owner.isSendCodeEnabled())
0778: return false;
0779:
0780: if (hasClientDocumentInvitedRemoteCtrl()) {
0781: Map clientDocs = getClientDocumentInvitedRemoteCtrlMap();
0782: for (Iterator it = clientDocs.keySet().iterator(); it
0783: .hasNext();) {
0784: ClientDocumentInvitedRemoteCtrlImpl client = (ClientDocumentInvitedRemoteCtrlImpl) it
0785: .next();
0786: if (!client.isSendCodeEnabled())
0787: return false;
0788: }
0789: }
0790:
0791: return true; // Todos pueden recibir código
0792: }
0793:
0794: public void checkCodeToSendEnabled() {
0795: if (!isScriptingEnabled())
0796: throw new ItsNatException("Scripting is disabled");
0797:
0798: if (!isSendCodeEnabled()) // No enviar a nadie
0799: throw new ItsNatException("Send Code is disabled"); // Provocamos el error para que el usuario sepa que no se puede enviar código
0800: }
0801:
0802: public void addCodeToSend(Object code) {
0803: addCodeToSend(code, true);
0804: }
0805:
0806: public void addCodeToSend(Object code, boolean remCtrlToo) {
0807: checkCodeToSendEnabled();
0808:
0809: CodeToSendEventImpl event = null;
0810: if (hasCodeToSendListeners()) {
0811: event = getCodeToSendListeners().preProcessCodeToSend(code);
0812: code = event.getCode();
0813: if (code == null)
0814: return; // Ha sido rechazado
0815: }
0816:
0817: ClientDocumentOwnerImpl owner = getClientDocumentOwnerImpl();
0818: if (owner.isSendCodeEnabled())
0819: owner.addCodeToSend(code);
0820:
0821: if (remCtrlToo)
0822: addCodeToSendToClientDocRemoteCtrl(code);
0823:
0824: if (event != null)
0825: getCodeToSendListeners().postProcessCodeToSend(event);
0826: }
0827:
0828: public void addCodeToSendToClientDocRemoteCtrl(Object code) {
0829: checkCodeToSendEnabled();
0830:
0831: if (hasClientDocumentInvitedRemoteCtrl()) {
0832: Map observerDocs = getClientDocumentInvitedRemoteCtrlMap();
0833: for (Iterator it = observerDocs.keySet().iterator(); it
0834: .hasNext();) {
0835: ClientDocumentInvitedRemoteCtrlImpl observer = (ClientDocumentInvitedRemoteCtrlImpl) it
0836: .next();
0837: if (observer.isSendCodeEnabled())
0838: observer.addCodeToSend(code);
0839: }
0840: }
0841: }
0842:
0843: public void addCodeToSendToClientDocRemoteCtrl(String code,
0844: NodeLocation nodeLoc) {
0845: // Las llamadas por ejemplo de registro de listeners, dispatchEvent etc no deben
0846: // enviarse a los remote ctrl observers, pero en el caso de que
0847: // exista un nodo que se cachea indirectamente, hay que cachear explícitamente
0848: // en el control remoto
0849:
0850: if ((nodeLoc != null) && !nodeLoc.isAlreadyCached()) {
0851: String coreRemCtrl = JSNodeRenderImpl
0852: .addNodeToCache(nodeLoc);
0853: addCodeToSendToClientDocRemoteCtrl(coreRemCtrl);
0854: }
0855: }
0856:
0857: public boolean hasCodeToSendListeners() {
0858: if (codeToSendListeners == null)
0859: return false;
0860: return codeToSendListeners.hasCodeToSendListeners();
0861: }
0862:
0863: public CodeToSendListenersImpl getCodeToSendListeners() {
0864: if (codeToSendListeners == null)
0865: this .codeToSendListeners = new CodeToSendListenersImpl(this );
0866: return codeToSendListeners;
0867: }
0868:
0869: public void addCodeToSendListener(CodeToSendListener listener) {
0870: getCodeToSendListeners().addCodeToSendListener(listener);
0871: }
0872:
0873: public void removeCodeToSendListener(CodeToSendListener listener) {
0874: getCodeToSendListeners().removeCodeToSendListener(listener);
0875: }
0876:
0877: public boolean isInvalid() {
0878: return invalid;
0879: }
0880:
0881: public void setInvalid() {
0882: this .invalid = true;
0883:
0884: clientDocOwner.setInvalid();
0885:
0886: if (hasClientDocumentInvitedRemoteCtrl()) {
0887: Map clientDocs = getClientDocumentInvitedRemoteCtrlMap();
0888: for (Iterator it = clientDocs.keySet().iterator(); it
0889: .hasNext();) {
0890: ClientDocumentInvitedRemoteCtrlImpl client = (ClientDocumentInvitedRemoteCtrlImpl) it
0891: .next();
0892: client.setInvalid();
0893: }
0894:
0895: clientDocs.clear();
0896: }
0897: }
0898:
0899: public Hashtable getAttributeMap() {
0900: if (attributes == null) // para ahorrar memoria si no se usa
0901: this .attributes = new Hashtable();
0902: return attributes;
0903: }
0904:
0905: public Object getAttribute(String name) {
0906: return getAttributeMap().get(name);
0907: }
0908:
0909: public void setAttribute(String name, Object value) {
0910: getAttributeMap().put(name, value);
0911: }
0912:
0913: public Enumeration getAttributeNames() {
0914: // Este método es la única razón para usar un Hashtable (el cual está sincronizado innecesariamente)
0915: // por seguir el patrón de ServletRequest etc
0916: return getAttributeMap().elements();
0917: }
0918:
0919: public void removeAttribute(String name) {
0920: getAttributeMap().remove(name);
0921: }
0922:
0923: public Object getVariable(String varName) {
0924: Object value = getAttribute(varName);
0925: if (value != null)
0926: return value;
0927:
0928: return getItsNatSessionImpl().getVariable(varName);
0929: }
0930:
0931: public ItsNatVariableResolver createItsNatVariableResolver() {
0932: return new ItsNatVariableResolverImpl(null, null, this , null,
0933: null);
0934: }
0935:
0936: public ElementListFree createElementListFree(Element parentElement,
0937: boolean master) {
0938: if (master)
0939: return new ElementListFreeMasterImpl(parentElement, this );
0940: else {
0941: if (parentElement instanceof HTMLSelectElement) // Funciona bien también en el Xerces antiguo
0942: return new HTMLCollectionSelectOptionsElementListImpl(
0943: (HTMLSelectElement) parentElement, this );
0944:
0945: boolean isOldXerces = ItsNatImpl.isOldXerces();
0946: if (isOldXerces) {
0947: // En las versiones de Xerces antiguas el getCells y el getRows puede funcionar mal ante cambios del DOM
0948: // usamos la implementación más lenta pero seguro
0949: return new ElementListFreeSlaveDefaultImpl(
0950: parentElement, this );
0951: } else {
0952: if (parentElement instanceof HTMLTableRowElement)
0953: return new HTMLCollectionTableCellElementListImpl(
0954: (HTMLTableRowElement) parentElement, this );
0955: else if (parentElement instanceof HTMLTableSectionElement)
0956: return new HTMLCollectionTableRowElementListImpl(
0957: (HTMLTableSectionElement) parentElement,
0958: this );
0959: else
0960: return new ElementListFreeSlaveDefaultImpl(
0961: parentElement, this );
0962: }
0963: }
0964: }
0965:
0966: public ElementTableFree createElementTableFree(
0967: Element parentElement, boolean master) {
0968: if (master)
0969: return new ElementTableFreeMasterImpl(this , parentElement);
0970: else
0971: return new ElementTableFreeSlaveImpl(this , parentElement);
0972: }
0973:
0974: public ElementLabel createElementLabel(Element parentElement,
0975: boolean removePattern, ElementLabelRenderer renderer) {
0976: if (renderer == null)
0977: renderer = createDefaultElementLabelRenderer(); // Aunque no se use no hay problema pues es un singleton
0978:
0979: return createElementLabelInternal(parentElement, removePattern,
0980: renderer);
0981: }
0982:
0983: public ElementLabelImpl createElementLabelInternal(
0984: Element parentElement, boolean removePattern,
0985: ElementLabelRenderer renderer) {
0986: return new ElementLabelImpl(this , parentElement, removePattern,
0987: renderer);
0988: }
0989:
0990: public ElementList createElementList(Element parentElement,
0991: boolean removePattern, ElementListStructure structure,
0992: ElementListRenderer renderer) {
0993: if (renderer == null)
0994: renderer = createDefaultElementListRenderer(); // Aunque no se use no hay problema pues es un singleton
0995: if (structure == null)
0996: structure = createDefaultElementListStructure(); // Aunque no se use no hay problema pues es un singleton
0997:
0998: return createElementListInternal(parentElement, null, true,
0999: null, removePattern, structure, renderer);
1000: }
1001:
1002: public ElementList createElementList(Element parentElement,
1003: boolean removePattern) {
1004: return createElementList(parentElement, removePattern, null,
1005: null);
1006: }
1007:
1008: public ElementListImpl createElementListInternal(
1009: Element parentElement, boolean removePattern,
1010: ElementListStructure structure, ElementListRenderer renderer) {
1011: return createElementListInternal(parentElement, null, true,
1012: null, removePattern, structure, renderer);
1013: }
1014:
1015: public ElementListImpl createElementListInternal(
1016: Element parentElement, Element childPatternElement,
1017: boolean clonePattern,
1018: DocumentFragment childContentPatternFragment,
1019: boolean removePattern, ElementListStructure structure,
1020: ElementListRenderer renderer) {
1021: return new ElementListImpl(this , parentElement,
1022: childPatternElement, clonePattern,
1023: childContentPatternFragment, removePattern, renderer,
1024: structure);
1025: }
1026:
1027: public ElementListImpl createElementListNoRenderInternal(
1028: Element parentElement, Element childPatternElement,
1029: boolean clonePattern, boolean removePattern) {
1030: // Como no renderiza no necesitamos ni la estructura ni el renderer, sirve para gestionar elementos
1031: // Pasamos childContentPatternFragment como null porque éste está vinculado a la renderización
1032: return createElementListInternal(parentElement,
1033: childPatternElement, clonePattern, null, removePattern,
1034: null, null);
1035: }
1036:
1037: public ElementTable createElementTable(Element parentElement,
1038: boolean removePattern) {
1039: return createElementTable(parentElement, removePattern, null,
1040: null);
1041: }
1042:
1043: public ElementTable createElementTable(Element parentElement,
1044: boolean removePattern, ElementTableStructure structure,
1045: ElementTableRenderer renderer) {
1046: if (renderer == null)
1047: renderer = createDefaultElementTableRenderer(); // Aunque no se use no hay problema pues es un singleton
1048: if (structure == null)
1049: structure = createDefaultElementTableStructure(); // Aunque no se use no hay problema pues es un singleton
1050:
1051: return createElementTableInternal(parentElement, removePattern,
1052: structure, renderer);
1053: }
1054:
1055: public ElementTableImpl createElementTableInternal(
1056: Element parentElement, boolean removePattern,
1057: ElementTableStructure structure,
1058: ElementTableRenderer renderer) {
1059: return new ElementTableImpl(this , parentElement, removePattern,
1060: structure, renderer);
1061: }
1062:
1063: public ElementTreeNode createElementTreeNode(Element parentElement,
1064: boolean removePattern) {
1065: return createElementTreeNode(parentElement, removePattern,
1066: null, null);
1067: }
1068:
1069: public ElementTreeNode createElementTreeNode(Element parentElement,
1070: boolean removePattern, ElementTreeNodeStructure structure,
1071: ElementTreeNodeRenderer renderer) {
1072: if (renderer == null)
1073: renderer = createDefaultElementTreeNodeRenderer(); // Aunque no se use no hay problema pues es un singleton
1074: if (structure == null)
1075: structure = createDefaultElementTreeNodeStructure(); // Es realmente un singleton
1076:
1077: return createElementTreeNodeInternal(parentElement,
1078: removePattern, structure, renderer);
1079: }
1080:
1081: public ElementTreeNodeNormalImpl createElementTreeNodeInternal(
1082: Element parentElement, boolean removePattern,
1083: ElementTreeNodeStructure structure,
1084: ElementTreeNodeRenderer renderer) {
1085: return new ElementTreeNodeNormalImpl(this , null, -1,
1086: parentElement, null, true, removePattern, structure,
1087: renderer);
1088: }
1089:
1090: public ElementTree createElementTree(boolean treeTable,
1091: Element parentElement, boolean removePattern) {
1092: return createElementTree(treeTable, parentElement,
1093: removePattern, null, null);
1094: }
1095:
1096: public ElementTree createElementTree(boolean treeTable,
1097: Element parentElement, boolean removePattern,
1098: ElementTreeNodeStructure structure,
1099: ElementTreeNodeRenderer renderer) {
1100: if (renderer == null)
1101: renderer = createDefaultElementTreeNodeRenderer();
1102: if (structure == null)
1103: structure = createDefaultElementTreeNodeStructure();
1104:
1105: return createElementTreeInternal(treeTable, parentElement,
1106: removePattern, structure, renderer);
1107: }
1108:
1109: public ElementTreeImpl createElementTreeInternal(boolean treeTable,
1110: Element parentElement, boolean removePattern,
1111: ElementTreeNodeStructure structure,
1112: ElementTreeNodeRenderer renderer) {
1113: return new ElementTreeImpl(this , treeTable, parentElement,
1114: removePattern, structure, renderer);
1115: }
1116:
1117: public ElementTreeNodeList createElementTreeNodeList(
1118: boolean treeTable, Element parentElement,
1119: boolean removePattern) {
1120: return createElementTreeNodeList(treeTable, parentElement,
1121: removePattern, null, null);
1122: }
1123:
1124: public ElementTreeNodeList createElementTreeNodeList(
1125: boolean treeTable, Element parentElement,
1126: boolean removePattern, ElementTreeNodeStructure structure,
1127: ElementTreeNodeRenderer renderer) {
1128: if (renderer == null)
1129: renderer = createDefaultElementTreeNodeRenderer(); // Aunque no se use no hay problema pues es un singleton
1130: if (structure == null)
1131: structure = createDefaultElementTreeNodeStructure();
1132:
1133: return createElementTreeNodeListInternal(treeTable,
1134: parentElement, removePattern, structure, renderer);
1135: }
1136:
1137: public ElementTreeNodeListImpl createElementTreeNodeListInternal(
1138: boolean treeTable, Element parentElement,
1139: boolean removePattern, ElementTreeNodeStructure structure,
1140: ElementTreeNodeRenderer renderer) {
1141: if (treeTable)
1142: return new ElementTreeTableNodeListRootImpl(this ,
1143: parentElement, removePattern, structure, renderer);
1144: else
1145: return new ElementTreeNormalNodeListRootImpl(this ,
1146: parentElement, removePattern, structure, renderer);
1147: }
1148:
1149: public ElementTreeVersatileImpl createElementTreeVersatileInternal(
1150: boolean rootLess, boolean treeTable, Element parentElement,
1151: boolean removePattern, ElementTreeNodeStructure structure,
1152: ElementTreeNodeRenderer renderer) {
1153: if (rootLess)
1154: return new ElementTreeVersatileRootlessImpl(this ,
1155: treeTable, parentElement, removePattern, structure,
1156: renderer);
1157: else
1158: return new ElementTreeVersatileWithRootImpl(this ,
1159: treeTable, parentElement, removePattern, structure,
1160: renderer);
1161: }
1162:
1163: public ElementListStructure createDefaultElementListStructure() {
1164: return ElementListStructureDefaultImpl
1165: .newElementListStructureDefault();
1166: }
1167:
1168: public ElementTableStructure createDefaultElementTableStructure() {
1169: return ElementTableStructureDefaultImpl
1170: .newElementTableStructureDefault();
1171: }
1172:
1173: public ElementTreeNodeStructure createDefaultElementTreeNodeStructure() {
1174: return ElementTreeNodeStructureDefaultImpl
1175: .newElementTreeNodeStructureDefault();
1176: }
1177:
1178: public ScriptUtil getScriptUtil() {
1179: return getJSScriptUtilImpl();
1180: }
1181:
1182: public JScriptUtilImpl getJSScriptUtilImpl() {
1183: if (jsGenerator == null)
1184: this .jsGenerator = new JScriptUtilImpl(this );
1185: return jsGenerator;
1186: }
1187:
1188: public ItsNatNode getItsNatNode(Node node) {
1189: if (node == null)
1190: return null;
1191: if (node == this )
1192: return this ;
1193: if (node == getDocument())
1194: return this ;
1195: return getItsNatNodeRegistry().getItsNatNode(node);
1196: }
1197:
1198: public ElementRenderer createDefaultElementRenderer() {
1199: return ElementRendererDefaultImpl.newElementRendererDefault();
1200: }
1201:
1202: public ElementLabelRenderer createDefaultElementLabelRenderer() {
1203: return ElementLabelRendererDefaultImpl
1204: .newElementLabelRendererDefault();
1205: }
1206:
1207: public ElementListRenderer createDefaultElementListRenderer() {
1208: return ElementListRendererDefaultImpl
1209: .newElementListRendererDefault();
1210: }
1211:
1212: public ElementTableRenderer createDefaultElementTableRenderer() {
1213: return ElementTableRendererDefaultImpl
1214: .newElementTableRendererDefault();
1215: }
1216:
1217: public ElementTreeNodeRenderer createDefaultElementTreeNodeRenderer() {
1218: return ElementTreeNodeRendererDefaultImpl
1219: .newElementTreeNodeRendererDefault();
1220: }
1221:
1222: public MutationEventListenerImpl getMutationEventListener() {
1223: return mutationListener;
1224: }
1225:
1226: public void registerMutationListener() {
1227: // A día de hoy sólo los documentos HTML pueden tener JavaScript
1228: MutationEventListenerImpl mutationListener = getMutationEventListener();
1229:
1230: EventTarget docTarget = (EventTarget) getOriginalDocument();
1231: docTarget.addEventListener("DOMNodeInserted", mutationListener,
1232: false);
1233: docTarget.addEventListener("DOMNodeRemoved", mutationListener,
1234: false);
1235: docTarget.addEventListener("DOMAttrModified", mutationListener,
1236: false);
1237: docTarget.addEventListener("DOMCharacterDataModified",
1238: mutationListener, false);
1239: }
1240:
1241: public String getScriptLoadCode() {
1242: if (this .scriptLoadCode == null)
1243: throw new ItsNatException(
1244: "Script code on load was already loaded");
1245: String code = scriptLoadCode;
1246: this .scriptLoadCode = null; // Para no gastar memoria
1247: return code;
1248: }
1249:
1250: public void setScriptLoadCode(String code) {
1251: this .scriptLoadCode = code;
1252: }
1253:
1254: public ItsNatComponentManagerImpl getItsNatComponentManagerImpl() {
1255: if (componentMgr == null)
1256: this .componentMgr = createItsNatComponentManager();
1257: return componentMgr;
1258: }
1259:
1260: public ItsNatComponentManager getItsNatComponentManager() {
1261: return getItsNatComponentManagerImpl();
1262: }
1263:
1264: public abstract ItsNatComponentManagerImpl createItsNatComponentManager();
1265:
1266: public boolean isNodeCacheEnabled() {
1267: // No es necesario hacer público pero podría
1268: return getNodeCache() != null;
1269: }
1270:
1271: public NodeCache getNodeCache() {
1272: return nodeCache; // puede ser null (no caché)
1273: }
1274:
1275: public String removeNodeFromCache(Node node) {
1276: NodeCache cacheNode = getNodeCache();
1277: if (cacheNode == null)
1278: return null;
1279: return cacheNode.removeNode(node);
1280: }
1281:
1282: public String getCachedNodeId(Node node) {
1283: NodeCache cacheNode = getNodeCache();
1284: if (cacheNode == null)
1285: return null;
1286: return cacheNode.getId(node);
1287: }
1288:
1289: public NodeLocation getNodeLocation(Node node) {
1290: if (node != null) {
1291: NodeCache nodeCache = getNodeCache();
1292: if (nodeCache != null) {
1293: return getNodeLocationUsingCache(node, nodeCache);
1294: } else {
1295: String path = getStringPathFromNode(node);
1296: return new NodeLocation(null, null, path);
1297: }
1298: } else
1299: return new NodeLocation(null, null, null);
1300: }
1301:
1302: public NodeLocation getNodeLocationUsingCache(Node node,
1303: NodeCache nodeCache) {
1304: // nodeCache no puede ser nulo
1305:
1306: String id = nodeCache.getId(node);
1307: if (id != null)
1308: return new NodeLocation(null, id, null); // Sólo se necesita el id del nodo, cuando está en la caché no necesitamos el string path que es una tarea que consume mucho tiempo tanto en el servidor como en el cliente
1309: else {
1310: id = nodeCache.addNode(node); // Si el nodo no es cacheable o la caché está bloqueada (sólo lectural) devuelve null, no pasa nada por no poder cachear
1311: return getNodeLocationUsingCache(node, id, nodeCache);
1312: }
1313: }
1314:
1315: public NodeLocation getNodeLocationUsingCache(Node node, String id,
1316: NodeCache nodeCache) {
1317: // nodeCache no puede ser nulo
1318: // Se supone que el nodo no ha sido cacheado en el cliente todavía aunque tenga
1319: // un id asignado en el servidor (este id puede ser null, no ha sido cacheado en el servidor)
1320: // por lo que hay que obtener un path, absoluto o relativo respecto a un padre cacheado.
1321:
1322: // Buscamos un nodo padre que esté cacheado para evitar formar un path
1323: // absoluto que lleva tiempo.
1324: String parentId = null;
1325: Node parent = node;
1326:
1327: do {
1328: parent = parent.getParentNode();
1329: parentId = nodeCache.getId(parent); // si parent es null devuelve null
1330: } while ((parentId == null) && (parent != null));
1331:
1332: String path = DOMPathResolver.getStringPathFromNode(node,
1333: parent); // Si parent es null (parentId es null) devuelve un path absoluto
1334:
1335: return new NodeLocation(parentId, id, path);
1336: }
1337:
1338: public String getStringPathFromNode(Node node) {
1339: return DOMPathResolver.getStringPathFromNode(node, null);
1340: }
1341:
1342: public String getRelativeStringPathFromNodeParent(Node child) {
1343: return DOMPathResolver
1344: .getRelativeStringPathFromNodeParent(child);
1345: }
1346:
1347: public Node getNodeFromStringPathFromClient(String pathStr) {
1348: if (pathStr.equals("null"))
1349: return null;
1350:
1351: // El pathStr es generado por el navegador
1352: if (pathStr.startsWith("id:")) {
1353: // Formato: id:idvalue
1354: String id = pathStr.substring("id:".length());
1355: NodeCache nodeCache = getNodeCache(); // La caché debe estar activado sí o sí
1356: return nodeCache.getNodeById(id);
1357: } else {
1358: // Nodo no cacheado
1359: Node node;
1360: String parentId = null;
1361: String path = null;
1362:
1363: if (pathStr.startsWith("pid:")) {
1364: // Formato: pid:idparent:pathrel
1365: int posSepPath = pathStr.lastIndexOf(':');
1366: parentId = pathStr.substring("pid:".length(),
1367: posSepPath);
1368: path = pathStr.substring(posSepPath + 1);
1369: NodeCache nodeCache = getNodeCache(); // La caché debe estar activado sí o sí
1370: Node parent = nodeCache.getNodeById(parentId); // no puede ser null
1371: node = DOMPathResolver.getNodeFromPath(path, parent,
1372: getDocument(), getDefaultView());
1373: } else {
1374: // Formato: pathabs
1375: path = pathStr;
1376: node = DOMPathResolver.getNodeFromPath(path, null,
1377: getDocument(), getDefaultView());
1378: }
1379:
1380: NodeCache nodeCache = getNodeCache();
1381: if (nodeCache != null) {
1382: // Guardamos en la caché y enviamos al cliente, así mejoramos el rendimiento
1383: String id = nodeCache.addNode(node); // Si el nodo no es cacheable o la caché está bloqueada devuelve null
1384: if (id != null) {
1385: NodeLocation nodeLoc = new NodeLocation(parentId,
1386: id, path);
1387: addCodeToSend(JSNodeRenderImpl
1388: .addNodeToCache(nodeLoc));
1389: }
1390: }
1391:
1392: return node;
1393: }
1394: }
1395:
1396: public boolean hasArtifacts() {
1397: if (artifacts == null)
1398: return false;
1399: return !artifacts.isEmpty();
1400: }
1401:
1402: public Map getArtifactMap() {
1403: if (artifacts == null)
1404: this .artifacts = new HashMap();
1405: return artifacts;
1406: }
1407:
1408: public void registerArtifact(String name, Object value) {
1409: Map artifacts = getArtifactMap();
1410: artifacts.put(name, value);
1411: }
1412:
1413: public Object getArtifact(String name) {
1414: if (!hasArtifacts())
1415: return null;
1416:
1417: Map artifacts = getArtifactMap();
1418: return artifacts.get(name);
1419: }
1420:
1421: public Object removeArtifact(String name) {
1422: Map artifacts = getArtifactMap();
1423: return artifacts.remove(name);
1424: }
1425:
1426: public Object getArtifact(String name, boolean cascade) {
1427: Object artif = getArtifact(name);
1428: if (cascade && (artif == null))
1429: artif = getDocumentTemplateImpl().getArtifact(name, true);
1430: return artif;
1431: }
1432:
1433: public boolean hasCachedNodes() {
1434: return (usedTemplates != null);
1435: }
1436:
1437: public String serializeNode(Node node) {
1438: String code = getDocumentTemplateVersion().serializeNode(node);
1439:
1440: code = resolveCachedNodes(code);
1441:
1442: return code;
1443: }
1444:
1445: public DateFormat getDefaultDateFormat() {
1446: if (dateFormat == null)
1447: this .dateFormat = DateFormat.getDateInstance();
1448: return dateFormat;
1449: }
1450:
1451: public void setDefaultDateFormat(DateFormat dateFormat) {
1452: this .dateFormat = dateFormat;
1453: }
1454:
1455: public NumberFormat getDefaultNumberFormat() {
1456: if (numberFormat == null)
1457: this .numberFormat = NumberFormat.getInstance();
1458: return numberFormat;
1459: }
1460:
1461: public void setDefaultNumberFormat(NumberFormat numberFormat) {
1462: this .numberFormat = numberFormat;
1463: }
1464:
1465: public void notifyEventReceived() {
1466: if (hasClientDocumentInvitedRemoteCtrl()) {
1467: Map clientDocs = getClientDocumentInvitedRemoteCtrlMap();
1468: for (Iterator it = clientDocs.keySet().iterator(); it
1469: .hasNext();) {
1470: ClientDocumentInvitedRemoteCtrlImpl client = (ClientDocumentInvitedRemoteCtrlImpl) it
1471: .next();
1472: client.normalEventReceived();
1473: }
1474: }
1475: }
1476:
1477: public LinkedList getRemoteControlEventListeners() {
1478: if (remControlListeners == null)
1479: this .remControlListeners = new LinkedList();
1480: return remControlListeners;
1481: }
1482:
1483: public void addRemoteControlEventListener(
1484: RemoteControlEventListener listener) {
1485: LinkedList remControlListeners = getRemoteControlEventListeners();
1486: remControlListeners.add(listener);
1487: }
1488:
1489: public void removeRemoteControlEventListener(
1490: RemoteControlEventListener listener) {
1491: LinkedList remControlListeners = getRemoteControlEventListeners();
1492: remControlListeners.remove(listener);
1493: }
1494:
1495: public Iterator getRemoteControlEventListenerIterator() {
1496: if (remControlListeners == null)
1497: return null;
1498: LinkedList remControlListeners = getRemoteControlEventListeners();
1499: return remControlListeners.iterator();
1500: }
1501:
1502: public Event createEvent(String eventType) throws DOMException {
1503: return ServerDOMBasedEventImpl.createDOMBasedEvent(eventType,
1504: this );
1505: }
1506:
1507: public void lockThread(long maxWait) {
1508: synchronized (this ) // si ya está sincronizado (lo normal) es redundante
1509: {
1510: // Al esperar liberamos el lock sobre el documento y otro hilo lo podrá usar
1511: try {
1512: wait(maxWait);
1513: } catch (InterruptedException ex) {
1514: throw new ItsNatException(ex);
1515: }
1516: }
1517: }
1518:
1519: public void unlockThreads() {
1520: synchronized (this ) {
1521: notifyAll(); // Liberamos el hilo request/response bloqueado
1522: }
1523: }
1524:
1525: public boolean dispatchEvent(EventTarget target, Event evt)
1526: throws EventException {
1527: if (hasEventDispatcherThreads()) {
1528: Set threads = getEventDispatcherThreadSet();
1529: if (threads.contains(Thread.currentThread())) {
1530: ClientDocumentOwnerImpl clientDoc = getClientDocumentOwnerImpl();
1531: return clientDoc.dispatchEvent(target, evt,
1532: getDefaultSyncMode(), getAJAXTimeout());
1533: }
1534: }
1535:
1536: return dispatchEventLocally(target, evt);
1537: }
1538:
1539: public boolean dispatchEventLocally(EventTarget target, Event evt)
1540: throws EventException {
1541: return ServerDOMEventImpl.dispatchEventLocally(target, evt);
1542: }
1543:
1544: public long getEventDispatcherMaxWait() {
1545: return evtDispMaxWait;
1546: }
1547:
1548: public void setEventDispatcherMaxWait(long wait) {
1549: this .evtDispMaxWait = wait;
1550: }
1551:
1552: public boolean hasEventDispatcherThreads() {
1553: if (evtDispThreadSet == null)
1554: return false;
1555: return !evtDispThreadSet.isEmpty();
1556: }
1557:
1558: public Set getEventDispatcherThreadSet() {
1559: if (evtDispThreadSet == null)
1560: this .evtDispThreadSet = new HashSet();
1561: return evtDispThreadSet;
1562: }
1563:
1564: public boolean isReferrerEnabled() {
1565: return getDocumentTemplateVersion().isReferrerEnabled();
1566: }
1567:
1568: public boolean isAJAXEnabled() {
1569: return getDocumentTemplateVersion().isAJAXEnabled();
1570: }
1571:
1572: public boolean isScriptingEnabled() {
1573: return getDocumentTemplateVersion().isScriptingEnabled();
1574: }
1575:
1576: public boolean isAutoCleanEventListeners() {
1577: return getDocumentTemplateVersion().isAutoCleanEventListeners();
1578: }
1579:
1580: public boolean isLoadScriptInline() {
1581: return getDocumentTemplateVersion().isLoadScriptInline();
1582: }
1583:
1584: public int getUseGZip() {
1585: return getDocumentTemplateVersion().getUseGZip();
1586: }
1587:
1588: public boolean isReferrerPushEnabled() {
1589: return getDocumentTemplateVersion().isReferrerPushEnabled();
1590: }
1591:
1592: public Date getCreationDate() {
1593: return getClientDocumentOwnerImpl().getCreationDate();
1594: }
1595:
1596: public void dispatchRemoteControlListeners(
1597: RemoteControlEventImpl event) {
1598: Iterator iterator;
1599:
1600: ItsNatServletImpl servlet = getDocumentTemplateImpl()
1601: .getItsNatServletImpl();
1602:
1603: iterator = servlet.getRemoteControlEventListenerIterator();
1604: dispatchRemoteControlListeners(iterator, event);
1605:
1606: ItsNatDocumentImpl itsNatDoc = event.getItsNatDocumentImpl();
1607: DocumentTemplateImpl docTemplate = itsNatDoc
1608: .getDocumentTemplateImpl();
1609: iterator = docTemplate.getRemoteControlEventListenerIterator();
1610: dispatchRemoteControlListeners(iterator, event);
1611:
1612: iterator = itsNatDoc.getRemoteControlEventListenerIterator();
1613: dispatchRemoteControlListeners(iterator, event);
1614: }
1615:
1616: public void dispatchRemoteControlListeners(Iterator iterator,
1617: RemoteControlEventImpl event) {
1618: if (iterator != null) {
1619: while (iterator.hasNext()) {
1620: RemoteControlEventListener listener = (RemoteControlEventListener) iterator
1621: .next();
1622: listener.handleRequest(event);
1623: }
1624: }
1625: }
1626:
1627: public boolean isUsePatternMarkupToRender() {
1628: return usePatternMarkupToRender;
1629: }
1630:
1631: public void setUsePatternMarkupToRender(
1632: boolean usePatternMarkupToRender) {
1633: this .usePatternMarkupToRender = usePatternMarkupToRender;
1634: }
1635:
1636: public LinkedList getReferrerItsNatServletRequestListenerList() {
1637: if (referrerRequestListeners == null)
1638: this .referrerRequestListeners = new LinkedList();
1639: return referrerRequestListeners;
1640: }
1641:
1642: public Iterator getReferrerItsNatServletRequestListenerIterator() {
1643: if (referrerRequestListeners == null)
1644: return null;
1645: if (referrerRequestListeners.isEmpty())
1646: return null;
1647: return referrerRequestListeners.iterator();
1648: }
1649:
1650: public void addReferrerItsNatServletRequestListener(
1651: ItsNatServletRequestListener listener) {
1652: if (!isReferrerEnabled())
1653: throw new ItsNatException("Referrer feature is not enabled");
1654:
1655: LinkedList referrerRequestListeners = getReferrerItsNatServletRequestListenerList();
1656: referrerRequestListeners.add(listener);
1657: }
1658:
1659: public void removeReferrerItsNatServletRequestListener(
1660: ItsNatServletRequestListener listener) {
1661: LinkedList referrerRequestListeners = getReferrerItsNatServletRequestListenerList();
1662: referrerRequestListeners.remove(listener);
1663: }
1664:
1665: public void dispatchReferrerRequestListeners(
1666: ItsNatServletRequest request, ItsNatServletResponse response) {
1667: // Sincronizar el documento antes de llamar a este método
1668: Iterator iterator = getReferrerItsNatServletRequestListenerIterator();
1669: if (iterator != null) {
1670: while (iterator.hasNext()) {
1671: ItsNatServletRequestListener listener = (ItsNatServletRequestListener) iterator
1672: .next();
1673: listener.processRequest(request, response);
1674: }
1675: }
1676: }
1677:
1678: // Node methods
1679:
1680: public int hashCode() {
1681: return getOriginalDocument().hashCode();
1682: }
1683:
1684: public boolean equals(Object other) {
1685: boolean res = super .equals(other);
1686: if (res)
1687: return true;
1688: if (other instanceof ItsNatNode)
1689: return getNode().equals(((ItsNatNode) other).getNode());
1690: return false;
1691: }
1692:
1693: public String getNodeName() {
1694: return getOriginalDocument().getNodeName();
1695: }
1696:
1697: public String getNodeValue() throws DOMException {
1698: return getOriginalDocument().getNodeValue();
1699: }
1700:
1701: public void setNodeValue(String nodeValue) throws DOMException {
1702: getOriginalDocument().setNodeValue(nodeValue);
1703: }
1704:
1705: public short getNodeType() {
1706: return getOriginalDocument().getNodeType();
1707: }
1708:
1709: public Node getParentNode() {
1710: return getOriginalDocument().getParentNode();
1711: }
1712:
1713: public NodeList getChildNodes() {
1714: return getOriginalDocument().getChildNodes();
1715: }
1716:
1717: public Node getFirstChild() {
1718: return getOriginalDocument().getFirstChild();
1719: }
1720:
1721: public Node getLastChild() {
1722: return getOriginalDocument().getLastChild();
1723: }
1724:
1725: public Node getPreviousSibling() {
1726: return getOriginalDocument().getPreviousSibling();
1727: }
1728:
1729: public Node getNextSibling() {
1730: return getOriginalDocument().getNextSibling();
1731: }
1732:
1733: public NamedNodeMap getAttributes() {
1734: return getOriginalDocument().getAttributes();
1735: }
1736:
1737: public Document getOwnerDocument() {
1738: return getOriginalDocument().getOwnerDocument();
1739: }
1740:
1741: public Node insertBefore(Node newChild, Node refChild)
1742: throws DOMException {
1743: return getOriginalDocument().insertBefore(newChild, refChild);
1744: }
1745:
1746: public Node replaceChild(Node newChild, Node oldChild)
1747: throws DOMException {
1748: return getOriginalDocument().replaceChild(newChild, oldChild);
1749: }
1750:
1751: public Node removeChild(Node oldChild) throws DOMException {
1752: return getOriginalDocument().removeChild(oldChild);
1753: }
1754:
1755: public Node appendChild(Node newChild) throws DOMException {
1756: return getOriginalDocument().appendChild(newChild);
1757: }
1758:
1759: public boolean hasChildNodes() {
1760: return getOriginalDocument().hasChildNodes();
1761: }
1762:
1763: public Node cloneNode(boolean deep) {
1764: return getOriginalDocument().cloneNode(deep);
1765: }
1766:
1767: public void normalize() {
1768: getOriginalDocument().normalize();
1769: }
1770:
1771: public boolean isSupported(String feature, String version) {
1772: return getOriginalDocument().isSupported(feature, version);
1773: }
1774:
1775: public String getNamespaceURI() {
1776: return getOriginalDocument().getNamespaceURI();
1777: }
1778:
1779: public String getPrefix() {
1780: return getOriginalDocument().getPrefix();
1781: }
1782:
1783: public void setPrefix(String prefix) throws DOMException {
1784: getOriginalDocument().setPrefix(prefix);
1785: }
1786:
1787: public String getLocalName() {
1788: return getOriginalDocument().getLocalName();
1789: }
1790:
1791: public boolean hasAttributes() {
1792: return getOriginalDocument().hasAttributes();
1793: }
1794:
1795: public String getBaseURI() {
1796: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1797: throw new ItsNatException("DOM 3 is not supported");
1798: }
1799:
1800: public short compareDocumentPosition(Node other)
1801: throws DOMException {
1802: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1803: throw new ItsNatException("DOM 3 is not supported");
1804: }
1805:
1806: public String getTextContent() throws DOMException {
1807: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1808: throw new ItsNatException("DOM 3 is not supported");
1809: }
1810:
1811: public void setTextContent(String textContent) throws DOMException {
1812: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1813: throw new ItsNatException("DOM 3 is not supported");
1814: }
1815:
1816: public boolean isSameNode(Node other) {
1817: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1818: throw new ItsNatException("DOM 3 is not supported");
1819: }
1820:
1821: public String lookupPrefix(String namespaceURI) {
1822: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1823: throw new ItsNatException("DOM 3 is not supported");
1824: }
1825:
1826: public boolean isDefaultNamespace(String namespaceURI) {
1827: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1828: throw new ItsNatException("DOM 3 is not supported");
1829: }
1830:
1831: public String lookupNamespaceURI(String prefix) {
1832: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1833: throw new ItsNatException("DOM 3 is not supported");
1834: }
1835:
1836: public boolean isEqualNode(Node arg) {
1837: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1838: throw new ItsNatException("DOM 3 is not supported");
1839: }
1840:
1841: public Object getFeature(String feature, String version) {
1842: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1843: throw new ItsNatException("DOM 3 is not supported");
1844: }
1845:
1846: public Object setUserData(String key, Object data,
1847: UserDataHandler handler) {
1848: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1849: throw new ItsNatException("DOM 3 is not supported");
1850: }
1851:
1852: public Object getUserData(String key) {
1853: // Para que compile con el JDK 1.5 (Node tiene métodos del DOM 3)
1854: throw new ItsNatException("DOM 3 is not supported");
1855: }
1856:
1857: // EventTarget methods
1858:
1859: public void addEventListener(String type, EventListener listener,
1860: boolean useCapture) {
1861: addEventListener((EventTarget) getDocument(), type, listener,
1862: useCapture);
1863: }
1864:
1865: public void removeEventListener(String type,
1866: EventListener listener, boolean useCapture) {
1867: removeEventListener((EventTarget) getDocument(), type,
1868: listener, useCapture);
1869: }
1870:
1871: public boolean dispatchEvent(Event evt) throws EventException {
1872: return dispatchEvent((EventTarget) getDocument(), evt);
1873: }
1874:
1875: // Document methods
1876:
1877: public NodeList getElementsByTagName(String tagname) {
1878: return getOriginalDocument().getElementsByTagName(tagname);
1879: }
1880:
1881: public Attr createAttribute(String name) throws DOMException {
1882: return getOriginalDocument().createAttribute(name);
1883: }
1884:
1885: public CDATASection createCDATASection(String data)
1886: throws DOMException {
1887: return getOriginalDocument().createCDATASection(data);
1888: }
1889:
1890: public Comment createComment(String data) {
1891: return getOriginalDocument().createComment(data);
1892: }
1893:
1894: public Element createElement(String tagName) throws DOMException {
1895: return getOriginalDocument().createElement(tagName);
1896: }
1897:
1898: public EntityReference createEntityReference(String name)
1899: throws DOMException {
1900: return getOriginalDocument().createEntityReference(name);
1901: }
1902:
1903: public Text createTextNode(String data) {
1904: return getOriginalDocument().createTextNode(data);
1905: }
1906:
1907: public Element getElementById(String elementId) {
1908: return getOriginalDocument().getElementById(elementId);
1909: }
1910:
1911: public Node importNode(Node importedNode, boolean deep)
1912: throws DOMException {
1913: return getOriginalDocument().importNode(importedNode, deep);
1914: }
1915:
1916: public DOMImplementation getImplementation() {
1917: return getOriginalDocument().getImplementation();
1918: }
1919:
1920: public NodeList getElementsByTagNameNS(String namespaceURI,
1921: String localName) {
1922: return getOriginalDocument().getElementsByTagNameNS(
1923: namespaceURI, localName);
1924: }
1925:
1926: public Attr createAttributeNS(String namespaceURI,
1927: String qualifiedName) throws DOMException {
1928: return getOriginalDocument().createAttributeNS(namespaceURI,
1929: qualifiedName);
1930: }
1931:
1932: public DocumentFragment createDocumentFragment() {
1933: return getOriginalDocument().createDocumentFragment();
1934: }
1935:
1936: public Element createElementNS(String namespaceURI,
1937: String qualifiedName) throws DOMException {
1938: return getOriginalDocument().createElementNS(namespaceURI,
1939: qualifiedName);
1940: }
1941:
1942: public ProcessingInstruction createProcessingInstruction(
1943: String target, String data) throws DOMException {
1944: return getOriginalDocument().createProcessingInstruction(
1945: target, data);
1946: }
1947:
1948: public DocumentType getDoctype() {
1949: return getOriginalDocument().getDoctype();
1950: }
1951:
1952: public Element getDocumentElement() {
1953: return getOriginalDocument().getDocumentElement();
1954: }
1955:
1956: public void setXmlVersion(String xmlVersion) throws DOMException {
1957: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
1958: throw new ItsNatException("DOM 3 is not supported");
1959: }
1960:
1961: public void setDocumentURI(String documentURI) {
1962: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
1963: throw new ItsNatException("DOM 3 is not supported");
1964: }
1965:
1966: public Node adoptNode(Node source) throws DOMException {
1967: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
1968: throw new ItsNatException("DOM 3 is not supported");
1969: }
1970:
1971: public void setStrictErrorChecking(boolean strictErrorChecking) {
1972: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
1973: throw new ItsNatException("DOM 3 is not supported");
1974: }
1975:
1976: public void setXmlStandalone(boolean xmlStandalone)
1977: throws DOMException {
1978: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
1979: throw new ItsNatException("DOM 3 is not supported");
1980: }
1981:
1982: public Node renameNode(Node n, String namespaceURI,
1983: String qualifiedName) throws DOMException {
1984: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
1985: throw new ItsNatException("DOM 3 is not supported");
1986: }
1987:
1988: public String getDocumentURI() {
1989: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
1990: throw new ItsNatException("DOM 3 is not supported");
1991: }
1992:
1993: public DOMConfiguration getDomConfig() {
1994: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
1995: throw new ItsNatException("DOM 3 is not supported");
1996: }
1997:
1998: public String getInputEncoding() {
1999: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
2000: throw new ItsNatException("DOM 3 is not supported");
2001: }
2002:
2003: public boolean getStrictErrorChecking() {
2004: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
2005: throw new ItsNatException("DOM 3 is not supported");
2006: }
2007:
2008: public String getXmlEncoding() {
2009: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
2010: throw new ItsNatException("DOM 3 is not supported");
2011: }
2012:
2013: public boolean getXmlStandalone() {
2014: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
2015: throw new ItsNatException("DOM 3 is not supported");
2016: }
2017:
2018: public String getXmlVersion() {
2019: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
2020: throw new ItsNatException("DOM 3 is not supported");
2021: }
2022:
2023: public void normalizeDocument() {
2024: // Para que compile con el JDK 1.5 (tiene métodos del DOM 3)
2025: throw new ItsNatException("DOM 3 is not supported");
2026: }
2027:
2028: }
|