/*
ItsNat Java Web Application Framework
Copyright (C) 2007 Innowhere Software Services S.L., Spanish Company
Author: Jose Maria Arranz Santamaria
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. See the GNU Affero General Public
License for more details. See the copy of the GNU Affero General Public License
included in this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.itsnat.impl.core;
import java.util.HashMap;
import java.util.Map;
import org.itsnat.impl.core.dom.render.DOMRenderImpl;
import org.itsnat.impl.core.util.UniqueIdGenerator;
import org.w3c.dom.Document;
/**
*
* @author jmarranz
*/
public abstract class MarkupContainerImpl
{
protected Map usedTemplates; // No sincronizamos porque slo se modifica en carga del markup del template (monohilo) o por el ItsNatDocument (usado siempre en monohilo)
protected UniqueIdGenerator idGenerator = new UniqueIdGenerator(isUniqueIdGeneratorSync());
protected String id;
/** Creates a new instance of MarkupContainerImpl */
public MarkupContainerImpl()
{
}
public abstract boolean isUniqueIdGeneratorSync();
public String generateUniqueId()
{
return idGenerator.generateUniqueId();
}
public abstract Document getDocument();
public abstract boolean hasCachedNodes();
public Map getUsedTemplateVersions()
{
if (usedTemplates == null)
this.usedTemplates = new HashMap();
return usedTemplates;
}
public MarkupTemplateVersionImpl getUsedMarkupTemplateVersion(String id)
{
return (MarkupTemplateVersionImpl)getUsedTemplateVersions().get(id);
}
public void addMarkupTemplateVersionIfCaching(MarkupTemplateVersionImpl template)
{
// Si ya est aadido no hace nada, si ha cambiado el contenido del fragmento
// como el id y el objeto DocFragmentTemplateVersionImpl son diferentes, a todos los efectos
// es como si fuera un nuevo fragmento, no intentamos quitar la anterior versin
// pues no tenemos garantas de que no quede
// nada de la anterior versin en el documento.
if (!template.hasCachedNodes()) return;
Map usedTemplates = getUsedTemplateVersions();
if (usedTemplates.containsKey(template.getId()))
return; // Ya fue aadido, en teora no puede cambiar (los templates contenidos son los mismos) pues ha de generarse una nueva versin, es decir un nuevo template (objecto e id) a todos los efectos
usedTemplates.put(template.getId(),template);
Map templatesOfTemplate = template.getUsedTemplateVersions();
usedTemplates.putAll( templatesOfTemplate );
}
public String resolveCachedNodes(String text)
{
if (hasCachedNodes())
{
int start = text.indexOf(CachedNode.getMarkCodeStart());
if (start == -1) return text;
StringBuffer textRes = new StringBuffer();
while (start != -1)
{
int end = text.indexOf('}',start) + 1; // DEBE existir necesariamente
String mark = text.substring(start,end);
String templateId = CachedNode.getTemplateId(mark);
MarkupTemplateVersionImpl template = getUsedMarkupTemplateVersion(templateId);
Map cacheMap = template.getElementCacheMap();
String nodeId = CachedNode.getNodeId(mark);
CachedNode cachedNode = (CachedNode)cacheMap.get(nodeId);
textRes.append( text.substring(0,start) );
String cachedCode = cachedNode.getCode();
cachedCode = resolveCachedNodes(cachedCode); // Resuelve as el caso de nodos cacheados de fragmentos includos con <include> dentro de nodos a su vez cacheados
textRes.append( cachedCode );
text = text.substring(start + mark.length());
start = text.indexOf(CachedNode.getMarkCodeStart());
}
textRes.append( text );
text = textRes.toString();
}
return text;
}
public String serializeDocument(Document doc,DOMRenderImpl docRender)
{
// El Document pasado ha debido ser creado a travs de este objeto
// pues el docRender est relacionado con el mismo (bueno con el original patrn ms exactamente)
String text = docRender.serializeDocument(doc);
text = resolveCachedNodes(text);
return text;
}
}
|