- moving AVMRemoteInputStream from jndi-client project to repo project

- extracting utility methods from sample website into generalized extension functions that can be used from xsl, freemarker (i hope), and jsp.  they all use AVMRemote to access data and each context has it's own adapter.
- implemented callout functions from xsl.  able to load multiple documents and traverse them.
- removed QNames from TemplatingService and added them to WCMModel.  this will break edit on any existing assets - you'll have to create new ones that have the right properties.  still not happy with model since besides not having child associations in place, i don't have a way of differentiating between the generated xmls and the other generated assets.  major bug.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4138 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ariel Backenroth
2006-10-18 06:20:50 +00:00
parent a2f161b731
commit 2e3cbebd82
17 changed files with 552 additions and 177 deletions

View File

@@ -84,6 +84,11 @@ public class TemplateTypeImpl
return this.schema;
}
public NodeRef getNodeRef()
{
return this.schemaNodeRef;
}
public List<TemplateInputMethod> getInputMethods()
{
return INPUT_METHODS;

View File

@@ -19,7 +19,7 @@ package org.alfresco.web.templating.xforms;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.*;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
@@ -34,20 +34,28 @@ import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.alfresco.model.WCMModel;
import org.alfresco.repo.avm.AVMRemote;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.web.bean.wcm.AVMConstants;
import org.alfresco.web.templating.*;
import org.alfresco.web.templating.extension.ExtensionFunctions;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.chiba.xml.util.DOMUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.apache.xalan.extensions.ExpressionContext;
import org.apache.xpath.objects.XObject;
import org.apache.xml.utils.QName;
import org.w3c.dom.*;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.SAXException;
public class XSLTOutputMethod
implements TemplateOutputMethod
{
private static final String ALFRESCO_NS = "http://www.alfresco.org/alfresco";
private static final String ALFRESCO_NS_PREFIX = "alfresco";
private static final Log LOGGER = LogFactory.getLog(XSLTOutputMethod.class);
@@ -62,6 +70,170 @@ public class XSLTOutputMethod
this.nodeService = nodeService;
}
//XXXarielb this is totally dirty - need to figure a better way to do this
private static AVMRemote getAVMRemote()
{
final javax.faces.context.FacesContext fc =
javax.faces.context.FacesContext.getCurrentInstance();
final org.springframework.web.context.WebApplicationContext wac =
org.springframework.web.jsf.FacesContextUtils.getRequiredWebApplicationContext(fc);
return (AVMRemote)wac.getBean("avmRemote");
}
private static ExtensionFunctions getExtensionFunctions()
{
return new ExtensionFunctions(XSLTOutputMethod.getAVMRemote());
}
private static String toAVMPath(final ExpressionContext ec, String path)
throws TransformerException
{
final XObject o = ec.getVariableOrParam(new QName("parent_path"));
if (o == null)
return null;
String avmPath = o.toString();
if (path != null && path.length() != 0 && path.charAt(0) == '/')
{
avmPath = avmPath.substring(0,
avmPath.indexOf(':') +
('/' + AVMConstants.DIR_APPBASE +
'/' + AVMConstants.DIR_WEBAPPS).length() + 1);
}
return avmPath + (avmPath.endsWith("/") ? path : '/' + path);
}
public static Document getXMLDocument(final ExpressionContext ec, final String path)
throws TransformerException,
IOException,
SAXException
{
final ExtensionFunctions ef = XSLTOutputMethod.getExtensionFunctions();
return ef.getXMLDocument(XSLTOutputMethod.toAVMPath(ec, path));
}
public static NodeIterator getXMLDocuments(final ExpressionContext ec,
final String templateTypeName,
String path)
throws TransformerException,
IOException,
SAXException
{
final ExtensionFunctions ef = XSLTOutputMethod.getExtensionFunctions();
path = XSLTOutputMethod.toAVMPath(ec, path);
final Map<String, Document> resultMap = ef.getXMLDocuments(templateTypeName, path);
LOGGER.debug("received " + resultMap.size() + " documents in " + path);
final List<Map.Entry<String, Document>> documents =
new ArrayList<Map.Entry<String, Document>>(resultMap.entrySet());
return new NodeIterator()
{
private int index = 0;
private boolean detached = false;
public void detach()
{
LOGGER.debug("detaching NodeIterator");
resultMap.clear();
documents.clear();
this.detached = true;
}
public boolean getExpandEntityReferences()
{
return true;
}
public NodeFilter getFilter()
{
return new NodeFilter()
{
public short acceptNode(final Node n)
{
return NodeFilter.FILTER_ACCEPT;
}
};
}
public Node getRoot()
{
LOGGER.error("NodeIterator.getRoot() unexpectedly called");
throw new UnsupportedOperationException();
}
public int getWhatToShow()
{
return NodeFilter.SHOW_ALL;
}
public Node nextNode()
throws DOMException
{
LOGGER.debug("NodeIterator.nextNode(" + index + ")");
if (this.detached)
throw new DOMException(DOMException.INVALID_STATE_ERR, null);
if (index == documents.size())
return null;
return this.getNodeAt(index++);
}
public Node previousNode()
throws DOMException
{
LOGGER.debug("NodeIterator.previousNode(" + index + ")");
if (this.detached)
throw new DOMException(DOMException.INVALID_STATE_ERR, null);
if (index == -1)
return null;
return this.getNodeAt(index--);
}
private Document getNodeAt(int index)
{
final Document d = documents.get(index).getValue();
final Element documentEl = d.getDocumentElement();
documentEl.setAttribute("xmlns:" + ALFRESCO_NS_PREFIX, ALFRESCO_NS);
documentEl.setAttributeNS(ALFRESCO_NS,
ALFRESCO_NS_PREFIX + ":file-name",
documents.get(index).getKey());
return d;
}
};
}
private void addScript(final Document d)
{
final Element docEl = d.getDocumentElement();
final String XALAN_NS = "http://xml.apache.org/xalan";
final String XALAN_NS_PREFIX = "xalan";
docEl.setAttribute("xmlns:" + XALAN_NS_PREFIX, XALAN_NS);
docEl.setAttribute("xmlns:" + ALFRESCO_NS_PREFIX, ALFRESCO_NS);
final Element compEl = d.createElementNS(XALAN_NS, XALAN_NS_PREFIX + ":component");
compEl.setAttribute("prefix", "alfresco");
docEl.appendChild(compEl);
final Element scriptEl = d.createElementNS(XALAN_NS, XALAN_NS_PREFIX + ":script");
scriptEl.setAttribute("lang", "javaclass");
scriptEl.setAttribute("src", XALAN_NS_PREFIX + "://" + this.getClass().getName());
compEl.appendChild(scriptEl);
}
private void addParameters(final Map<String, String> parameters,
final Document xslDocument)
{
final Element docEl = xslDocument.getDocumentElement();
final String XSL_NS = docEl.getNamespaceURI();
final String XSL_NS_PREFIX = docEl.getPrefix();
for (Map.Entry<String, String> e : parameters.entrySet())
{
final Element el = xslDocument.createElementNS(XSL_NS, XSL_NS_PREFIX + ":variable");
el.setAttribute("name", e.getKey());
el.appendChild(xslDocument.createTextNode(e.getValue()));
docEl.insertBefore(el, docEl.getFirstChild());
}
}
public void generate(final Document xmlContent,
final TemplateType tt,
final Map<String, String> parameters,
@@ -76,7 +248,11 @@ public class XSLTOutputMethod
final String sandBoxUrl = (String)parameters.get("avm_store_url");
final TransformerFactory tf = TransformerFactory.newInstance();
final TemplatingService ts = TemplatingService.getInstance();
final DOMSource source = new DOMSource(ts.parseXML(this.nodeRef));
final Document xslDocument = ts.parseXML(this.nodeRef);
this.addScript(xslDocument);
this.addParameters(parameters, xslDocument);
final DOMSource source = new DOMSource(xslDocument);
final Templates templates = tf.newTemplates(source);
final Transformer t = templates.newTransformer();
t.setURIResolver(new URIResolver()
@@ -108,12 +284,6 @@ public class XSLTOutputMethod
}
});
for (Map.Entry<String, String> e : parameters.entrySet())
{
t.setParameter(e.getKey(), e.getValue());
}
LOGGER.debug("setting parameter avm_store_url=" + sandBoxUrl);
final StreamResult result = new StreamResult(out);
try
{