/*
Milyn - Copyright (C) 2006 - 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (version 2.1) as published by the Free Software
Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details:
http://www.gnu.org/licenses/lgpl.txt
*/
package org.milyn.util;
import freemarker.ext.dom.NodeModel;
import org.milyn.container.ExecutionContext;
import org.milyn.delivery.DOMModel;
import org.milyn.javabean.context.BeanContext;
import org.w3c.dom.Element;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* FreeMarker utility class.
* @author <a href="mailto:tom.fennelly@jboss.com">tom.fennelly@jboss.com</a>
*/
public abstract class FreeMarkerUtils {
/**
* Get a "merged" model for FreeMarker templating.
* <p/>
* This utility merges the current set of beans being managed by the
* {@link BeanContext} associated with the
* current {@link ExecutionContext}, with the contents of the {@link DOMModel}
* associated with the current {@link ExecutionContext}. This is very useful
* for templating with FreeMarker.
*
* @param executionContext The current execution context.
* @return A merged templating model.
*/
public static Map<String, Object> getMergedModel(ExecutionContext executionContext) {
Map<String, Object> beans = executionContext.getBeanContext().getBeanMap();
Map<String, Object> model = beans;
DOMModel domModel = DOMModel.getModel(executionContext);
if(!domModel.getModels().isEmpty()) {
Map<String, ElementToNodeModel> elementToNodeModelMap = getElementToNodeModelMap(executionContext);
model = new HashMap<String, Object>();
model.putAll(beans);
Set<Map.Entry<String, Element>> models = domModel.getModels().entrySet();
for (Map.Entry<String, Element> entry : models) {
NodeModel nodeModel = getNodeModel(entry.getKey(), entry.getValue(), elementToNodeModelMap);
model.put(entry.getKey(), nodeModel);
}
}
return model;
}
private static NodeModel getNodeModel(String key, Element element, Map<String, ElementToNodeModel> elementToNodeModelMap) {
ElementToNodeModel elementToNodeModel = elementToNodeModelMap.get(key);
if(elementToNodeModel == null) {
elementToNodeModel = new ElementToNodeModel();
elementToNodeModelMap.put(key, elementToNodeModel);
elementToNodeModel.element = element;
elementToNodeModel.nodeModel = NodeModel.wrap(element);
} else if(elementToNodeModel.element != element) {
// Must be a new element with the same name... update the map...
elementToNodeModel.element = element;
elementToNodeModel.nodeModel = NodeModel.wrap(element);
}
return elementToNodeModel.nodeModel;
}
private static Map<String, ElementToNodeModel> getElementToNodeModelMap(ExecutionContext executionContext) {
@SuppressWarnings("unchecked")
Map<String, ElementToNodeModel> map = (Map<String, ElementToNodeModel>) executionContext.getAttribute(ElementToNodeModel.class);
if(map == null) {
map = new HashMap<String, ElementToNodeModel>();
executionContext.setAttribute(ElementToNodeModel.class, map);
}
return map;
}
private static class ElementToNodeModel {
private Element element;
private NodeModel nodeModel;
}
}