org.sakaiproject.metaobj.shared.control.XsltArtifactView.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.metaobj.shared.control.XsltArtifactView.java

Source

/*******************************************************************************
 * $URL$
 * $Id$
 * **********************************************************************************
 *
 * Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation
 *
 * Licensed under the Educational Community License, Version 2.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/ECL-2.0
 *
 * 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.sakaiproject.metaobj.shared.control;

import org.springframework.web.servlet.view.xslt.AbstractXsltView;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.util.NestedServletException;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.validation.FieldError;
import org.springframework.validation.BindingResultUtils;
import org.jdom.transform.JDOMSource;
import org.jdom.Element;
import org.jdom.Document;
import org.sakaiproject.content.api.ResourceEditingHelper;
import org.sakaiproject.content.api.ResourceToolAction;
import org.sakaiproject.metaobj.shared.mgt.StructuredArtifactDefinitionManager;
import org.sakaiproject.metaobj.shared.model.Artifact;
import org.sakaiproject.metaobj.shared.model.ElementBean;
import org.sakaiproject.metaobj.shared.model.Id;
import org.sakaiproject.metaobj.shared.FormHelper;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.tool.api.ToolSession;
import org.sakaiproject.tool.cover.SessionManager;
import org.sakaiproject.tool.cover.ToolManager;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.util.Web;

import javax.xml.transform.*;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.Map.Entry;
import java.io.InputStream;

/**
 * Created by IntelliJ IDEA.
 * User: johnellis
 * Date: Oct 30, 2006
 * Time: 10:10:42 AM
 * To change this template use File | Settings | File Templates.
 */
public class XsltArtifactView extends AbstractXsltView {

    private ResourceLoader resourceLoader = new ResourceLoader();
    private String bundleLocation;
    private static final String STYLESHEET_PARAMS = "org.sakaiproject.metaobj.shared.control.XsltArtifactView.paramsMap";
    private static final String STYLESHEET_LOCATION = "org.sakaiproject.metaobj.shared.control.XsltArtifactView.stylesheetLocation";
    private String uriResolverBeanName;
    private URIResolver uriResolver;
    private boolean readOnly;

    // These parameter names are reserved. Anything not on this list may be passed
    // as an HTTP query parameter to pass through from the browser to the stylesheet.
    protected static final List<String> reservedParams = Collections
            .unmodifiableList(Arrays.asList("preview", "fromResources", "edit", "panelId", "subForm",
                    FormHelper.XSL_SITE_ID, FormHelper.XSL_PRESENTATION_TYPE, FormHelper.XSL_PRESENTATION_ID,
                    FormHelper.XSL_PRESENTATION_ITEM_ID, FormHelper.XSL_PRESENTATION_ITEM_NAME,
                    FormHelper.XSL_FORM_TYPE, FormHelper.XSL_ARTIFACT_ID, FormHelper.XSL_ARTIFACT_REFERENCE,
                    FormHelper.XSL_OBJECT_ID, FormHelper.XSL_OBJECT_TITLE, FormHelper.XSL_WIZARD_PAGE_ID));

    protected Source createXsltSource(Map map, String string, HttpServletRequest httpServletRequest,
            HttpServletResponse httpServletResponse) throws Exception {

        httpServletResponse.setContentType(getContentType());
        WebApplicationContext context = getWebApplicationContext();
        setUriResolver((URIResolver) context.getBean(uriResolverBeanName));

        ToolSession toolSession = SessionManager.getCurrentToolSession();

        String homeType = null;

        ElementBean bean = (ElementBean) map.get("bean");

        Element root = null;
        Map paramsMap = new Hashtable();

        for (Enumeration e = httpServletRequest.getParameterNames(); e.hasMoreElements();) {
            String k = e.nextElement().toString();
            // Do not allow reserved parameter names to be overwritten
            if (!reservedParams.contains(k)) {
                paramsMap.put(k, httpServletRequest.getParameter(k));
            }
        }

        httpServletRequest.setAttribute(STYLESHEET_PARAMS, paramsMap);
        if (toolSession.getAttribute(FormHelper.PREVIEW_HOME_TAG) != null) {
            paramsMap.put("preview", "true");
        }

        if (toolSession.getAttribute(ResourceToolAction.ACTION_PIPE) != null) {
            paramsMap.put("fromResources", "true");
        }

        if (httpServletRequest.getAttribute(FormHelper.URL_DECORATION) != null) {
            paramsMap.put("urlDecoration", httpServletRequest.getAttribute(FormHelper.URL_DECORATION));
        }

        HashMap<String, String> xslParams = new HashMap<String, String>();
        xslParams.put(FormHelper.XSL_PRESENTATION_ID, FormHelper.PRESENTATION_ID);
        xslParams.put(FormHelper.XSL_PRESENTATION_TYPE, FormHelper.PRESENTATION_TEMPLATE_ID);
        xslParams.put(FormHelper.XSL_PRESENTATION_ITEM_ID, FormHelper.PRESENTATION_ITEM_DEF_ID);
        xslParams.put(FormHelper.XSL_PRESENTATION_ITEM_NAME, FormHelper.PRESENTATION_ITEM_DEF_NAME);
        xslParams.put(FormHelper.XSL_FORM_TYPE, ResourceEditingHelper.CREATE_SUB_TYPE);
        xslParams.put(FormHelper.XSL_ARTIFACT_REFERENCE, ResourceEditingHelper.ATTACHMENT_ID);
        xslParams.put(FormHelper.XSL_OBJECT_ID, FormHelper.XSL_OBJECT_ID);
        xslParams.put(FormHelper.XSL_OBJECT_TITLE, FormHelper.XSL_OBJECT_TITLE);
        xslParams.put(FormHelper.XSL_WIZARD_PAGE_ID, FormHelper.XSL_WIZARD_PAGE_ID);

        // Load up our XSL parameters according to the mapping into the tool session above.
        // Note that this is not always one-to-one due to some string/key inconsistencies around the tools.
        for (Entry<String, String> item : xslParams.entrySet()) {
            Object val = toolSession.getAttribute(item.getValue());
            if (val != null) {
                paramsMap.put(item.getKey(), val);
            }
        }

        Id id = null;

        if (bean instanceof Artifact) {
            root = getStructuredArtifactDefinitionManager().createFormViewXml((Artifact) bean, null);
            homeType = getHomeType((Artifact) bean);
            id = ((Artifact) bean).getId();
        } else {
            EditedArtifactStorage sessionBean = (EditedArtifactStorage) httpServletRequest.getSession()
                    .getAttribute(EditedArtifactStorage.EDITED_ARTIFACT_STORAGE_SESSION_KEY);

            if (sessionBean != null) {
                root = getStructuredArtifactDefinitionManager()
                        .createFormViewXml((Artifact) sessionBean.getRootArtifact(), null);

                replaceNodes(root, bean, sessionBean);
                paramsMap.put("subForm", "true");
                homeType = getHomeType(sessionBean.getRootArtifact());
                id = sessionBean.getRootArtifact().getId();
            } else {
                return new javax.xml.transform.dom.DOMSource();
            }
        }

        if (id != null) {
            paramsMap.put("edit", "true");
            paramsMap.put(FormHelper.XSL_ARTIFACT_ID, id.getValue());
        }

        httpServletRequest.setAttribute(STYLESHEET_LOCATION,
                getStructuredArtifactDefinitionManager().getTransformer(homeType, readOnly));

        Errors errors = BindingResultUtils.getBindingResult(map, "bean");
        if (errors != null && errors.hasErrors()) {
            Element errorsElement = new Element("errors");

            List errorsList = errors.getAllErrors();

            for (Iterator i = errorsList.iterator(); i.hasNext();) {
                Element errorElement = new Element("error");
                ObjectError error = (ObjectError) i.next();
                if (error instanceof FieldError) {
                    FieldError fieldError = (FieldError) error;
                    errorElement.setAttribute("field", fieldError.getField());
                    Element rejectedValue = new Element("rejectedValue");
                    if (fieldError.getRejectedValue() != null) {
                        rejectedValue.addContent(fieldError.getRejectedValue().toString());
                    }
                    errorElement.addContent(rejectedValue);
                }
                Element message = new Element("message");
                message.addContent(context.getMessage(error, getResourceLoader().getLocale()));
                errorElement.addContent(message);
                errorsElement.addContent(errorElement);
            }

            root.addContent(errorsElement);
        }

        if (httpServletRequest.getParameter("success") != null) {
            Element success = new Element("success");
            success.setAttribute("messageKey", httpServletRequest.getParameter("success"));
            root.addContent(success);
        }

        if (toolSession.getAttribute(ResourceEditingHelper.CUSTOM_CSS) != null) {
            Element uri = new Element("uri");
            uri.setText((String) toolSession.getAttribute(ResourceEditingHelper.CUSTOM_CSS));
            root.getChild("css").addContent(uri);
            uri.setAttribute("order", "100");
        }

        if (toolSession.getAttribute(FormHelper.FORM_STYLES) != null) {
            List styles = (List) toolSession.getAttribute(FormHelper.FORM_STYLES);
            int index = 101;
            for (Iterator<String> i = styles.iterator(); i.hasNext();) {
                Element uri = new Element("uri");
                uri.setText(i.next());
                root.getChild("css").addContent(uri);
                uri.setAttribute("order", "" + index);
                index++;
            }
        }

        Document doc = new Document(root);
        return new JDOMSource(doc);
    }

    protected String getHomeType(Artifact bean) {
        if (bean.getHome().getType() == null) {
            return "new bean";
        } else if (bean.getHome().getType().getId() == null) {
            return "new bean";
        }
        return bean.getHome().getType().getId().getValue();
    }

    protected void replaceNodes(Element root, ElementBean bean, EditedArtifactStorage sessionBean) {
        Element structuredData = root.getChild("formData").getChild("artifact").getChild("structuredData");
        structuredData.removeContent();
        structuredData.addContent((Element) bean.getBaseElement().clone());

        Element schema = root.getChild("formData").getChild("artifact").getChild("schema");
        Element schemaRoot = schema.getChild("element");
        StringTokenizer st = new StringTokenizer(sessionBean.getCurrentPath(), "/");
        Element newRoot = schemaRoot;

        while (st.hasMoreTokens()) {
            String schemaName = st.nextToken();
            List children = newRoot.getChild("children").getChildren("element");
            for (Iterator i = children.iterator(); i.hasNext();) {
                Element schemaElement = (Element) i.next();
                if (schemaName.equals(schemaElement.getAttributeValue("name"))) {
                    newRoot = schemaElement;
                    break;
                }
            }
        }

        schema.removeChild("element");
        schema.addContent(newRoot.detach());
    }

    protected Map getParameters(HttpServletRequest request) {
        Map params = super.getParameters(request);

        if (params == null) {
            params = new Hashtable();
        }

        if (ToolManager.getCurrentPlacement() != null) {
            params.put("panelId", Web.escapeJavascript("Main" + ToolManager.getCurrentPlacement().getId()));
            params.put(FormHelper.XSL_SITE_ID, ToolManager.getCurrentPlacement().getContext());
        }

        if (request.getAttribute(STYLESHEET_PARAMS) != null)
            params.putAll((Map) request.getAttribute(STYLESHEET_PARAMS));

        if (request.getAttribute(STYLESHEET_LOCATION) != null)
            params.put(STYLESHEET_LOCATION, request.getAttribute(STYLESHEET_LOCATION));
        return params;
    }

    /**
     * Perform the actual transformation, writing to the given result.
     * @param source the Source to transform
     * @param parameters a Map of parameters to be applied to the stylesheet
     * @param result the result to write to
     * @throws Exception we let this method throw any exception; the
     * AbstractXlstView superclass will catch exceptions
     */
    protected void doTransform(Source source, Map parameters, Result result, String encoding) throws Exception {

        InputStream stylesheetLocation = null;
        // Nulls gets logged by getTransformer, so don't bother logging again.
        if (parameters != null)
            stylesheetLocation = (InputStream) parameters.get(STYLESHEET_LOCATION);
        Transformer trans = getTransformer(stylesheetLocation);

        // Explicitly apply URIResolver to every created Transformer.
        if (getUriResolver() != null) {
            trans.setURIResolver(getUriResolver());
        }

        // Apply any subclass supplied parameters to the transformer.
        if (parameters != null) {
            for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry) it.next();
                trans.setParameter(entry.getKey().toString(), entry.getValue());
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Added parameters [" + parameters + "] to transformer object");
            }
        }

        // Specify default output properties.
        //trans.setOutputProperty(OutputKeys.ENCODING, encoding);
        trans.setOutputProperty(OutputKeys.INDENT, "yes");

        // Xalan-specific, but won't do any harm in other XSLT engines.
        trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

        // Perform the actual XSLT transformation.
        try {
            trans.transform(source, result);
            if (logger.isDebugEnabled()) {
                logger.debug("XSLT transformed with stylesheet [" + stylesheetLocation + "]");
            }
        } catch (TransformerException ex) {
            throw new NestedServletException("Couldn't perform transform with stylesheet [" + stylesheetLocation
                    + "] in XSLT view with name [" + getBeanName() + "]", ex);
        }
    }

    protected Transformer getTransformer(InputStream transformer) throws TransformerException {
        try {
            if (transformer == null) {
                logger.warn(this + ".getTransformer passed null InputStream");
                return getTransformerFactory().newTransformer();
            } else {
                return getTransformerFactory().newTransformer(new StreamSource(transformer));
            }
        } catch (TransformerConfigurationException ex) {
            logger.warn("Couldn't create XSLT transformer for stylesheet in XSLT view with name [" + getBeanName()
                    + "]", ex);
            return getTransformerFactory().newTransformer();
        }
    }

    protected StructuredArtifactDefinitionManager getStructuredArtifactDefinitionManager() {
        return (StructuredArtifactDefinitionManager) ComponentManager.get("structuredArtifactDefinitionManager");
    }

    public String getBundleLocation() {
        return bundleLocation;
    }

    public void setBundleLocation(String bundleLocation) {
        this.bundleLocation = bundleLocation;
        setResourceLoader(new ResourceLoader(bundleLocation));
    }

    public ResourceLoader getResourceLoader() {
        return resourceLoader;
    }

    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public String getUriResolverBeanName() {
        return uriResolverBeanName;
    }

    public void setUriResolverBeanName(String uriResolverBeanName) {
        this.uriResolverBeanName = uriResolverBeanName;
    }

    public URIResolver getUriResolver() {
        return uriResolver;
    }

    public void setUriResolver(URIResolver uriResolver) {
        this.uriResolver = uriResolver;
        getTransformerFactory().setURIResolver(uriResolver);
    }

    public boolean isReadOnly() {
        return readOnly;
    }

    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    protected void dumpDocument(Element node) {
        try {
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.transform(new JDOMSource(node), new StreamResult(System.out));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}