/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/rwiki/trunk/rwiki-impl/impl/src/java/uk/ac/cam/caret/sakai/rwiki/component/service/impl/XSLTEntityHandler.java $ * $Id: XSLTEntityHandler.java 109558 2012-06-25 11:50:49Z matthew.buckett@oucs.ox.ac.uk $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation. * * Licensed under the Educational Community License, Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ecl1.php * * 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 uk.ac.cam.caret.sakai.rwiki.component.service.impl; import java.io.IOException; import java.io.OutputStream; import java.io.StringReader; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Vector; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.Transformer; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.TransformerHandler; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xml.serializer.OutputPropertiesFactory; import org.apache.xml.serializer.Serializer; import org.apache.xml.serializer.SerializerFactory; import org.sakaiproject.component.api.ComponentManager; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.entity.api.Entity; import org.sakaiproject.entity.api.EntityManager; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.site.api.Group; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.cover.SiteService; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.AttributesImpl; import uk.ac.cam.caret.sakai.rwiki.component.Messages; import uk.ac.cam.caret.sakai.rwiki.service.api.RenderService; import uk.ac.cam.caret.sakai.rwiki.service.api.model.RWikiEntity; import uk.ac.cam.caret.sakai.rwiki.service.api.model.RWikiObject; import uk.ac.cam.caret.sakai.rwiki.utils.DebugContentHandler; import uk.ac.cam.caret.sakai.rwiki.utils.DigestHtml; import uk.ac.cam.caret.sakai.rwiki.utils.NameHelper; import uk.ac.cam.caret.sakai.rwiki.utils.SchemaNames; import uk.ac.cam.caret.sakai.rwiki.utils.SimpleCoverage; /** * Provides a XSLT Based entity handler. It will serialise the an RWikiObject * into XML and then apply a XSLT to generate the Whole output. * * @author ieb */ public class XSLTEntityHandler extends BaseEntityHandlerImpl { private static Log log = LogFactory.getLog(XSLTEntityHandler.class); private static ThreadLocal currentRequest = new ThreadLocal(); /** * dependency */ private String anchorLinkFormat = null; /** * dependency */ private String standardLinkFormat = null; /** * dependency */ private String hrefTagFormat = null; /** * dependency */ private String xalan270ContentHandler = null; /** * dependency */ private RenderService renderService = null; /** * dependency */ private String authZPrefix = ""; //$NON-NLS-1$ /** * dependency The base name of the xslt file, relative to context root. */ private String xslt = null; /** * Control whether the xml is escaped for this handler */ private boolean escaped = true; /** * dependency The default strack trace message to use if all else fails * (pattern). */ private String defaultStackTrace; /** * A format pattern for formatting a stack trace in the xml.@param tag for * 'servletConfig'. 140 Expected * * @throws tag * for 'ServletException'. */ private String errorFormat; /** * Thread holder for the transformer */ private ThreadLocal transformerHolder = new ThreadLocal(); /** * A map containing headers to inject into the response */ private Map responseHeaders; /** * A map containing SAX Serializer properties */ private Map outputProperties; /** * A map containing transform parameters. */ private Map<String, String> transformParameters; private EntityManager entityManager; private SAXParserFactory saxParserFactory; private SerializerFactory serializerFactory; private String breadCrumbParameter = "breadcrumb"; private String breadCrumbParameterFormat = "?breadcrumb=0"; /** Configuration: allow use of alias for site id in references. */ protected boolean m_siteAlias = true; private Object load(ComponentManager cm, String name) { Object o = cm.get(name); if (o == null) { log.error("Cant find Spring component named " + name); //$NON-NLS-1$ } return o; } /** * {@inheritDoc} */ public String getDescription(Entity entity) { if (!isAvailable()) return null; if (!(entity instanceof RWikiEntity)) return null; return entity.getId(); } /** * {@inheritDoc} */ public String getUrl(Entity entity) { if (!isAvailable()) return null; if (!(entity instanceof RWikiEntity)) return null; return entity.getUrl() + getMinorType(); } /** * @return */ public static HttpServletRequest getCurrentRequest() { return (HttpServletRequest) currentRequest.get(); } /** * @param request */ public static void setCurrentRequest(HttpServletRequest request) { currentRequest.set(request); } /** * {@inheritDoc} */ public void outputContent(final Entity entity, final Entity sideBar, final HttpServletRequest request, final HttpServletResponse res) { if (!isAvailable()) return; if (!(entity instanceof RWikiEntity)) return; try { String skin = ServerConfigurationService.getString("skin.default"); //$NON-NLS-1$ String skinRepo = ServerConfigurationService.getString("skin.repo"); //$NON-NLS-1$ request.setAttribute("sakai.skin.repo", skinRepo); //$NON-NLS-1$ request.setAttribute("sakai.skin", skin); //$NON-NLS-1$ HttpSession s = request.getSession(); PageVisits pageVisits = (PageVisits) s.getAttribute(XSLTEntityHandler.class .getName() + this.getMinorType() + "_visits"); boolean withBreadcrumbs = !"0".equals(request.getParameter(breadCrumbParameter ) ); if (pageVisits == null) { pageVisits = new PageVisits(); s.setAttribute(XSLTEntityHandler.class.getName() + this.getMinorType() + "_visits", pageVisits); } RWikiEntity rwe = (RWikiEntity) entity; if (!rwe.isContainer()) { RWikiObject rwo = rwe.getRWikiObject(); pageVisits.addPage(rwo.getName()); } setCurrentRequest(request); if (responseHeaders != null) { for (Iterator i = responseHeaders.keySet().iterator(); i.hasNext();) { String name = (String) i.next(); String value = (String) responseHeaders.get(name); res.setHeader(name, value); } } OutputStream out = res.getOutputStream(); ContentHandler opch = getOutputHandler(out); ContentHandler ch = null; if (false) { ch = new DebugContentHandler(opch); } else { ch = opch; } Attributes dummyAttributes = new AttributesImpl(); ch.startDocument(); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ENTITYSERVICE, SchemaNames.EL_NSENTITYSERVICE, dummyAttributes); AttributesImpl propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_REQUEST_PATH_INFO, //$NON-NLS-1$ SchemaNames.ATTR_REQUEST_PATH_INFO, "string", request //$NON-NLS-1$ .getPathInfo()); propA.addAttribute("", SchemaNames.ATTR_REQUEST_USER, //$NON-NLS-1$ SchemaNames.ATTR_REQUEST_USER, "string", request //$NON-NLS-1$ .getRemoteUser()); propA.addAttribute("", SchemaNames.ATTR_REQUEST_PROTOCOL, //$NON-NLS-1$ SchemaNames.ATTR_REQUEST_PROTOCOL, "string", request //$NON-NLS-1$ .getProtocol()); propA.addAttribute("", SchemaNames.ATTR_REQUEST_SERVER_NAME, //$NON-NLS-1$ SchemaNames.ATTR_REQUEST_SERVER_NAME, "string", request //$NON-NLS-1$ .getServerName()); propA.addAttribute("", SchemaNames.ATTR_REQUEST_SERVER_PORT, //$NON-NLS-1$ SchemaNames.ATTR_REQUEST_SERVER_PORT, "string", String //$NON-NLS-1$ .valueOf(request.getServerPort())); propA.addAttribute("", SchemaNames.ATTR_REQUEST_REQUEST_URL, //$NON-NLS-1$ SchemaNames.ATTR_REQUEST_REQUEST_URL, "string", String //$NON-NLS-1$ .valueOf(request.getRequestURL())); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_PROPERTIES, SchemaNames.EL_NSREQUEST_PROPERTIES, propA); addRequestAttributes(ch, request); addRequestParameters(ch, request); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_PROPERTIES, SchemaNames.EL_NSREQUEST_PROPERTIES); if ( withBreadcrumbs ) { ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_PAGEVISITS, SchemaNames.EL_NSPAGEVISITS, dummyAttributes); List<String[]> pv = pageVisits.getPageNames(this.getMinorType()); for (Iterator<String[]> i = pv.iterator(); i.hasNext();) { String[] visit = i.next(); propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_URL, SchemaNames.ATTR_URL, "string", visit[0]); addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_PAGEVISIT, SchemaNames.EL_NSPAGEVISIT, propA, visit[1]); } ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_PAGEVISITS, SchemaNames.EL_NSPAGEVISITS); } ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ENTITY, SchemaNames.EL_NSENTITY, dummyAttributes); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTIES, SchemaNames.EL_NSXMLPROPERTIES, dummyAttributes); ResourceProperties rp = entity.getProperties(); for (Iterator i = rp.getPropertyNames(); i.hasNext();) { Object key = i.next(); String name = String.valueOf(key); String value = String.valueOf(rp.getProperty(name)); propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_NAME, //$NON-NLS-1$ SchemaNames.ATTR_NAME, "string", name); //$NON-NLS-1$ addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTY, SchemaNames.EL_NSXMLPROPERTY, propA, value); } propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_NAME, //$NON-NLS-1$ SchemaNames.ATTR_NAME, "string", "_handler"); //$NON-NLS-1$ //$NON-NLS-2$ addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTY, SchemaNames.EL_NSXMLPROPERTY, propA, " XSLTEntity Handler"); //$NON-NLS-1$ if (!rwe.isContainer()) { RWikiObject rwo = rwe.getRWikiObject(); propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_NAME, //$NON-NLS-1$ SchemaNames.ATTR_NAME, "string", "_title"); //$NON-NLS-1$ //$NON-NLS-2$ addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTY, SchemaNames.EL_NSXMLPROPERTY, propA, NameHelper.localizeName(rwo .getName(), rwo.getRealm())); } else { propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_NAME, //$NON-NLS-1$ SchemaNames.ATTR_NAME, "string", "_title"); //$NON-NLS-1$ //$NON-NLS-2$ addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTY, SchemaNames.EL_NSXMLPROPERTY, propA, entity.getReference()); } ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTIES, SchemaNames.EL_NSXMLPROPERTIES); /* http://jira.sakaiproject.org/browse/SAK-13281 * escapeXML is controlled via config settings */ if (!rwe.isContainer()) { RWikiObject rwo = rwe.getRWikiObject(); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_RENDEREDCONTENT, SchemaNames.EL_NSRENDEREDCONTENT, dummyAttributes); renderToXML(rwo, ch, withBreadcrumbs, this.escaped); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_RENDEREDCONTENT, SchemaNames.EL_NSRENDEREDCONTENT); } ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ENTITY, SchemaNames.EL_NSENTITY); if (sideBar != null && sideBar instanceof RWikiEntity) { RWikiEntity sbrwe = (RWikiEntity) sideBar; RWikiObject sbrwo = sbrwe.getRWikiObject(); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_SIDEBAR, SchemaNames.EL_NSSIDEBAR, dummyAttributes); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTIES, SchemaNames.EL_NSXMLPROPERTIES, dummyAttributes); propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_NAME, //$NON-NLS-1$ SchemaNames.ATTR_NAME, "string", "_title"); //$NON-NLS-1$ //$NON-NLS-2$ addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTY, SchemaNames.EL_NSXMLPROPERTY, propA, NameHelper.localizeName( sbrwo.getName(), sbrwo.getRealm())); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_XMLPROPERTIES, SchemaNames.EL_NSXMLPROPERTIES); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_RENDEREDCONTENT, SchemaNames.EL_NSRENDEREDCONTENT, dummyAttributes); renderToXML(sbrwo, ch, withBreadcrumbs, this.escaped); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_RENDEREDCONTENT, SchemaNames.EL_NSRENDEREDCONTENT); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_SIDEBAR, SchemaNames.EL_NSSIDEBAR); } ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ENTITYSERVICE, SchemaNames.EL_NSENTITYSERVICE); ch.endDocument(); } catch (Throwable ex) { log.info("Failed to serialize " + ex.getMessage()); //$NON-NLS-1$ ex.printStackTrace(); throw new RuntimeException(Messages.getString("XSLTEntityHandler.68") //$NON-NLS-1$ + ex.getLocalizedMessage(), ex); } finally { setCurrentRequest(null); } } /** * Adds an element to the content handler. * * @param ch * the content handler * @param ns * the name space of the element * @param lname * the local name * @param qname * the qname * @param attr * the attribute list * @param content * content of the element * @throws SAXException * if the underlying sax chain has a problem */ public void addElement(final ContentHandler ch, final String ns, final String lname, final String qname, final Attributes attr, final Object content) throws SAXException { ch.startElement(ns, lname, qname, attr); try { if (content != null) { char[] c = String.valueOf(content).toCharArray(); ch.characters(c, 0, c.length); } } finally { ch.endElement(ns, lname, qname); } } /** * {@inheritDoc} */ public ResourceProperties getProperties(Entity entity) { return entity.getProperties(); } /** * Serialises the rendered content of the RWiki Object to SAX * * @param rwo * @param ch * @param withBreadCrumb */ public void renderToXML(RWikiObject rwo, final ContentHandler ch, boolean withBreadCrumb, boolean escapeXML) throws SAXException, IOException { String renderedPage; try { renderedPage = render(rwo,withBreadCrumb); } catch (Exception e) { renderedPage = Messages.getString("XSLTEntityHandler.32") + rwo.getName() + Messages.getString("XSLTEntityHandler.33") + e.getClass() + Messages.getString("XSLTEntityHandler.34") + e.getMessage(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ log.info(renderedPage, e); } String contentDigest = DigestHtml.digest(renderedPage); if (contentDigest.length() > 500) { contentDigest = contentDigest.substring(0, 500); } if (renderedPage == null || renderedPage.trim().length() == 0) { renderedPage = Messages.getString("XSLTEntityHandler.35"); //$NON-NLS-1$ } if (contentDigest == null || contentDigest.trim().length() == 0) { contentDigest = Messages.getString("XSLTEntityHandler.36"); //$NON-NLS-1$ } String cdataEscapedRendered = renderedPage .replaceAll("]]>", "]]>]]><![CDATA["); //$NON-NLS-1$ //$NON-NLS-2$ String cdataContentDigest = contentDigest.replaceAll("]]>", "]]>]]><![CDATA["); //$NON-NLS-1$ //$NON-NLS-2$ /* http://jira.sakaiproject.org/browse/SAK-13281 * ensure all page content is escaped or double escaped before it goes into the parser, * if this is not done then the parser will unescape html entities during processing */ renderedPage = "<content><rendered>" + (escapeXML ? StringEscapeUtils.escapeXml(renderedPage) : renderedPage) //$NON-NLS-1$ + "</rendered><rendered-cdata><![CDATA[" + cdataEscapedRendered + "]]></rendered-cdata><contentdigest><![CDATA[" + cdataContentDigest //$NON-NLS-1$ //$NON-NLS-2$ + "]]></contentdigest></content>"; //$NON-NLS-1$ try { parseToSAX(renderedPage, ch); } catch (SAXException ex) { SimpleCoverage.cover("Failed to parse renderedPage from " + rwo.getName()); //$NON-NLS-1$ Attributes dummyAttributes = new AttributesImpl(); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ERROR, SchemaNames.EL_NSERROR, dummyAttributes); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ERRORDESC, SchemaNames.EL_NSERRORDESC, dummyAttributes); String s = Messages.getString("XSLTEntityHandler.46") //$NON-NLS-1$ + ex.getMessage(); ch.characters(s.toCharArray(), 0, s.length()); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ERRORDESC, SchemaNames.EL_NSERRORDESC); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_RAWCONTENT, SchemaNames.EL_NSRAWCONTENT, dummyAttributes); ch.characters(renderedPage.toCharArray(), 0, renderedPage.length()); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_RAWCONTENT, SchemaNames.EL_NSRAWCONTENT); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ERROR, SchemaNames.EL_NSERROR); } // SimpleCoverage.cover("Failed to parse ::\n" + renderedPage // + "\n:: from ::\n" + rwo.getContent()); // Attributes dummyAttributes = new AttributesImpl(); // ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ERROR, // SchemaNames.EL_NSERROR, dummyAttributes); // ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ERRORDESC, // SchemaNames.EL_NSERRORDESC, dummyAttributes); // String s = "The Rendered Content did not parse correctly " // + ex.getMessage(); // ch.characters(s.toCharArray(), 0, s.length()); // ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ERRORDESC, // SchemaNames.EL_NSERRORDESC); // ch.startElement(SchemaNames.NS_CONTAINER, // SchemaNames.EL_RAWCONTENT, SchemaNames.EL_NSRAWCONTENT, // dummyAttributes); // ch.characters(renderedPage.toCharArray(), 0, renderedPage.length()); // ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_RAWCONTENT, // SchemaNames.EL_NSRAWCONTENT); // ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_ERROR, // SchemaNames.EL_NSERROR); } public void parseToSAX(final String toRender, final ContentHandler ch) throws IOException, SAXException { /** * create a proxy for the stream, filtering out the start element and * end element events */ ContentHandler proxy = new ContentHandler() { public void setDocumentLocator(Locator arg0) { ch.setDocumentLocator(arg0); } public void startDocument() throws SAXException { // ignore } public void endDocument() throws SAXException { // ignore } public void startPrefixMapping(String arg0, String arg1) throws SAXException { ch.startPrefixMapping(arg0, arg1); } public void endPrefixMapping(String arg0) throws SAXException { ch.endPrefixMapping(arg0); } public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { ch.startElement(arg0, arg1, arg2, arg3); } public void endElement(String arg0, String arg1, String arg2) throws SAXException { ch.endElement(arg0, arg1, arg2); } public void characters(char[] arg0, int arg1, int arg2) throws SAXException { ch.characters(arg0, arg1, arg2); } public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException { ch.ignorableWhitespace(arg0, arg1, arg2); } public void processingInstruction(String arg0, String arg1) throws SAXException { ch.processingInstruction(arg0, arg1); } public void skippedEntity(String arg0) throws SAXException { ch.skippedEntity(arg0); } }; InputSource ins = new InputSource(new StringReader(toRender)); XMLReader xmlReader; try { SAXParser saxParser = saxParserFactory.newSAXParser(); xmlReader = saxParser.getXMLReader(); } catch (Exception e) { log.error("SAXException when creating XMLReader", e); //$NON-NLS-1$ // rethrow!! throw new SAXException(e); } xmlReader.setContentHandler(proxy); xmlReader.parse(ins); } public String render(RWikiObject rwo, boolean withBreadCrumb) { String localSpace = NameHelper.localizeSpace(rwo.getName(), rwo.getRealm()); // use site alias / mail archive alias here to render links with short URL // localSpace pattern: /site/siteId String localAliasSpace; if (m_siteAlias) { localAliasSpace = NameHelper.aliasSpace(localSpace); } else { localAliasSpace = localSpace; } ComponentPageLinkRenderImpl plr = new ComponentPageLinkRenderImpl(localAliasSpace, withBreadCrumb); plr.setAnchorURLFormat(anchorLinkFormat); plr.setStandardURLFormat(standardLinkFormat); plr.setBreadcrumbSwitch(breadCrumbParameterFormat ); plr.setUrlFormat(hrefTagFormat); if (renderService == null) { // only for testing return rwo.getContent(); } else { return renderService.renderPage(rwo, localSpace, plr); } } /** * {@inheritDoc} */ public Collection getAuthzGroups(Reference ref, String userId) { // use the resources realm, all container (folder) realms Collection rv = new Vector(); if (!isAvailable()) return rv; try { // try the resource, all the folders above it (don't include /) String paths[] = ref.getId().split(Entity.SEPARATOR); boolean container = ref.getId().endsWith(Entity.SEPARATOR); if (paths.length > 1) { StringBuffer root = new StringBuffer(Entity.SEPARATOR + paths[1] + Entity.SEPARATOR); // rv.add(root); List<String> al = new ArrayList<String>(); for (int next = 2; next < paths.length; next++) { root.append(paths[next]); if ((next < paths.length - 1) || container) { root.append(Entity.SEPARATOR); } al.add(root.toString()); } for (int i = al.size() - 1; i >= 0; i--) { // add in the sections authzgroup rv.add(authZPrefix + al.get(i)); } } // special check for group-user : the grant's in the user's My // Workspace site String parts[] = ref.getId().split(Entity.SEPARATOR); if ((parts.length > 3) && ("group-user".equals(parts[1]))) //$NON-NLS-1$ { rv.add(SiteService.siteReference(SiteService.getUserSiteId(parts[3]))); } // . how do we get a section by ID, I assume that the if (paths.length > 4 && ("group".equals(paths[3]) || "section".equals(paths[3]))) //$NON-NLS-1$ //$NON-NLS-2$ { // paths 2 is the site id, which will be of the same form as a // group id String[] testuuid = paths[2].split("-"); //$NON-NLS-1$ String[] uuidparts = paths[4].split("-"); //$NON-NLS-1$ boolean isuuid = false; String groupID = Entity.SEPARATOR + paths[1] + Entity.SEPARATOR + paths[2] + Entity.SEPARATOR + paths[3] + Entity.SEPARATOR + paths[4]; if (testuuid.length > 0 && testuuid.length == uuidparts.length) { isuuid = true; for (int i = 0; i < testuuid.length; i++) { if (testuuid[i].length() != uuidparts[i].length()) { isuuid = false; } } } if (!isuuid) { // could be a section name Reference siteRef = entityManager.newReference(ref.getContext()); Site s = (Site) siteRef.getEntity(); Collection l = s.getGroups(); for (Iterator is = l.iterator(); is.hasNext();) { Group g = (Group) is.next(); if (paths[4].equalsIgnoreCase(g.getTitle())) { groupID = g.getId(); log.debug("Found Match " + groupID); //$NON-NLS-1$ break; } } log.debug("Converted ID " + groupID); //$NON-NLS-1$ } else { log.debug("Raw ID " + groupID); //$NON-NLS-1$ } rv.add(groupID); } // TODO: At the moment we cant use ref.addSiteContextAuthzGroup // since ref context is // /site/siteid and should be siteid need to look into this // // site rv.add(SiteService.siteReference(parts[2])); // site helper rv.add("!site.helper"); //$NON-NLS-1$ } catch (Throwable e) { log.error(this + " Problem ", e); //$NON-NLS-1$ } return rv; } /** * called by spring. */ public void init() { if (!isAvailable()) return; ComponentManager cm = org.sakaiproject.component.cover.ComponentManager.getInstance(); entityManager = (EntityManager) load(cm, EntityManager.class.getName()); renderService = (RenderService) load(cm, RenderService.class.getName()); saxParserFactory = SAXParserFactory.newInstance(); saxParserFactory.setNamespaceAware(true); try { XSLTTransform xsltTransform = new XSLTTransform(); xsltTransform.setXslt(new InputSource(this.getClass().getResourceAsStream(xslt))); xsltTransform.getContentHandler(); } catch (Exception ex) { log.error("Please check that the xslt is in the classpath " //$NON-NLS-1$ + xslt,ex); throw new RuntimeException( "Failed to initialise XSLTTransformer context with xslt " //$NON-NLS-1$ + xslt, ex); } } /** * called by spring. */ public void destroy() { } /** * @see uk.co.tfd.sakai.xmlserver.api.OutputContentHandler#getOutputHandler(java.io.Writer) */ public ContentHandler getOutputHandler(Writer out) throws IOException { throw new RuntimeException("Method Not In Use "); /* if (!isAvailable()) return null; try { XSLTTransform xsltTransform = (XSLTTransform) transformerHolder.get(); if (xsltTransform == null) { xsltTransform = new XSLTTransform(); xsltTransform.setXslt(new InputSource(this.getClass() .getResourceAsStream(xslt))); transformerHolder.set(xsltTransform); } SAXResult sr = new SAXResult(); TransformerHandler th = xsltTransform.getContentHandler(); Properties p = OutputPropertiesFactory.getDefaultMethodProperties("xml"); p.putAll(outputProperties); Serializer s = SerializerFactory.getSerializer(p); s.setWriter(out); sr.setHandler(s.asContentHandler()); th.setResult(sr); return th; } catch (Exception ex) { throw new RuntimeException("Failed to create Content Handler", ex); //$NON-NLS-1$ /* * String stackTrace = null; try { StringWriter exw = new * StringWriter(); PrintWriter pw = new PrintWriter(exw); * ex.printStackTrace(pw); stackTrace = exw.toString(); } catch * (Exception ex2) { stackTrace = * MessageFormat.format(defaultStackTrace, new Object[] { * ex.getMessage() }); } out.write(MessageFormat.format(errorFormat, * new Object[] { ex.getMessage(), stackTrace })); * / } */ } public ContentHandler getOutputHandler(OutputStream out) throws IOException { if (!isAvailable()) return null; try { XSLTTransform xsltTransform = (XSLTTransform) transformerHolder.get(); if (xsltTransform == null) { xsltTransform = new XSLTTransform(); xsltTransform.setXslt(new InputSource(this.getClass() .getResourceAsStream(xslt))); transformerHolder.set(xsltTransform); } SAXResult sr = new SAXResult(); TransformerHandler th = xsltTransform.getContentHandler(); Transformer transformer = th.getTransformer(); if (transformParameters != null) { for (Map.Entry<String, String> entry: transformParameters.entrySet()) { transformer.setParameter(entry.getKey(), entry.getValue()); } } Properties p = OutputPropertiesFactory.getDefaultMethodProperties("xml"); // SAK-14388 - use the alternate XHTMLSerializer2 for Websphere environments if ("websphere".equals(ServerConfigurationService.getString("servlet.container"))) { // SAK-16712: null in java.util.Properties causes NullPointerException if (getXalan270ContentHandler() != null ) { outputProperties.put("{http://xml.apache.org/xalan}content-handler", getXalan270ContentHandler()); } } p.putAll(outputProperties); /* S_KEY_CONTENT_HANDLER:{http://xml.apache.org/xalan}content-handler S_KEY_ENTITIES:{http://xml.apache.org/xalan}entities S_KEY_INDENT_AMOUNT:{http://xml.apache.org/xalan}indent-amount S_OMIT_META_TAG:{http://xml.apache.org/xalan}omit-meta-tag S_USE_URL_ESCAPING:{http://xml.apache.org/xalan}use-url-escaping */ Serializer s = SerializerFactory.getSerializer(p); s.setOutputStream(out); sr.setHandler(s.asContentHandler()); th.setResult(sr); return th; } catch (Exception ex) { throw new RuntimeException("Failed to create Content Handler", ex); //$NON-NLS-1$ /* * String stackTrace = null; try { StringWriter exw = new * StringWriter(); PrintWriter pw = new PrintWriter(exw); * ex.printStackTrace(pw); stackTrace = exw.toString(); } catch * (Exception ex2) { stackTrace = * MessageFormat.format(defaultStackTrace, new Object[] { * ex.getMessage() }); } out.write(MessageFormat.format(errorFormat, * new Object[] { ex.getMessage(), stackTrace })); */ } } // Need to configure components correctly. /** * @return Returns the xslt. */ public String getXslt() { return xslt; } /** * @param xslt * The xslt to set. */ public void setXslt(final String xslt) { this.xslt = xslt; } /** * @return Returns the defaultStackTrace. */ public String getDefaultStackTrace() { return defaultStackTrace; } /** * @param defaultStackTrace * The defaultStackTrace to set. */ public void setDefaultStackTrace(final String defaultStackTrace) { this.defaultStackTrace = defaultStackTrace; } /** * @return Returns the errorFormat. */ public String getErrorFormat() { return errorFormat; } /** * @param errorFormat * The errorFormat to set. */ public void setErrorFormat(final String errorFormat) { this.errorFormat = errorFormat; } /** * @return Returns the authZPrefix. */ public String getAuthZPrefix() { return authZPrefix; } /** * @param authZPrefix * The authZPrefix to set. */ public void setAuthZPrefix(String authZPrefix) { this.authZPrefix = authZPrefix; } /** * @return Returns the anchorLinkFormat. */ public String getAnchorLinkFormat() { return anchorLinkFormat; } /** * @param anchorLinkFormat * The anchorLinkFormat to set. */ public void setAnchorLinkFormat(String anchorLinkFormat) { this.anchorLinkFormat = anchorLinkFormat; } /** * @return Returns the hrefTagFormat. */ public String getHrefTagFormat() { return hrefTagFormat; } /** * @param hrefTagFormat * The hrefTagFormat to set. */ public void setHrefTagFormat(String hrefTagFormat) { this.hrefTagFormat = hrefTagFormat; } /** * @return Returns the standardLinkFormat. */ public String getStandardLinkFormat() { return standardLinkFormat; } /** * @param standardLinkFormat * The standardLinkFormat to set. */ public void setStandardLinkFormat(String standardLinkFormat) { this.standardLinkFormat = standardLinkFormat; } /** * @return Returns the outputProperties. */ public Map getOutputProperties() { return outputProperties; } /** * @param outputProperties * The outputProperties to set. */ public void setOutputProperties(Map outputProperties) { this.outputProperties = outputProperties; } /** * @param transformParameters * The transform paramaters that should be passed when transforming it. */ public void setTransformParameters(Map<String,String> transformParameters) { this.transformParameters = transformParameters; } /** * @return Returns the responseHeaders. */ public Map getResponseHeaders() { return responseHeaders; } /** * @param responseHeaders * The responseHeaders to set. */ public void setResponseHeaders(Map responseHeaders) { this.responseHeaders = responseHeaders; } public void addRequestAttributes(ContentHandler ch, HttpServletRequest request) throws Exception { if (!isAvailable()) return; // add the attributes AttributesImpl dummyAttributes = new AttributesImpl(); ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_ATTRIBUTES, SchemaNames.EL_NSREQUEST_ATTRIBUTES, dummyAttributes); for (Enumeration e = request.getAttributeNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); Object attr = request.getAttribute(name); AttributesImpl propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_NAME, //$NON-NLS-1$ SchemaNames.ATTR_NAME, "string", name); //$NON-NLS-1$ if (attr instanceof Object[]) { Object[] oattr = (Object[]) attr; ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_ATTRIBUTE, SchemaNames.EL_NSREQUEST_ATTRIBUTE, propA); for (int i = 0; i < oattr.length; i++) { addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_VALUE, SchemaNames.EL_NSVALUE, dummyAttributes, oattr[i]); } ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_ATTRIBUTE, SchemaNames.EL_NSREQUEST_ATTRIBUTE); } else { ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_ATTRIBUTE, SchemaNames.EL_NSREQUEST_ATTRIBUTE, propA); addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_VALUE, SchemaNames.EL_NSVALUE, dummyAttributes, attr); ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_ATTRIBUTE, SchemaNames.EL_NSREQUEST_ATTRIBUTE); } } ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_ATTRIBUTES, SchemaNames.EL_NSREQUEST_ATTRIBUTES); } public void addRequestParameters(ContentHandler ch, HttpServletRequest request) throws Exception { if (!isAvailable()) return; AttributesImpl dummyAttributes = new AttributesImpl(); // add the request parameters ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_PARAMS, SchemaNames.EL_NSREQUEST_PARAMS, dummyAttributes); for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); String[] attr = request.getParameterValues(name); AttributesImpl propA = new AttributesImpl(); propA.addAttribute("", SchemaNames.ATTR_NAME, //$NON-NLS-1$ SchemaNames.ATTR_NAME, "string", name); //$NON-NLS-1$ ch.startElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_PARAM, SchemaNames.EL_NSREQUEST_PARAM, propA); for (int i = 0; i < attr.length; i++) { addElement(ch, SchemaNames.NS_CONTAINER, SchemaNames.EL_VALUE, SchemaNames.EL_NSVALUE, dummyAttributes, attr[i]); } ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_PARAM, SchemaNames.EL_NSREQUEST_PARAM); } ch.endElement(SchemaNames.NS_CONTAINER, SchemaNames.EL_REQUEST_PARAMS, SchemaNames.EL_REQUEST_PARAMS); } /** * @return Returns the entityManager. */ public EntityManager getEntityManager() { return entityManager; } /** * @param entityManager * The entityManager to set. */ public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } /** * @return the breadCrumbParameterFormat */ public String getBreadCrumbParameterFormat() { return breadCrumbParameterFormat; } /** * @param breadCrumbParameterFormat the breadCrumbParameterFormat to set */ public void setBreadCrumbParameterFormat(String breadCrumbParameterFormat) { this.breadCrumbParameterFormat = breadCrumbParameterFormat; } /** * @return the breadCrumbParameter */ public String getBreadCrumbParameter() { return breadCrumbParameter; } /** * @param breadCrumbParameter the breadCrumbParameter to set */ public void setBreadCrumbParameter(String breadCrumbParameter) { this.breadCrumbParameter = breadCrumbParameter; } /** * @return the xalan270ContentHandler */ public String getXalan270ContentHandler() { return xalan270ContentHandler; } /** * @param xalan270ContentHandler * the xalan270ContentHandler to set */ public void setXalan270ContentHandler(String xalan270ContentHandler) { this.xalan270ContentHandler = xalan270ContentHandler; } public boolean isEscaped() { return escaped; } public void setEscaped(boolean escaped) { this.escaped = escaped; } }