update to press release component of sample website

- adding sub navigation to press release page to generate navigation by category in xsl (demoware for virgin)
- adding sub navigation to index.jsp to generate navigation by category (also demoware for virgin)
- cleanup of freemarker template and all sorts of fancy xpath stuff
- putting the company footer data type directly in the press release.xsd rather than having a seperate xsd.  while this makes the form creation process a bit confusing, it demonstrates why the root element name field is there, and minimizes files.  also forced me to clean up some major overloading of pr:company_footer.

changes to form data functions
- renamed getXMLDocument and getXMLDocuments to parseXMLDocument since it's now returning the document element rather than documents so that xpath traversal works (also since the document is completely useless in the context of templates)

adding bsf.jar so that hopefully someday i can write extension functions in javascript within xsl templates (couldn't get it to work).


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4217 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ariel Backenroth
2006-10-24 22:43:05 +00:00
parent 346bfe2c33
commit 3d6221f39e
19 changed files with 459 additions and 186 deletions

View File

@@ -106,6 +106,9 @@
</target>
<target name="sample-website" depends="init">
<delete failonerror="false">
<fileset dir="${dir.build}/sample-website"/>
</delete>
<mkdir dir="${dir.build}/sample-website/alfresco"/>
<copy todir="${dir.build}/sample-website/alfresco">
<fileset dir="${dir.src}/test-resources/websites/alfresco" excludes="**/.svn"/>

View File

@@ -83,18 +83,25 @@ public abstract class AbstractRenderingEngine
protected static String toAVMPath(final String parentAVMPath, final String path)
{
String parent = parentAVMPath;
if (path != null && path.length() != 0 && path.charAt(0) == '/')
if (path == null ||
path.length() == 0 ||
".".equals(path) ||
"./".equals(path))
{
return parentAVMPath;
}
if (path.charAt(0) == '/')
{
//XXXarielb this doesn't work with context paths for the website
parent = parentAVMPath.substring(0,
parentAVMPath.indexOf(':') +
('/' + AVMConstants.DIR_APPBASE +
'/' + AVMConstants.DIR_WEBAPPS).length() + 1);
'/' + AVMConstants.DIR_WEBAPPS).length());
}
if (parent.endsWith("/"))
{
parent = parent.substring(0, parent.length() - 1);
}
final String result = parent + '/' + path;
final String result =
parent + (parent.endsWith("/") || path.startsWith("/") ? path : '/' + path);
LOGGER.debug("built full avmPath " + result +
" for parent " + parentAVMPath +
" and request path " + path);

View File

@@ -57,7 +57,7 @@ public class FormDataFunctions
* @param avmPath a path within the avm repository.
* @return the parsed document.
*/
public Document getXMLDocument(final String avmPath)
public Document parseXMLDocument(final String avmPath)
throws IOException,
SAXException
{
@@ -85,7 +85,7 @@ public class FormDataFunctions
* @param avmPath a path within the avm repository.
* @return the parsed document.
*/
public Map<String, Document> getXMLDocuments(final String formName, final String avmPath)
public Map<String, Document> parseXMLDocuments(final String formName, final String avmPath)
throws IOException,
SAXException
{

View File

@@ -280,7 +280,7 @@ public final class FormsService
final OutputStreamWriter out = new OutputStreamWriter(fileOut);
final HashMap<String, String> parameters =
this.getOutputMethodParameters(formInstanceDataFileName,
this.getRenderingEngineParameters(formInstanceDataFileName,
renditionFileName,
parentPath);
re.generate(formInstanceData, parameters, out);
@@ -356,7 +356,7 @@ public final class FormsService
final OutputStreamWriter writer = new OutputStreamWriter(out);
final HashMap<String, String> parameters =
this.getOutputMethodParameters(formInstanceDataFileName,
this.getRenderingEngineParameters(formInstanceDataFileName,
renditionFileName,
parentPath);
re.generate(formInstanceData, parameters, writer);
@@ -366,15 +366,17 @@ public final class FormsService
}
}
private static HashMap<String, String> getOutputMethodParameters(final String formInstanceDataFileName,
final String renditionFileName,
final String parentAvmPath)
private static HashMap<String, String> getRenderingEngineParameters(final String formInstanceDataFileName,
final String renditionFileName,
final String parentAvmPath)
{
final HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("avm_sandbox_url", AVMConstants.buildAVMStoreUrl(parentAvmPath));
parameters.put("form_instance_data_file_name", formInstanceDataFileName);
parameters.put("rendition_file_name", renditionFileName);
parameters.put("parent_path", parentAvmPath);
final FacesContext fc = FacesContext.getCurrentInstance();
parameters.put("request_context_path", fc.getExternalContext().getRequestContextPath());
return parameters;
}

View File

@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
@@ -48,8 +49,8 @@ public class FreeMarkerRenderingEngine
private static final Log LOGGER = LogFactory.getLog(FreeMarkerRenderingEngine.class);
public FreeMarkerRenderingEngine(final NodeRef nodeRef,
final NodeService nodeService,
final ContentService contentService)
final NodeService nodeService,
final ContentService contentService)
{
super(nodeRef, nodeService, contentService);
}
@@ -78,7 +79,7 @@ public class FreeMarkerRenderingEngine
final TemplateHashModel instanceDataModel = NodeModel.wrap(xmlContent);
// build models for each of the extension functions
final TemplateModel getXMLDocumentModel = new TemplateMethodModel()
final TemplateModel parseXMLDocumentModel = new TemplateMethodModel()
{
public Object exec(final List args)
throws TemplateModelException
@@ -87,8 +88,9 @@ public class FreeMarkerRenderingEngine
{
final FormDataFunctions ef = FreeMarkerRenderingEngine.getFormDataFunctions();
final String path = FreeMarkerRenderingEngine.toAVMPath(parameters.get("parent_path"),
(String)args.get(0));
return ef.getXMLDocument(path);
(String)args.get(0));
final Document d = ef.parseXMLDocument(path);
return d != null ? d.getDocumentElement() : null;
}
catch (Exception e)
{
@@ -96,7 +98,7 @@ public class FreeMarkerRenderingEngine
}
}
};
final TemplateModel getXMLDocumentsModel = new TemplateMethodModel()
final TemplateModel parseXMLDocumentsModel = new TemplateMethodModel()
{
public Object exec(final List args)
throws TemplateModelException
@@ -104,20 +106,35 @@ public class FreeMarkerRenderingEngine
try
{
final FormDataFunctions ef = FreeMarkerRenderingEngine.getFormDataFunctions();
final String path = FreeMarkerRenderingEngine.toAVMPath(parameters.get("parent_path"),
args.size() == 1 ? "" : (String)args.get(1));
final Map<String, Document> resultMap = ef.getXMLDocuments((String)args.get(0), path);
final String path =
FreeMarkerRenderingEngine.toAVMPath(parameters.get("parent_path"),
args.size() == 1 ? "" : (String)args.get(1));
final Map<String, Document> resultMap = ef.parseXMLDocuments((String)args.get(0), path);
LOGGER.debug("received " + resultMap.size() + " documents in " + path);
// create a root document for rooting all the results. we do this
// so that each document root element has a common parent node
// and so that xpath axes work properly
final FormsService fs = FormsService.getInstance();
final DocumentBuilder documentBuilder = fs.getDocumentBuilder();
final Document rootNodeDocument = documentBuilder.newDocument();
final Element rootNodeDocumentEl =
rootNodeDocument.createElementNS(ALFRESCO_NS,
ALFRESCO_NS_PREFIX + ":file_list");
rootNodeDocumentEl.setAttribute("xmlns:" + ALFRESCO_NS_PREFIX, ALFRESCO_NS);
rootNodeDocument.appendChild(rootNodeDocumentEl);
final List<NodeModel> result = new ArrayList<NodeModel>(resultMap.size());
for (Map.Entry<String, Document> e : resultMap.entrySet())
{
final Document d = e.getValue();
final Element documentEl = d.getDocumentElement();
final Element documentEl = e.getValue().getDocumentElement();
documentEl.setAttribute("xmlns:" + ALFRESCO_NS_PREFIX, ALFRESCO_NS);
documentEl.setAttributeNS(ALFRESCO_NS,
ALFRESCO_NS_PREFIX + ":file-name",
ALFRESCO_NS_PREFIX + ":file_name",
e.getKey());
result.add(NodeModel.wrap(d));
final Node n = rootNodeDocument.importNode(documentEl, true);
rootNodeDocumentEl.appendChild(n);
result.add(NodeModel.wrap(n));
}
return result;
}
@@ -135,13 +152,13 @@ public class FreeMarkerRenderingEngine
public TemplateModel get(final String key)
throws TemplateModelException
{
if ("getXMLDocument".equals(key))
if ("parseXMLDocument".equals(key))
{
return getXMLDocumentModel;
return parseXMLDocumentModel;
}
if ("getXMLDocuments".equals(key))
if ("parseXMLDocuments".equals(key))
{
return getXMLDocumentsModel;
return parseXMLDocumentsModel;
}
return super.get(key);
}

View File

@@ -48,18 +48,18 @@ public class ServletContextFormDataFunctionsAdapter
return path;
}
public Document getXMLDocument(final String path)
public Document parseXMLDocument(final String path)
throws IOException,
SAXException
{
return super.getXMLDocument(this.toAVMPath(path));
return super.parseXMLDocument(this.toAVMPath(path));
}
public Map<String, Document> getXMLDocuments(final String formName,
final String path)
public Map<String, Document> parseXMLDocuments(final String formName,
final String path)
throws IOException,
SAXException
{
return super.getXMLDocuments(formName, this.toAVMPath(path));
return super.parseXMLDocuments(formName, this.toAVMPath(path));
}
}

View File

@@ -20,6 +20,7 @@ import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
@@ -37,6 +38,7 @@ import org.alfresco.model.WCMModel;
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.forms.FormsService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xalan.extensions.ExpressionContext;
@@ -46,7 +48,14 @@ import org.w3c.dom.*;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.SAXException;
import org.apache.bsf.BSFManager;
/**
* A rendering engine which uses xsl templates to generate renditions of
* form instance data.
*
* @author Ariel Backenroth
*/
public class XSLTRenderingEngine
extends AbstractRenderingEngine
{
@@ -54,8 +63,8 @@ public class XSLTRenderingEngine
private static final Log LOGGER = LogFactory.getLog(XSLTRenderingEngine.class);
public XSLTRenderingEngine(final NodeRef nodeRef,
final NodeService nodeService,
final ContentService contentService)
final NodeService nodeService,
final ContentService contentService)
{
super(nodeRef, nodeService, contentService);
}
@@ -67,37 +76,60 @@ public class XSLTRenderingEngine
return o == null ? null : XSLTRenderingEngine.toAVMPath(o.toString(), path);
}
public static Document getXMLDocument(final ExpressionContext ec, final String path)
public static Node parseXMLDocument(final ExpressionContext ec, final String path)
throws TransformerException,
IOException,
SAXException
{
final FormDataFunctions ef = XSLTRenderingEngine.getFormDataFunctions();
return ef.getXMLDocument(XSLTRenderingEngine.toAVMPath(ec, path));
final Document d = ef.parseXMLDocument(XSLTRenderingEngine.toAVMPath(ec, path));
return d != null ? d.getDocumentElement() : null;
}
public static NodeIterator getXMLDocuments(final ExpressionContext ec,
final String formName)
public static NodeIterator parseXMLDocuments(final ExpressionContext ec,
final String formName)
throws TransformerException,
IOException,
SAXException
{
return XSLTRenderingEngine.getXMLDocuments(ec, formName, "");
return XSLTRenderingEngine.parseXMLDocuments(ec, formName, "");
}
public static NodeIterator getXMLDocuments(final ExpressionContext ec,
final String formName,
String path)
public static NodeIterator parseXMLDocuments(final ExpressionContext ec,
final String formName,
String path)
throws TransformerException,
IOException,
SAXException
{
final FormDataFunctions ef = XSLTRenderingEngine.getFormDataFunctions();
path = XSLTRenderingEngine.toAVMPath(ec, path);
final Map<String, Document> resultMap = ef.getXMLDocuments(formName, path);
final Map<String, Document> resultMap = ef.parseXMLDocuments(formName, path);
LOGGER.debug("received " + resultMap.size() + " documents in " + path);
final List<Map.Entry<String, Document>> documents =
new ArrayList<Map.Entry<String, Document>>(resultMap.entrySet());
// create a root document for rooting all the results. we do this
// so that each document root element has a common parent node
// and so that xpath axes work properly
final FormsService fs = FormsService.getInstance();
final DocumentBuilder documentBuilder = fs.getDocumentBuilder();
final Document rootNodeDocument = documentBuilder.newDocument();
final Element rootNodeDocumentEl =
rootNodeDocument.createElementNS(ALFRESCO_NS,
ALFRESCO_NS_PREFIX + ":file_list");
rootNodeDocumentEl.setAttribute("xmlns:" + ALFRESCO_NS_PREFIX, ALFRESCO_NS);
rootNodeDocument.appendChild(rootNodeDocumentEl);
final List<Node> documents = new ArrayList<Node>(resultMap.size());
for (Map.Entry<String, Document> mapEntry : resultMap.entrySet())
{
final Element documentEl = mapEntry.getValue().getDocumentElement();
documentEl.setAttributeNS(ALFRESCO_NS,
ALFRESCO_NS_PREFIX + ":file_name",
mapEntry.getKey());
final Node n = rootNodeDocument.importNode(documentEl, true);
documents.add(n);
rootNodeDocumentEl.appendChild(n);
}
return new NodeIterator()
{
@@ -130,8 +162,7 @@ public class XSLTRenderingEngine
public Node getRoot()
{
LOGGER.error("NodeIterator.getRoot() unexpectedly called");
throw new UnsupportedOperationException();
return rootNodeDocumentEl;
}
public int getWhatToShow()
@@ -147,7 +178,7 @@ public class XSLTRenderingEngine
throw new DOMException(DOMException.INVALID_STATE_ERR, null);
if (index == documents.size())
return null;
return this.getNodeAt(index++);
return documents.get(index++);
}
public Node previousNode()
@@ -158,18 +189,7 @@ public class XSLTRenderingEngine
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;
return documents.get(index--);
}
};
}
@@ -214,8 +234,8 @@ public class XSLTRenderingEngine
throws IOException,
RenderingEngine.RenderingException
{
// XXXarielb - dirty - fix this
final String sandBoxUrl = (String)parameters.get("avm_store_url");
System.setProperty("org.apache.xalan.extensions.bsf.BSFManager",
BSFManager.class.getName());
final TransformerFactory tf = TransformerFactory.newInstance();
final FormsService ts = FormsService.getInstance();
Document xslDocument = null;
@@ -243,11 +263,17 @@ public class XSLTRenderingEngine
LOGGER.error(tce);
throw new RenderingEngine.RenderingException(tce);
}
// create a uri resolver to resolve document() calls to the virtualized
// web application
t.setURIResolver(new URIResolver()
{
public Source resolve(final String href, final String base)
throws TransformerException
{
// XXXarielb - dirty - fix this
final String sandBoxUrl = (String)parameters.get("avm_sandbox_url");
URI uri = null;
try
{

View File

@@ -23,9 +23,10 @@ import org.alfresco.web.forms.*;
/**
* Bean for getting data for company footers which are included within press release forms.
* It's used by /media/releases/get_company_footer_simple_type.jsp to aggregate all
* forms created by company-footer.xsd in /media/releases/content and generate an
* xsd simpleType enumeration which is used within the press release form (press-release.xsd).
* It's used by /media/releases/get_company_footer_choices_simple_type.jsp to aggregate all
* forms created by press-release.xsd with company_footer as the root tag name
* in /media/releases/content and generate an xsd simpleType enumeration which is used within
* the press release form.
* press-release.xsl then uses the selected company footers and loads the xml assets and
* includes their content within the generated press release renditions.
*/
@@ -42,20 +43,20 @@ public class CompanyFooterBean
*
* @return a list of populated CompanyFooterBeans.
*/
public static List<CompanyFooterBean> getCompanyFooters(final PageContext pageContext)
public static List<CompanyFooterBean> getCompanyFooterChoices(final PageContext pageContext)
throws Exception
{
final FormDataFunctions ef =
new ServletContextFormDataFunctionsAdapter(pageContext.getServletContext());
final Map<String, Document> entries = ef.getXMLDocuments("company-footer",
"/media/releases/content");
final Map<String, Document> entries =
ef.parseXMLDocuments("company-footer", "/media/releases/content");
final List<CompanyFooterBean> result = new ArrayList<CompanyFooterBean>(entries.size());
for (Map.Entry<String, Document> entry : entries.entrySet())
{
final String fileName = entry.getKey();
final Document d = entry.getValue();
final Element n = (Element)d.getElementsByTagName("alfresco:name").item(0);
final Element n = (Element)d.getElementsByTagName("pr:name").item(0);
result.add(new CompanyFooterBean(n.getFirstChild().getNodeValue(),
fileName));
}

View File

@@ -38,73 +38,145 @@ public class PressReleaseBean
*
* @return a list of populated PressReleaseBeans.
*/
public static List<PressReleaseBean> getPressReleases(final PageContext pageContext)
throws Exception
{
final FormDataFunctions ef =
new ServletContextFormDataFunctionsAdapter(pageContext.getServletContext());
public static List<PressReleaseBean> getPressReleases(final PageContext pageContext)
throws Exception
{
final FormDataFunctions ef =
new ServletContextFormDataFunctionsAdapter(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() )
{
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$", ".html");
result.add(new PressReleaseBean(t.getFirstChild().getNodeValue(),
a.getFirstChild().getNodeValue(),
date,
href));
}
return result;
}
final Map<String, Document> entries =
ef.parseXMLDocuments("press-release", "/media/releases/content");
final List<PressReleaseBean> result = new ArrayList<PressReleaseBean>(entries.size());
for (Map.Entry<String, Document> entry : entries.entrySet())
{
result.add(PressReleaseBean.loadPressRelease(entry.getValue(), entry.getKey()));
}
return result;
}
private final String title;
private final String theAbstract;
private final Date launchDate;
private final String href;
/**
* Provides a list of press releases for a specified category.
*
* @param pageContext the page context from the jsp
* @param category the category to search for
*
* @return all press releases within the specified category.
*/
public static List<PressReleaseBean> getPressReleasesInCategory(final PageContext pageContext,
final String category)
throws Exception
{
final FormDataFunctions ef =
new ServletContextFormDataFunctionsAdapter(pageContext.getServletContext());
public PressReleaseBean(final String title,
final String theAbstract,
final Date launchDate,
final String href)
{
this.title = title;
this.theAbstract = theAbstract;
this.launchDate = launchDate;
this.href = href;
}
final Map<String, Document> entries =
ef.parseXMLDocuments("press-release", "/media/releases/content");
final List<PressReleaseBean> result = new ArrayList<PressReleaseBean>(entries.size());
for (Map.Entry<String, Document> entry : entries.entrySet())
{
final Document d = entry.getValue();
final Element cEl = (Element)
d.getElementsByTagName("pr:category").item(0);
if (category.equals(cEl.getFirstChild().getNodeValue()))
{
result.add(PressReleaseBean.loadPressRelease(d, entry.getKey()));
}
}
return result;
}
/**
* Returns a set of unique categories used by the press releases in sorted order.
*
* @param pageContext the page context variable from the jsp
*
* @return a set of unique categories used by the press releases in sorted order.
*/
public static Set<String> getPressReleaseCategories(final PageContext pageContext)
throws Exception
{
final FormDataFunctions ef =
new ServletContextFormDataFunctionsAdapter(pageContext.getServletContext());
final TreeSet<String> result = new TreeSet<String>();
final Map<String, Document> entries =
ef.parseXMLDocuments("press-release", "/media/releases/content");
for (Map.Entry<String, Document> entry : entries.entrySet())
{
final Element cEl = (Element)
entry.getValue().getElementsByTagName("pr:category").item(0);
result.add(cEl.getFirstChild().getNodeValue());
}
return result;
}
/**
* Utility function to create an instance of a press release using
* form instance data.
*
* @param d the xml document
* @param fileName the filename of the file from which the document was loaded.
*
* @return a press release representing the content of the file.
*/
private static PressReleaseBean loadPressRelease(final Document d,
final String fileName)
throws Exception
{
final Element t = (Element)d.getElementsByTagName("pr:title").item(0);
final Element a = (Element)d.getElementsByTagName("pr:abstract").item(0);
final Element dateEl = (Element)d.getElementsByTagName("pr: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$", ".html");
return new PressReleaseBean(t.getFirstChild().getNodeValue(),
a.getFirstChild().getNodeValue(),
date,
href);
}
private final String title;
private final String theAbstract;
private final Date launchDate;
private final String href;
public PressReleaseBean(final String title,
final String theAbstract,
final Date launchDate,
final String href)
{
this.title = title;
this.theAbstract = theAbstract;
this.launchDate = launchDate;
this.href = href;
}
/**
* The title of the press release as defined in the xml asset.
*/
public String getTitle()
{
return this.title;
}
public String getTitle()
{
return this.title;
}
/**
* The abstract of the press release as defined in the xml asset.
*/
public String getAbstract()
{
return this.theAbstract;
}
public String getAbstract()
{
return this.theAbstract;
}
/**
* The launch date of the press release as defined in the xml asset.
*/
public Date getLaunchDate()
{
return this.launchDate;
}
public Date getLaunchDate()
{
return this.launchDate;
}
/**
/**
* Returns the url within the webapp to the xml file describing this press release
*
* @return the url to the xml file which will be something like /media/releases/content/[filename].xml

View File

@@ -7,15 +7,25 @@
<tlib-version>1.0</tlib-version>
<short-name>pr</short-name>
<uri>http://www.alfresco.org/pr</uri>
<uri>http://www.alfresco.org/alfresco/pr</uri>
<function>
<name>getPressReleases</name>
<function-class>org.alfresco.web.pr.PressReleaseBean</function-class>
<function-signature>java.util.List getPressReleases(javax.servlet.jsp.PageContext)</function-signature>
</function>
<function>
<name>getCompanyFooters</name>
<name>getPressReleasesInCategory</name>
<function-class>org.alfresco.web.pr.PressReleaseBean</function-class>
<function-signature>java.util.List getPressReleasesInCategory(javax.servlet.jsp.PageContext, java.lang.String)</function-signature>
</function>
<function>
<name>getPressReleaseCategories</name>
<function-class>org.alfresco.web.pr.PressReleaseBean</function-class>
<function-signature>java.util.Set getPressReleaseCategories(javax.servlet.jsp.PageContext)</function-signature>
</function>
<function>
<name>getCompanyFooterChoices</name>
<function-class>org.alfresco.web.pr.CompanyFooterBean</function-class>
<function-signature>java.util.List getCompanyFooters(javax.servlet.jsp.PageContext)</function-signature>
<function-signature>java.util.List getCompanyFooterChoices(javax.servlet.jsp.PageContext)</function-signature>
</function>
</taglib>

View File

@@ -39,7 +39,7 @@
<!-- register the pr tag library -->
<taglib>
<taglib-uri>http://www.alfresco.org/pr</taglib-uri>
<taglib-uri>http://www.alfresco.org/alfresco/pr</taglib-uri>
<taglib-location>/WEB-INF/pr.tld</taglib-location>
</taglib>

View File

@@ -21,7 +21,7 @@ which wants to update the list of available company footers dynamically.
<jsp:root version="1.2"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:pr="http://www.alfresco.org/pr">
xmlns:pr="http://www.alfresco.org/alfresco/pr">
<!-- xmlns:pr is mapped to /WEB-INF/pr.tld by web.xml -->
<jsp:directive.page language="java" contentType="text/html; charset=UTF-8"/>
<jsp:directive.page isELIgnored="false"/>
@@ -31,7 +31,7 @@ which wants to update the list of available company footers dynamically.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:alfresco="http://www.alfresco.org/alfresco"
elementFormDefault="qualified">
<xs:simpleType name="company_footer">
<xs:simpleType name="company_footer_choices">
<xs:restriction base="xs:string">
<xs:enumeration value="company_footer_1.xml">
<xs:annotation>
@@ -54,10 +54,10 @@ which wants to update the list of available company footers dynamically.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:alfresco="http://www.alfresco.org/alfresco"
elementFormDefault="qualified">
<xs:simpleType name="company_footer">
<xs:simpleType name="company_footer_choices">
<xs:restriction base="xs:string">
<!-- call into CompanyFooterBean to retrieve all company footers -->
<c:forEach items="${pr:getCompanyFooters(pageContext)}" var="companyFooter">
<c:forEach items="${pr:getCompanyFooterChoices(pageContext)}" var="companyFooter">
<jsp:element name="xs:enumeration">
<!-- this is the file name of the company footer -->
<jsp:attribute name="value"><c:out value="${companyFooter.fileName}"/></jsp:attribute>

View File

@@ -19,7 +19,7 @@ Produces the index page for the press release page.
<jsp:root version="1.2"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:pr="http://www.alfresco.org/pr"
xmlns:pr="http://www.alfresco.org/alfresco/pr"
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt">
<!-- xmlns:pr is mapped to /WEB-INF/pr.tld by web.xml -->
@@ -82,6 +82,25 @@ Produces the index page for the press release page.
<!-- Feature Content -->
<div id="right_content">
<div class="box_blue">
<h2>Press Releases By Category</h2>
<ul>
<!-- load all categories used by the press releases -->
<c:forEach items="${pr:getPressReleaseCategories(pageContext)}" var="category">
<li>
<c:out value="${category}"/>
<ul>
<c:forEach items="${pr:getPressReleasesInCategory(pageContext, category)}" var="pressRelease">
<li>
<jsp:element name="a">
<jsp:attribute name="href"><c:out value="${pressRelease.href}"/></jsp:attribute>
<jsp:body><c:out value="${pressRelease.title}"/></jsp:body>
</jsp:element>
</li>
</c:forEach>
</ul>
</li>
</c:forEach>
</ul>
<h2>Press Release Archive</h2>
<ul>
<li><a href="/media/releases/archives/index.html">View Archived Releases</a></li>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:alfresco="http://www.alfresco.org/alfresco"
targetNamespace="http://www.alfresco.org/alfresco"
elementFormDefault="qualified">
<xs:element name="company_footer">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="body" type="xs:anyType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -1,22 +1,31 @@
<#ftl ns_prefixes={"alfresco", "http://www.alfresco.org/alfresco"}>
--- ${.vars["/alfresco:press_release/alfresco:title"]} ---
<#ftl ns_prefixes={"D", "http://www.alfresco.org/alfresco/pr"}>
-- ${.vars["/alfresco:press_release/alfresco:abstract"]} --
<#list .vars["/alfresco:press_release/alfresco:body"] as body>
<#macro show_heading heading>
${heading}
<#list 1..heading?length as index>-</#list>
</#macro>
<@show_heading heading="Title: ${press_release.title}"/>
<@show_heading heading="Abstract: ${press_release.abstract}"/>
<#list press_release.body as body>
<#if body_index = 0>
${.vars["/alfresco:press_release/alfresco:location"]}--${.vars["/alfresco:press_release/alfresco:launch_date"]}--
${press_release.location}--${press_release.launch_date}--
</#if>
${body?trim}
</#list>
<#list .vars["/alfresco:press_release/alfresco:include_company_footer"] as cf>
<#assign cf_document=alfresco.getXMLDocument(cf)>
-- About ${cf_document["/alfresco:company_footer/alfresco:name"]} --
<#list cf_document["/alfresco:company_footer/alfresco:body"] as body>
<#list press_release.include_company_footer as cf>
<#assign cf_document=alfresco.parseXMLDocument(cf)>
<@show_heading heading="About ${cf_document.name}"/>
<#list cf_document.body as body>
${body?trim}
</#list>
</#list>
<#if .vars["/alfresco:press_release/alfresco:include_media_contacts"] = "true">
-- Media Contacts --
<#if press_release.include_media_contacts = "true">
<@show_heading heading="Media Contacts"/>
John Newton
Alfresco Software Inc.
+44 1628 860639

View File

@@ -1,9 +1,30 @@
<?xml version="1.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.
Describes a press release and related assets.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:alfresco="http://www.alfresco.org/alfresco"
targetNamespace="http://www.alfresco.org/alfresco"
xmlns:pr="http://www.alfresco.org/alfresco/pr"
targetNamespace="http://www.alfresco.org/alfresco/pr"
elementFormDefault="qualified">
<xs:include schemaLocation="/media/releases/get_company_footer_simple_type.jsp"/>
<!-- dynamically loads the company footer choices simple type -->
<xs:include schemaLocation="/media/releases/get_company_footer_choices_simple_type.jsp"/>
<xs:simpleType name="category">
<xs:restriction base="xs:string">
<xs:enumeration value="Product"/>
@@ -13,6 +34,18 @@
<xs:enumeration value="Training"/>
</xs:restriction>
</xs:simpleType>
<!-- defines the form for creating a company footer -->
<xs:element name="company_footer">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="body" type="xs:anyType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- defines the form for creating a press release -->
<xs:element name="press_release">
<xs:complexType>
<xs:sequence>
@@ -20,10 +53,10 @@
<xs:element name="abstract" type="xs:string"/>
<xs:element name="location" type="xs:string"/>
<xs:element name="body" type="xs:anyType" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="include_company_footer" type="alfresco:company_footer" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="include_company_footer" type="pr:company_footer_choices" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="include_media_contacts" type="xs:boolean" default="true"/>
<xs:element name="keywords" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="category" type="alfresco:category" default="Company"/>
<xs:element name="category" type="pr:category" default="Company"/>
<xs:element name="launch_date" type="xs:date"/>
<xs:element name="expiration_date" type="xs:date"/>
</xs:sequence>

View File

@@ -21,7 +21,7 @@ Produces an html rendition of a press release
<xsl:stylesheet version="1.0"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:alfresco="http://www.alfresco.org/alfresco"
xmlns:pr="http://www.alfresco.org/alfresco/pr"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
exclude-result-prefixes="xhtml">
<xsl:output method="html" encoding="UTF-8" indent="yes"
@@ -35,9 +35,9 @@ Produces an html rendition of a press release
<head>
<!-- include common navigation components using SSIs (see web.xml for more information) -->
<xsl:comment>#include virtual="/assets/include_in_head.html"</xsl:comment>
<title><xsl:value-of select="/alfresco:press_release/alfresco:title"/></title>
<title><xsl:value-of select="/pr:press_release/pr:title"/></title>
<meta name="description" lang="en" >
<xsl:attribute name="content"><xsl:value-of select="/alfresco:press_release/alfresco:title"/></xsl:attribute>
<xsl:attribute name="content"><xsl:value-of select="/pr:press_release/pr:title"/></xsl:attribute>
</meta>
<style type="text/css">
p.leader {
@@ -54,36 +54,99 @@ Produces an html rendition of a press release
<div id="main_content">
<!-- BEGIN MAIN CONTENT -->
<h1><xsl:value-of select="/alfresco:press_release/alfresco:title"/></h1>
<p><strong><xsl:value-of select="/alfresco:press_release/alfresco:abstract"/></strong></p>
<h1><xsl:value-of select="/pr:press_release/pr:title"/></h1>
<p><strong><xsl:value-of select="/pr:press_release/pr:abstract"/></strong></p>
<p></p>
<xsl:for-each select="/alfresco:press_release/alfresco:body">
<xsl:for-each select="/pr:press_release/pr:body">
<p>
<xsl:if test="position()=1"><xsl:value-of select="normalize-space(/alfresco:press_release/alfresco:location)"/>&#8212;<xsl:value-of select="normalize-space(/alfresco:press_release/alfresco:launch_date)"/>&#8212;</xsl:if><xsl:value-of select="normalize-space(.)" disable-output-escaping="yes"/>
<xsl:if test="position()=1"><xsl:value-of select="normalize-space(/pr:press_release/pr:location)"/>&#8212;<xsl:value-of select="normalize-space(/pr:press_release/pr:launch_date)"/>&#8212;</xsl:if><xsl:value-of select="normalize-space(.)" disable-output-escaping="yes"/>
</p>
</xsl:for-each>
<xsl:for-each select="/alfresco:press_release/alfresco:include_company_footer">
<xsl:for-each select="/pr:press_release/pr:include_company_footer">
<xsl:variable name="cf-id"><xsl:value-of select="."/></xsl:variable>
<!-- load the xml document for the company footer using a built in FormDataFunction -->
<xsl:variable name="cf" select="alfresco:getXMLDocument($cf-id)"/>
<h2>About <xsl:value-of select="$cf/alfresco:company_footer/alfresco:name"/></h2>
<xsl:for-each select="$cf/alfresco:company_footer/alfresco:body">
<xsl:variable name="cf" select="alfresco:parseXMLDocument($cf-id)"/>
<h2>About <xsl:value-of select="$cf/pr:name"/></h2>
<xsl:for-each select="$cf/pr:body">
<p><xsl:value-of select="." disable-output-escaping="yes"/></p>
</xsl:for-each>
</xsl:for-each>
<xsl:if test="/alfresco:press_release/alfresco:include_media_contacts='true'">
<xsl:if test="/pr:press_release/pr:include_media_contacts='true'">
<h2>Media Contacts</h2>
<div><p>John Newton<br />Alfresco Software Inc.<br />+44 1628 860639<br />press@alfresco.com</p></div>
<div><p>Chuck Tanowitz<br />Schwartz Communications<br />+1 781 684-0770<br />alfresco@schwartz-pr.com</p></div>
</xsl:if>
<!-- END MAIN CONTENT -->
<xsl:element name="a">
<xsl:attribute name="href"><xsl:value-of select="fn:replaceAll(string($alfresco:form_instance_data_file_name), '.xml', '.txt')"/></xsl:attribute>
<xsl:attribute name="href">
<xsl:value-of select="fn:replaceAll(string($alfresco:form_instance_data_file_name), '.xml', '.txt')"/>
</xsl:attribute>
<xsl:text>view plain text version</xsl:text>
</xsl:element>
</div>
<!-- Feature Content -->
<div id="right_content">&#160;</div>
<div id="right_content">
<div class="box_blue">
<h2>Press Releases By Category</h2>
<!-- store the current category in a variable for later comparison -->
<xsl:variable name="my_category"
select="/pr:press_release/pr:category"/>
<!-- store the current title in a variable for later comparison -->
<xsl:variable name="my_title"
select="/pr:press_release/pr:title"/>
<!-- load all press releases into a variable by calling into a form data function -->
<xsl:variable name="all_press_releases"
select="alfresco:parseXMLDocuments('press-release')"/>
<ul>
<!-- select a unique set of categories for the first level navigation -->
<xsl:for-each select="$all_press_releases[not(pr:category=preceding-sibling::pr:press_release/pr:category)]">
<xsl:sort select="pr:category"/>
<li>
<xsl:choose>
<!-- for the current category, present all press releases in this category -->
<xsl:when test="pr:category=$my_category">
<b><xsl:value-of select="pr:category"/></b>
<ul>
<!-- iterate all press releases which are in my_category -->
<xsl:for-each select="$all_press_releases[pr:category=$my_category]">
<xsl:sort select="pr:title"/>
<li>
<xsl:element name="a">
<xsl:if test="$my_title=pr:title">
<xsl:attribute name="style">font-weight:bold;</xsl:attribute>
</xsl:if>
<xsl:attribute name="href">
<xsl:value-of select="fn:replaceAll(string(@alfresco:file_name), '.xml', '.html')"/>
</xsl:attribute>
<xsl:value-of select="pr:title"/>
</xsl:element>
</li>
</xsl:for-each>
</ul>
</xsl:when>
<xsl:otherwise>
<!--
for other categories present a link to the first document in that category
with the category label
-->
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="fn:replaceAll(string(@alfresco:file_name), '.xml', '.html')"/>
</xsl:attribute>
<xsl:value-of select="pr:category"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</li>
</xsl:for-each>
</ul>
<h2>Press Release Archive</h2>
<ul>
<li><a href="/media/releases/archives/index.html">View Archived Releases</a></li>
</ul>
</div>
</div>
<div id="clear">&#160;</div>
</div>
<!--All Three End -->

View File

@@ -21,24 +21,38 @@
</head>
<body>
<div>Generated by output-method-callout.ftl</div>
<div class="name"><#noparse>${alfresco.avm_sandbox_url}</#noparse></div>
<span>${alfresco.avm_sandbox_url}</span>
<div class="name"><#noparse>${alfresco.form_instance_data_file_name}</#noparse></div>
<span>${alfresco.form_instance_data_file_name}</span>
<div class="name"><#noparse>${alfresco.rendition_file_name}</#noparse></div>
<span>${alfresco.rendition_file_name}</span>
<div class="name"><#noparse>${alfresco.parent_path}</#noparse></div>
<span>${alfresco.parent_path}</span>
<div class="name"><#noparse>${alfresco.request_context_path}</#noparse></div>
<span>${alfresco.request_context_path}</span>
<div class="name">My value accessed using <#noparse>${simple.string}</#noparse>:</div>
<span>${simple.string}</span>
<div class="name">My value accessed using <#noparse>$alfresco.getXMLDocument(${alfresco.form_instance_data_file_name})</#noparse>:</div>
<span>${alfresco.getXMLDocument(alfresco.form_instance_data_file_name).simple.string}</span>
<div class="name">My value accessed using <#noparse>$alfresco.parseXMLDocument(${alfresco.form_instance_data_file_name})</#noparse>:</div>
<span>${alfresco.parseXMLDocument(alfresco.form_instance_data_file_name).string}</span>
<div class="name">Values from xml files generated by in ${alfresco.parent_path}:</div>
<ul>
<#list alfresco.getXMLDocuments('output-method-callout') as d>
<li>${d["/simple/@alfresco:file-name"]} = ${d.simple.string}</li>
</#list>
<#list alfresco.parseXMLDocuments('output-method-callout') as d>
<li>
<div class="name">
<#noparse>${d["@alfresco:file_name"]} = ${d.string}</#noparse>
</div>
<span>${d["@alfresco:file_name"]} = ${d.string}</span>
</li>
</#list>
</ul>
</body>
</html>

View File

@@ -48,15 +48,26 @@ body
&lt;xsl:value-of select="$alfresco:parent_path"/&gt;
</div>
<span><xsl:value-of select="$alfresco:parent_path"/></span>
<div class="name">
&lt;xsl:value-of select="$alfresco:request_context_path"/&gt;
</div>
<span><xsl:value-of select="$alfresco:request_context_path"/></span>
<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($alfresco:form_instance_data_file_name):</div>
<span><xsl:value-of select="alfresco:getXMLDocument($alfresco:form_instance_data_file_name)/simple/string"/></span>
<div class="name">My value accessed using alfresco:parseXMLDocument($alfresco:form_instance_data_file_name):</div>
<span><xsl:value-of select="alfresco:parseXMLDocument($alfresco:form_instance_data_file_name)/string"/></span>
<div class="name">Values from xml files generated by in <xsl:value-of select="$alfresco: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 select="alfresco:parseXMLDocuments('output-method-callout')">
<li>
<div class="name">
&lt;xsl:value-of select="@alfresco:file_name"/&gt; = &lt;xsl:value-of select="string"/&gt;
</div>
<span>
<xsl:value-of select="@alfresco:file_name"/> = <xsl:value-of select="string"/>
</span>
</li>
</xsl:for-each>
</ul>
</body>