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;
015:
016: import java.util.HashMap;
017: import java.util.Map;
018: import org.itsnat.impl.core.dom.render.DOMRenderImpl;
019: import org.itsnat.impl.core.util.UniqueIdGenerator;
020: import org.w3c.dom.Document;
021:
022: /**
023: *
024: * @author jmarranz
025: */
026: public abstract class MarkupContainerImpl {
027: protected Map usedTemplates; // No sincronizamos porque sólo se modifica en carga del markup del template (monohilo) o por el ItsNatDocument (usado siempre en monohilo)
028: protected UniqueIdGenerator idGenerator = new UniqueIdGenerator(
029: isUniqueIdGeneratorSync());
030: protected String id;
031:
032: /** Creates a new instance of MarkupContainerImpl */
033: public MarkupContainerImpl() {
034: }
035:
036: public abstract boolean isUniqueIdGeneratorSync();
037:
038: public String generateUniqueId() {
039: return idGenerator.generateUniqueId();
040: }
041:
042: public abstract Document getDocument();
043:
044: public abstract boolean hasCachedNodes();
045:
046: public Map getUsedTemplateVersions() {
047: if (usedTemplates == null)
048: this .usedTemplates = new HashMap();
049: return usedTemplates;
050: }
051:
052: public MarkupTemplateVersionImpl getUsedMarkupTemplateVersion(
053: String id) {
054: return (MarkupTemplateVersionImpl) getUsedTemplateVersions()
055: .get(id);
056: }
057:
058: public void addMarkupTemplateVersionIfCaching(
059: MarkupTemplateVersionImpl template) {
060: // Si ya está añadido no hace nada, si ha cambiado el contenido del fragmento
061: // como el id y el objeto DocFragmentTemplateVersionImpl son diferentes, a todos los efectos
062: // es como si fuera un nuevo fragmento, no intentamos quitar la anterior versión
063: // pues no tenemos garantías de que no quede
064: // nada de la anterior versión en el documento.
065:
066: if (!template.hasCachedNodes())
067: return;
068:
069: Map usedTemplates = getUsedTemplateVersions();
070: if (usedTemplates.containsKey(template.getId()))
071: return; // Ya fue añadido, en teoría no puede cambiar (los templates contenidos son los mismos) pues ha de generarse una nueva versión, es decir un nuevo template (objecto e id) a todos los efectos
072:
073: usedTemplates.put(template.getId(), template);
074:
075: Map templatesOfTemplate = template.getUsedTemplateVersions();
076: usedTemplates.putAll(templatesOfTemplate);
077: }
078:
079: public String resolveCachedNodes(String text) {
080: if (hasCachedNodes()) {
081: int start = text.indexOf(CachedNode.getMarkCodeStart());
082: if (start == -1)
083: return text;
084:
085: StringBuffer textRes = new StringBuffer();
086: while (start != -1) {
087: int end = text.indexOf('}', start) + 1; // DEBE existir necesariamente
088: String mark = text.substring(start, end);
089: String templateId = CachedNode.getTemplateId(mark);
090: MarkupTemplateVersionImpl template = getUsedMarkupTemplateVersion(templateId);
091:
092: Map cacheMap = template.getElementCacheMap();
093: String nodeId = CachedNode.getNodeId(mark);
094: CachedNode cachedNode = (CachedNode) cacheMap
095: .get(nodeId);
096:
097: textRes.append(text.substring(0, start));
098: String cachedCode = cachedNode.getCode();
099: cachedCode = resolveCachedNodes(cachedCode); // Resuelve así el caso de nodos cacheados de fragmentos includos con <include> dentro de nodos a su vez cacheados
100: textRes.append(cachedCode);
101:
102: text = text.substring(start + mark.length());
103:
104: start = text.indexOf(CachedNode.getMarkCodeStart());
105: }
106:
107: textRes.append(text);
108:
109: text = textRes.toString();
110: }
111:
112: return text;
113: }
114:
115: public String serializeDocument(Document doc,
116: DOMRenderImpl docRender) {
117: // El Document pasado ha debido ser creado a través de este objeto
118: // pues el docRender está relacionado con el mismo (bueno con el original patrón más exactamente)
119:
120: String text = docRender.serializeDocument(doc);
121:
122: text = resolveCachedNodes(text);
123:
124: return text;
125: }
126: }
|