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.response;
015:
016: import java.io.IOException;
017: import java.io.Writer;
018: import org.itsnat.core.ItsNatException;
019: import org.itsnat.impl.core.DocumentTemplateVersionImpl;
020: import org.itsnat.impl.core.ItsNatDocumentImpl;
021: import org.itsnat.impl.core.ItsNatServletRequestImpl;
022: import org.itsnat.impl.core.ItsNatServletResponseImpl;
023: import org.itsnat.impl.core.ItsNatSessionImpl;
024: import org.itsnat.impl.core.domutil.ItsNatDOMUtilInternal;
025: import org.w3c.dom.Document;
026: import org.w3c.dom.html.HTMLDocument;
027: import org.w3c.dom.html.HTMLScriptElement;
028:
029: /**
030: *
031: * @author jmarranz
032: */
033: public class ResponseLoadHTMLDocSharedImpl {
034: protected static final String timeStamp = Long.toString(System
035: .currentTimeMillis());
036:
037: /**
038: * Creates a new instance of ResponseLoadHTMLDocSharedImpl
039: */
040: public ResponseLoadHTMLDocSharedImpl() {
041: }
042:
043: public static void addScriptToLoadedDocument(String docCode,
044: String loadScriptCode, Writer out,
045: boolean loadScriptInline, boolean remView,
046: ItsNatServletResponseImpl itsNatResponse) {
047: //loadScriptCode = "var start=new Date().getTime();\n" + loadScriptCode + "alert(new Date().getTime() - start);";
048: StringBuffer scriptsCode = new StringBuffer();
049:
050: ItsNatDocumentImpl itsNatDoc = itsNatResponse
051: .getItsNatDocumentImpl();
052: if (itsNatDoc.isScriptingEnabled()) {
053: int prevScriptsToRemove = 0;
054: DocumentTemplateVersionImpl docTemplate = itsNatDoc
055: .getDocumentTemplateVersion();
056: if (docTemplate.isAddFrameworkScriptFiles()) {
057: String jsPathBase = docTemplate
058: .getFrameworkScriptFilesBasePath();
059:
060: scriptsCode.append(generateFrameworkScriptElement(
061: "itsnat.js", jsPathBase, itsNatDoc));
062: scriptsCode.append(generateFrameworkScriptElement(
063: "itsnat_ajax.js", jsPathBase, itsNatDoc));
064:
065: if (itsNatDoc.isMSIE())
066: scriptsCode.append(generateFrameworkScriptElement(
067: "itsnat_msie.js", jsPathBase, itsNatDoc));
068: else
069: scriptsCode.append(generateFrameworkScriptElement(
070: "itsnat_w3c.js", jsPathBase, itsNatDoc));
071:
072: prevScriptsToRemove = 3;
073: }
074:
075: scriptsCode.append(generateFinalScriptElementCode(
076: loadScriptCode, loadScriptInline, remView,
077: prevScriptsToRemove, itsNatResponse));
078: }
079:
080: addCodeToHTMLBody(docCode, scriptsCode.toString(), out);
081: }
082:
083: private static String generateFrameworkScriptElement(String jsPath,
084: String jsPathBase, ItsNatDocumentImpl itsNatDoc) {
085: Document doc = itsNatDoc.getDocument();
086: HTMLScriptElement scriptElem = (HTMLScriptElement) doc
087: .createElement("script");
088: scriptElem.setType("text/javascript");
089: if (!jsPathBase.equals(""))
090: jsPath = jsPathBase + "/" + jsPath;
091: jsPath += "?time=" + timeStamp; // Evita el problema de la caché del MSIE que no actualiza el archivo .js ante cambios del mismo salvo haciendo "reload/actualizar", así se genera un URL único al cargar la aplicación, por otra parte el número no cambia durante la vida de la aplicación por lo que el archivo es cacheado por MSIE, si se cambia el .js deberá pararse/recargarse la aplicación web, al recargarse esta clase el timeStamp se actualiza
092: scriptElem.setSrc(jsPath);
093: return itsNatDoc.serializeNode(scriptElem);
094: }
095:
096: public static String generateFinalScriptElementCode(
097: String codeToExec, boolean loadScriptInline,
098: boolean remView, int prevScriptsToRemove,
099: ItsNatServletResponseImpl itsNatResponse) {
100: ItsNatDocumentImpl itsNatDoc = itsNatResponse
101: .getItsNatDocumentImpl();
102: HTMLDocument doc = (HTMLDocument) itsNatDoc.getDocument();
103:
104: HTMLScriptElement script = (HTMLScriptElement) doc
105: .createElement("script");
106: ItsNatDOMUtilInternal.setAttribute(script, "type",
107: "text/javascript");
108:
109: String code = getScriptContentOnLoad(codeToExec, remView,
110: prevScriptsToRemove, itsNatResponse);
111:
112: if (loadScriptInline) {
113: script.appendChild(doc.createTextNode(code));
114: } else {
115: itsNatDoc.setScriptLoadCode(code);
116:
117: ItsNatServletRequestImpl request = itsNatResponse
118: .getItsNatServletRequestImpl();
119: String url = request.getServletURLInternal();
120: url += "?itsnat_doc_id=" + itsNatDoc.getId();
121: url += "&itsnat_load_script=true";
122: script.setSrc(url);
123: }
124:
125: return itsNatDoc.serializeNode(script);
126: }
127:
128: public static String getScriptContentOnLoad(String codeToExec,
129: boolean remView, int prevScriptsToRemove,
130: ItsNatServletResponseImpl itsNatResponse) {
131: prevScriptsToRemove++; // Incrementamos en 1 porque siempre hay que eliminar el <script> con el código de carga
132:
133: // Eliminamos los <script> del framework y del <script> de carga antes de ejecutar el resto del código para que no influya
134:
135: StringBuffer code = new StringBuffer();
136: code.append("\n");
137: code.append("for(var i = 1; i <= " + prevScriptsToRemove
138: + "; i++)");
139: code
140: .append(" document.body.removeChild(document.body.lastChild); \n"); // Eliminamos los <script> del framework antes de ejecutar el resto del código para que no influya
141:
142: code.append(getInitDocumentCode(remView, itsNatResponse));
143: code.append(codeToExec);
144: return code.toString();
145: }
146:
147: public static String getInitDocumentCode(boolean remView,
148: ItsNatServletResponseImpl itsNatResponse) {
149: ItsNatDocumentImpl itsNatDoc = itsNatResponse
150: .getItsNatDocumentImpl();
151:
152: ItsNatServletRequestImpl request = itsNatResponse
153: .getItsNatServletRequestImpl();
154: // Usamos la session del request y no la del propietario del documento
155: // para asegurar que no se suplanta al propietario
156: ItsNatSessionImpl session = request.getItsNatSessionImpl();
157: String sessionId = session.getId();
158: String docId = itsNatDoc.getId();
159: String servletPath = request.getServletURLInternal();
160: int errorMode = itsNatDoc.getClientErrorMode();
161: boolean cacheEnabled = itsNatDoc.getNodeCache() != null;
162:
163: StringBuffer code = new StringBuffer();
164: code.append("itsnat_init(document); \n");
165: code
166: .append("var itsNatDoc = document.itsNatDoc = new itsnat.HTMLDocument(\""
167: + sessionId
168: + "\",\""
169: + docId
170: + "\",\""
171: + servletPath
172: + "\","
173: + remView
174: + ","
175: + errorMode + "," + cacheEnabled + "); \n");
176: return code.toString();
177: }
178:
179: public static void addCodeToHTMLBody(String docCode,
180: String codeToAdd, Writer out) {
181: int posHTMLEnd = docCode.lastIndexOf('<');
182: int posBODYEnd = docCode.lastIndexOf('<', posHTMLEnd - 1);
183: String preScript = docCode.substring(0, posBODYEnd);
184: String posScript = docCode.substring(posBODYEnd);
185: try {
186: out.write(preScript);
187: out.write(codeToAdd);
188: out.write(posScript);
189: } catch (IOException ex) {
190: throw new ItsNatException(ex);
191: }
192: }
193: }
|