mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
- 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:
@@ -115,6 +115,9 @@
|
||||
deprecation="on" debug="on" target="1.5" source="1.5"
|
||||
classpathref="classpath.compile"/>
|
||||
<mkdir dir="${dir.build}/sample-website/alfresco/ROOT/WEB-INF/lib"/>
|
||||
<jar basedir="${dir.build}/classes"
|
||||
destfile="${dir.build}/sample-website/alfresco/ROOT/WEB-INF/lib/alfresco-templating-extension.jar"
|
||||
includes="org/alfresco/web/templating/extension/*.class"/>
|
||||
<jar basedir="${dir.build}/sample-website/alfresco/ROOT/WEB-INF/classes"
|
||||
destfile="${dir.build}/sample-website/alfresco/ROOT/WEB-INF/lib/alfresco-sample-website.jar"
|
||||
includes="**/*.class"/>
|
||||
|
@@ -24,6 +24,7 @@ import javax.faces.event.ActionEvent;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.WCMModel;
|
||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
@@ -309,7 +310,7 @@ public class AVMEditBean
|
||||
tx.commit();
|
||||
|
||||
// TODO: regenerate template content
|
||||
if (nodeService.getProperty(avmRef, TemplatingService.TT_QNAME) != null)
|
||||
if (nodeService.getProperty(avmRef, WCMModel.PROP_TEMPLATE_DERIVED_FROM) != null)
|
||||
{
|
||||
OutputUtil.regenerate(avmRef,
|
||||
this.contentService,
|
||||
|
@@ -36,6 +36,7 @@ import org.alfresco.config.Config;
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.config.ConfigService;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.WCMModel;
|
||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
@@ -102,11 +103,16 @@ public class CreateWebContentWizard extends BaseContentWizard
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("generating template output for " + this.templateTypeName);
|
||||
this.nodeService.setProperty(AVMNodeConverter.ToNodeRef(-1, this.createdPath),
|
||||
TemplatingService.TT_QNAME,
|
||||
this.templateTypeName);
|
||||
TemplatingService ts = TemplatingService.getInstance();
|
||||
TemplateType tt = this.getTemplateType();
|
||||
final TemplateType tt = this.getTemplateType();
|
||||
final TemplatingService ts = TemplatingService.getInstance();
|
||||
|
||||
final Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
||||
props.put(WCMModel.PROP_TEMPLATE_DERIVED_FROM, tt.getNodeRef());
|
||||
props.put(WCMModel.PROP_TEMPLATE_DERIVED_FROM_NAME, tt.getName());
|
||||
this.nodeService.addAspect(AVMNodeConverter.ToNodeRef(-1, this.createdPath),
|
||||
WCMModel.ASPECT_TEMPLATE_DERIVED,
|
||||
props);
|
||||
|
||||
OutputUtil.generate(this.createdPath.substring(0, this.createdPath.lastIndexOf('/')),
|
||||
ts.parseXML(this.content),
|
||||
tt,
|
||||
|
@@ -23,6 +23,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.WCMModel;
|
||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||
import org.alfresco.service.cmr.avm.AVMNotFoundException;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
@@ -77,24 +78,21 @@ public class OutputUtil
|
||||
final OutputStreamWriter out = new OutputStreamWriter(fileOut);
|
||||
|
||||
final HashMap<String, String> parameters =
|
||||
getOutputMethodParameters(sandBoxUrl, fileName, generatedFileName);
|
||||
getOutputMethodParameters(sandBoxUrl, fileName, generatedFileName, parentPath);
|
||||
tom.generate(xml, tt, parameters, out);
|
||||
out.close();
|
||||
|
||||
NodeRef outputNodeRef = AVMNodeConverter.ToNodeRef(-1, fullAvmPath);
|
||||
nodeService.setProperty(outputNodeRef,
|
||||
TemplatingService.TT_QNAME,
|
||||
tt.getName());
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_TITLE, fileName);
|
||||
nodeService.addAspect(outputNodeRef, ContentModel.ASPECT_TITLED, titledProps);
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
||||
props.put(WCMModel.PROP_TEMPLATE_DERIVED_FROM, tt.getNodeRef());
|
||||
props.put(WCMModel.PROP_TEMPLATE_DERIVED_FROM_NAME, tt.getName());
|
||||
nodeService.addAspect(outputNodeRef, WCMModel.ASPECT_TEMPLATE_DERIVED, props);
|
||||
|
||||
props = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
props.put(ContentModel.PROP_TITLE, fileName);
|
||||
nodeService.addAspect(outputNodeRef, ContentModel.ASPECT_TITLED, props);
|
||||
|
||||
LOGGER.debug("generated " + generatedFileName + " using " + tom);
|
||||
|
||||
NodeRef createdNodeRef = AVMNodeConverter.ToNodeRef(-1, parentPath + '/' + fileName);
|
||||
nodeService.setProperty(createdNodeRef,
|
||||
TemplatingService.TT_GENERATED_OUTPUT_QNAME,
|
||||
outputNodeRef.toString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -114,9 +112,10 @@ public class OutputUtil
|
||||
try
|
||||
{
|
||||
final TemplatingService ts = TemplatingService.getInstance();
|
||||
final String templateTypeName = (String)
|
||||
nodeService.getProperty(nodeRef, TemplatingService.TT_QNAME);
|
||||
final TemplateType tt = ts.getTemplateType(templateTypeName);
|
||||
final NodeRef templateTypeNodeRef = (NodeRef)
|
||||
nodeService.getProperty(nodeRef, WCMModel.PROP_TEMPLATE_DERIVED_FROM);
|
||||
|
||||
final TemplateType tt = ts.getTemplateType(templateTypeNodeRef);
|
||||
|
||||
final ContentReader reader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
|
||||
final Document xml = ts.parseXML(reader.getContentInputStream());
|
||||
@@ -147,7 +146,7 @@ public class OutputUtil
|
||||
|
||||
final OutputStreamWriter writer = new OutputStreamWriter(out);
|
||||
final HashMap<String, String> parameters =
|
||||
getOutputMethodParameters(sandBoxUrl, fileName, generatedFileName);
|
||||
getOutputMethodParameters(sandBoxUrl, fileName, generatedFileName, parentPath);
|
||||
tom.generate(xml, tt, parameters, writer);
|
||||
writer.close();
|
||||
LOGGER.debug("generated " + fileName + " using " + tom);
|
||||
@@ -163,12 +162,14 @@ public class OutputUtil
|
||||
|
||||
private static HashMap<String, String> getOutputMethodParameters(final String sandBoxUrl,
|
||||
final String fileName,
|
||||
final String generatedFileName)
|
||||
final String generatedFileName,
|
||||
final String parentPath)
|
||||
{
|
||||
final HashMap<String, String> parameters = new HashMap<String, String>();
|
||||
parameters.put("avm_store_url", sandBoxUrl);
|
||||
parameters.put("derived_from_file_name", fileName);
|
||||
parameters.put("generated_file_name", generatedFileName);
|
||||
parameters.put("parent_path", parentPath);
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
@@ -16,10 +16,11 @@
|
||||
*/
|
||||
package org.alfresco.web.templating;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.w3c.dom.Document;
|
||||
import java.util.List;
|
||||
import java.net.URI;
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Encapsulation of a template type.
|
||||
@@ -37,6 +38,8 @@ public interface TemplateType
|
||||
/** the xml schema for this template type */
|
||||
public Document getSchema();
|
||||
|
||||
public NodeRef getNodeRef();
|
||||
|
||||
//XXXarielb not used currently and not sure if it's necessary...
|
||||
// public void addInputMethod(final TemplateInputMethod in);
|
||||
|
||||
|
@@ -55,19 +55,6 @@ import org.alfresco.web.bean.repository.Repository;
|
||||
public final class TemplatingService implements Serializable
|
||||
{
|
||||
|
||||
/**
|
||||
* temporary location of the property on nodes that are xml files created
|
||||
* by templating.
|
||||
*/
|
||||
public static final org.alfresco.service.namespace.QName TT_QNAME =
|
||||
org.alfresco.service.namespace.QName.createQName(org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI, "tt");
|
||||
|
||||
/**
|
||||
* temporary location of the property on nodes generated from xml assets.
|
||||
*/
|
||||
public static final org.alfresco.service.namespace.QName TT_GENERATED_OUTPUT_QNAME =
|
||||
org.alfresco.service.namespace.QName.createQName(org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI, "tt_generated_output");
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(TemplatingService.class);
|
||||
|
||||
/** the single instance initialized using spring */
|
||||
@@ -194,6 +181,11 @@ public final class TemplatingService implements Serializable
|
||||
}
|
||||
}
|
||||
|
||||
public TemplateType getTemplateType(final NodeRef nodeRef)
|
||||
{
|
||||
return this.newTemplateType(nodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* instantiate a template type. for now this will always generate the
|
||||
* xforms implementation, but will at some point be configurable such that
|
||||
|
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.templating.extension;
|
||||
|
||||
import org.alfresco.model.WCMModel;
|
||||
import org.alfresco.repo.avm.AVMRemote;
|
||||
import org.alfresco.repo.avm.AVMRemoteInputStream;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMNotFoundException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.SAXException;
|
||||
import javax.xml.parsers.*;
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ExtensionFunctions
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog(ExtensionFunctions.class);
|
||||
|
||||
private static DocumentBuilder documentBuilder;
|
||||
|
||||
private final AVMRemote avmRemote;
|
||||
|
||||
public ExtensionFunctions(final AVMRemote avmRemote)
|
||||
{
|
||||
this.avmRemote = avmRemote;
|
||||
}
|
||||
|
||||
public Document getXMLDocument(final String avmPath)
|
||||
throws IOException,
|
||||
SAXException
|
||||
{
|
||||
final DocumentBuilder db = this.getDocumentBuilder();
|
||||
final InputStream istream =
|
||||
new AVMRemoteInputStream(this.avmRemote.getInputHandle(-1, avmPath),
|
||||
this.avmRemote);
|
||||
|
||||
Document result;
|
||||
try
|
||||
{
|
||||
return db.parse(istream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
istream.close();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Document> getXMLDocuments(final String templateTypeName, final String avmPath)
|
||||
throws IOException,
|
||||
SAXException
|
||||
{
|
||||
final Map<String, AVMNodeDescriptor> entries =
|
||||
this.avmRemote.getDirectoryListing(-1, avmPath);
|
||||
final DocumentBuilder db = this.getDocumentBuilder();
|
||||
final Map<String, Document> result = new HashMap<String, Document>();
|
||||
for (Map.Entry<String, AVMNodeDescriptor> entry : entries.entrySet())
|
||||
{
|
||||
final String entryName = entry.getKey();
|
||||
AVMNodeDescriptor entryNode = entry.getValue();
|
||||
if (entryNode.isFile())
|
||||
{
|
||||
final PropertyValue pv =
|
||||
this.avmRemote.getNodeProperty(-1,
|
||||
avmPath + '/' + entryName,
|
||||
WCMModel.PROP_TEMPLATE_DERIVED_FROM_NAME);
|
||||
if (pv != null &&
|
||||
pv.getStringValue() != null &&
|
||||
((String)pv.getStringValue()).equals(templateTypeName))
|
||||
{
|
||||
|
||||
InputStream istream = null;
|
||||
try
|
||||
{
|
||||
istream = new AVMRemoteInputStream(this.avmRemote.getInputHandle(-1, avmPath + '/' + entryName),
|
||||
this.avmRemote);
|
||||
}
|
||||
catch (AVMNotFoundException avmnfe)
|
||||
{
|
||||
// this is most likely happening because this is the current file we're generating
|
||||
// and the avm is telling us that it has no content yet. we won't hit this once
|
||||
// we have a way of distinguishing templateoutputmethodgenerated
|
||||
// from templategenerated
|
||||
LOGGER.debug("skipping "+ entryName, avmnfe);
|
||||
}
|
||||
try
|
||||
{
|
||||
result.put(entryName, db.parse(istream));
|
||||
}
|
||||
catch (SAXException sax)
|
||||
{
|
||||
// this is most likely happening because we have the same property for defined
|
||||
// for tempalteoutputmethodderived and templatederived so we can't distinguish them right now
|
||||
// need to clean this up
|
||||
LOGGER.debug("error parsing " + entryName+ "... skipping", sax);
|
||||
}
|
||||
finally
|
||||
{
|
||||
istream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static DocumentBuilder getDocumentBuilder()
|
||||
{
|
||||
if (ExtensionFunctions.documentBuilder == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
dbf.setValidating(false);
|
||||
ExtensionFunctions.documentBuilder = dbf.newDocumentBuilder();
|
||||
}
|
||||
catch (ParserConfigurationException pce)
|
||||
{
|
||||
LOGGER.error(pce);
|
||||
}
|
||||
}
|
||||
return ExtensionFunctions.documentBuilder;
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.templating.extension;
|
||||
|
||||
import org.alfresco.jndi.AVMFileDirContext;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.SAXException;
|
||||
import javax.servlet.ServletContext;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
public class ServletContextExtensionFunctionsAdapter
|
||||
extends ExtensionFunctions
|
||||
{
|
||||
|
||||
private final ServletContext servletContext;
|
||||
|
||||
public ServletContextExtensionFunctionsAdapter(final ServletContext servletContext)
|
||||
{
|
||||
super(AVMFileDirContext.getAVMRemote());
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
private String toAVMPath(String path)
|
||||
{
|
||||
// The real_path will look somethign like this:
|
||||
// /alfresco.avm/avm.alfresco.localhost/$-1$alfreco-guest-main:/appBase/avm_webapps/my_webapp
|
||||
path = this.servletContext.getRealPath(path);
|
||||
|
||||
// The avm_path to the root of the context will look something like this:
|
||||
// alfreco-guest-main:/appBase/avm_webapps/my_webapp
|
||||
path = path.substring(path.indexOf('$', path.indexOf('$') + 1) + 1);
|
||||
path = path.replace('\\','/');
|
||||
return path;
|
||||
}
|
||||
|
||||
public Document getXMLDocument(final String path)
|
||||
throws IOException,
|
||||
SAXException
|
||||
{
|
||||
return super.getXMLDocument(this.toAVMPath(path));
|
||||
}
|
||||
|
||||
public Map<String, Document> getXMLDocuments(final String templateTypeName,
|
||||
final String path)
|
||||
throws IOException,
|
||||
SAXException
|
||||
{
|
||||
return super.getXMLDocuments(templateTypeName, this.toAVMPath(path));
|
||||
}
|
||||
}
|
@@ -84,6 +84,11 @@ public class TemplateTypeImpl
|
||||
return this.schema;
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return this.schemaNodeRef;
|
||||
}
|
||||
|
||||
public List<TemplateInputMethod> getInputMethods()
|
||||
{
|
||||
return INPUT_METHODS;
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -19,6 +19,7 @@ package org.alfresco.web.pr;
|
||||
import java.util.*;
|
||||
import javax.servlet.jsp.PageContext;
|
||||
import org.w3c.dom.*;
|
||||
import org.alfresco.web.templating.extension.*;
|
||||
|
||||
public class CompanyFooterBean
|
||||
{
|
||||
@@ -26,16 +27,18 @@ public class CompanyFooterBean
|
||||
public static List<CompanyFooterBean> getCompanyFooters(final PageContext pageContext)
|
||||
throws Exception
|
||||
{
|
||||
final Map<String, Document> entries = Util.loadXMLDocuments(pageContext,
|
||||
"/media/releases/content/company_footers",
|
||||
"alfresco:company-footer");
|
||||
final ExtensionFunctions ef =
|
||||
new ServletContextExtensionFunctionsAdapter(pageContext.getServletContext());
|
||||
|
||||
final Map<String, Document> entries = ef.getXMLDocuments("company-footer",
|
||||
"/media/releases/content/company_footers");
|
||||
final List<CompanyFooterBean> result = new ArrayList<CompanyFooterBean>(entries.size());
|
||||
for (Map.Entry<String, Document> entry : entries.entrySet())
|
||||
{
|
||||
String fileName = entry.getKey();
|
||||
Document d = entry.getValue();
|
||||
Element n = (Element)d.getElementsByTagName("alfresco:name").item(0);
|
||||
String href = "/media/releases/content/company_footers/" + fileName;
|
||||
final String fileName = entry.getKey();
|
||||
final Document d = entry.getValue();
|
||||
final Element n = (Element)d.getElementsByTagName("alfresco:name").item(0);
|
||||
final String href = "/media/releases/content/company_footers/" + fileName;
|
||||
result.add(new CompanyFooterBean(n.getFirstChild().getNodeValue(),
|
||||
href));
|
||||
}
|
||||
|
@@ -20,24 +20,26 @@ import java.util.*;
|
||||
import java.text.*;
|
||||
import javax.servlet.jsp.PageContext;
|
||||
import org.w3c.dom.*;
|
||||
import org.alfresco.web.templating.extension.*;
|
||||
|
||||
public class PressReleaseBean
|
||||
{
|
||||
public static List<PressReleaseBean> getPressReleases(final PageContext pageContext)
|
||||
throws Exception
|
||||
{
|
||||
final Map<String, Document> entries = Util.loadXMLDocuments(pageContext,
|
||||
"/media/releases/content",
|
||||
"alfresco:press-release");
|
||||
final ExtensionFunctions ef =
|
||||
new ServletContextExtensionFunctionsAdapter(pageContext.getServletContext());
|
||||
|
||||
final Map<String, Document> entries = ef.getXMLDocuments("press-release", "/media/releases/content");
|
||||
final List<PressReleaseBean> result = new ArrayList<PressReleaseBean>(entries.size());
|
||||
for (Map.Entry<String, Document> entry : entries.entrySet() )
|
||||
{
|
||||
String fileName = entry.getKey();
|
||||
Document d = entry.getValue();
|
||||
Element t = (Element)d.getElementsByTagName("alfresco:title").item(0);
|
||||
Element a = (Element)d.getElementsByTagName("alfresco:abstract").item(0);
|
||||
Element dateEl = (Element)d.getElementsByTagName("alfresco:launch_date").item(0);
|
||||
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(dateEl.getFirstChild().getNodeValue());
|
||||
final String fileName = entry.getKey();
|
||||
final Document d = entry.getValue();
|
||||
final Element t = (Element)d.getElementsByTagName("alfresco:title").item(0);
|
||||
final Element a = (Element)d.getElementsByTagName("alfresco:abstract").item(0);
|
||||
final Element dateEl = (Element)d.getElementsByTagName("alfresco:launch_date").item(0);
|
||||
final Date date = new SimpleDateFormat("yyyy-MM-dd").parse(dateEl.getFirstChild().getNodeValue());
|
||||
String href = "/media/releases/content/" + fileName;
|
||||
href = href.replaceAll(".xml$", ".shtml");
|
||||
result.add(new PressReleaseBean(t.getFirstChild().getNodeValue(),
|
||||
|
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.web.pr;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import javax.servlet.jsp.PageContext;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import org.alfresco.jndi.*;
|
||||
import org.alfresco.repo.avm.AVMRemote;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.w3c.dom.*;
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
public class Util
|
||||
{
|
||||
|
||||
public static Map<String, Document> loadXMLDocuments(final PageContext pageContext,
|
||||
final String path,
|
||||
final String documentElementNodeName)
|
||||
throws Exception
|
||||
{
|
||||
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
dbf.setValidating(false);
|
||||
final DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
|
||||
// The real_path will look somethign like this:
|
||||
// /alfresco.avm/avm.alfresco.localhost/$-1$alfreco-guest-main:/appBase/avm_webapps/my_webapp
|
||||
final String realPath = pageContext.getServletContext().getRealPath(path);
|
||||
|
||||
// The avm_path to the root of the context will look something like this:
|
||||
// alfreco-guest-main:/appBase/avm_webapps/my_webapp
|
||||
String avmPath = realPath.substring(realPath.indexOf('$', realPath.indexOf('$') + 1) + 1);
|
||||
avmPath = avmPath.replace('\\','/');
|
||||
|
||||
final AVMRemote avm_remote = AVMFileDirContext.getAVMRemote();
|
||||
final Map<String, AVMNodeDescriptor> entries = avm_remote.getDirectoryListing(-1, avmPath);
|
||||
|
||||
Map<String, Document> result = new HashMap<String, Document>();
|
||||
for (Map.Entry<String, AVMNodeDescriptor> entry : entries.entrySet() )
|
||||
{
|
||||
final String entryName = entry.getKey();
|
||||
AVMNodeDescriptor entryNode = entry.getValue();
|
||||
if (entryNode.isFile())
|
||||
{
|
||||
final InputStream istream =
|
||||
new AVMRemoteInputStream(avm_remote.getInputHandle(-1, avmPath + '/' + entryName),
|
||||
avm_remote );
|
||||
try
|
||||
{
|
||||
final Document d = db.parse(istream);
|
||||
if (documentElementNodeName.equals(d.getDocumentElement().getNodeName()))
|
||||
result.put(entryName, d);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
istream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
elementFormDefault="qualified">
|
||||
<xs:element name="simple">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="string" type="xs:string" default="default string value"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xhtml="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
exclude-result-prefixes="xhtml">
|
||||
|
||||
<xsl:output method="html" version="4.01" encoding="UTF-8" indent="yes"
|
||||
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
doctype-system="http://www.w3.org/TR/html4/loose.dtd"/>
|
||||
<xsl:preserve-space elements="*"/>
|
||||
|
||||
<xsl:variable name="my_variable">my_variable has a value</xsl:variable>
|
||||
<xsl:variable name="my_variable_as_arg">my_variable_as_arg has a value</xsl:variable>
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body
|
||||
{
|
||||
font-family: Tahoma, Arial, Helvetica, sans-serif;
|
||||
background-color: white;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.name
|
||||
{
|
||||
color: #003366;
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
<title>Simple Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>Generated by output-method-callout.xsl</div>
|
||||
<div class="name">My value accessed using /simple/string:</div>
|
||||
<span><xsl:value-of select="/simple/string"/></span>
|
||||
<div class="name">My value accessed using alfresco:getXMLDocument(<xsl:value-of select="$derived_from_file_name"/>):</div>
|
||||
<span><xsl:value-of select="alfresco:getXMLDocument($derived_from_file_name)/simple/string"/></span>
|
||||
<div class="name">Values from xml files generated by in <xsl:value-of select="$parent_path"/>:</div>
|
||||
<ul>
|
||||
<xsl:for-each select="alfresco:getXMLDocuments('output-method-callout', '')/simple">
|
||||
<li><xsl:value-of select="@alfresco:file-name"/> = <xsl:value-of select="string"/></li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
@@ -64,7 +64,9 @@ if (upload == null || upload.getFile() == null)
|
||||
</f:verbatim>
|
||||
</h:column>
|
||||
<%
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
%>
|
||||
<h:outputText id="template-output-method-file-name"
|
||||
value="#{WizardManager.bean.templateOutputMethodFileName}"/>
|
||||
|
@@ -24,6 +24,7 @@
|
||||
<%@ page isELIgnored="false" %>
|
||||
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
|
||||
<%@ page import="org.alfresco.web.bean.wcm.*,
|
||||
org.alfresco.model.WCMModel,
|
||||
org.alfresco.service.cmr.repository.*,
|
||||
org.alfresco.web.bean.content.*,
|
||||
org.alfresco.web.templating.*" %>
|
||||
@@ -35,9 +36,9 @@
|
||||
final AVMBrowseBean browseBean = (AVMBrowseBean)session.getAttribute("AVMBrowseBean");
|
||||
NodeRef nr = browseBean.getAvmActionNode().getNodeRef();
|
||||
final AVMEditBean editBean = (AVMEditBean)session.getAttribute("AVMEditBean");
|
||||
String ttName = (String)browseBean.getNodeService().getProperty(nr, TemplatingService.TT_QNAME);
|
||||
final NodeRef ttNodeRef = (NodeRef)browseBean.getNodeService().getProperty(nr, WCMModel.PROP_TEMPLATE_DERIVED_FROM);
|
||||
final TemplatingService ts = TemplatingService.getInstance();
|
||||
final TemplateType tt = ts.getTemplateType(ttName);
|
||||
final TemplateType tt = ts.getTemplateType(ttNodeRef);
|
||||
TemplateInputMethod tim = tt.getInputMethods().get(0);
|
||||
final InstanceData instanceData = new InstanceData()
|
||||
{
|
||||
|
Reference in New Issue
Block a user