/********************************************************************************** * $URL:https://source.sakaiproject.org/svn/osp/trunk/common/tool-lib/src/java/org/theospi/portfolio/shared/control/XmlElementView.java $ * $Id:XmlElementView.java 9134 2006-05-08 20:28:42Z chmaurer@iupui.edu $ *********************************************************************************** * * Copyright (c) 2005, 2006, 2008 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.theospi.portfolio.shared.control; import java.io.File; import java.io.FileWriter; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.ResourceNotFoundException; import org.sakaiproject.metaobj.shared.control.EditedArtifactStorage; import org.sakaiproject.metaobj.shared.control.SchemaBean; import org.sakaiproject.metaobj.shared.mgt.HomeFactory; import org.sakaiproject.metaobj.shared.mgt.home.StructuredArtifactHomeInterface; import org.sakaiproject.metaobj.shared.model.StructuredArtifact; import org.sakaiproject.metaobj.utils.mvc.impl.TemplateJstlView; import org.sakaiproject.metaobj.utils.mvc.intf.VelocityEngineFactory; import org.sakaiproject.metaobj.utils.xml.SchemaNode; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.ApplicationContextException; /** * Created by IntelliJ IDEA. * User: John Ellis * Date: Apr 20, 2004 * Time: 3:32:34 PM * To change this template use File | Settings | File Templates. */ public class XmlElementView extends TemplateJstlView { protected final transient Log logger = LogFactory.getLog(getClass()); private String templateName = ""; private VelocityEngine velocityEngine; private Template template; private String baseUrl = null; public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { setBody(prepareTemplateForRendering(model, request, response)); super.render(model, request, response); } /** * Prepare for rendering, and determine the request dispatcher path * to forward to respectively to include. * <p>This implementation simply returns the configured URL. * Subclasses can override this to determine a resource to render, * typically interpreting the URL in a different manner. * * @param request current HTTP request * @param response current HTTP response * @return the request dispatcher path to use * @throws Exception if preparations failed * @see #getUrl * @see org.springframework.web.servlet.view.tiles.TilesView#prepareForRendering */ protected String prepareTemplateForRendering(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { HomeFactory factory = (HomeFactory) getWebApplicationContext().getBean("homeFactory"); SchemaNode schema = null; StructuredArtifactHomeInterface home = null; String schemaName = null; schemaName = request.getParameter("schema"); if (schemaName == null) { schemaName = (String) request.getAttribute("schema"); if (schemaName == null) { schemaName = request.getParameter("artifactType"); } } home = (StructuredArtifactHomeInterface) factory.getHome(schemaName); if (request.getAttribute(EditedArtifactStorage.STORED_ARTIFACT_FLAG) != null) { EditedArtifactStorage sessionBean = (EditedArtifactStorage)request.getSession().getAttribute( EditedArtifactStorage.EDITED_ARTIFACT_STORAGE_SESSION_KEY); if (!(sessionBean.getCurrentElement() instanceof StructuredArtifact)) { home = (StructuredArtifactHomeInterface)sessionBean.getHome(); schema = sessionBean.getCurrentSchemaNode(); schemaName += "." + sessionBean.getCurrentPath(); } } String baseFile = getBaseUrl() + "_" + schemaName; File genFile = new File(getWebApplicationContext().getServletContext().getRealPath(""), baseFile + ".jsp"); File customFile = new File(getWebApplicationContext().getServletContext().getRealPath(""), baseFile + "_custom.jsp"); if (customFile.exists()) { return baseFile + "_custom.jsp"; } if (genFile.exists()) { if (genFile.lastModified() > home.getModified().getTime() && genFile.lastModified() > getVelocityTemplate().getLastModified()) { return baseFile + ".jsp"; } } return createJspFromTemplate(home, baseFile + ".jsp", genFile, schemaName, schema); } protected String createJspFromTemplate(StructuredArtifactHomeInterface home, String resultFile, File jspFile, String schemaName, SchemaNode schema) throws Exception { VelocityContext context = new VelocityContext(); if (schema != null) { context.put("schema", new SchemaBean(schema, home.getRootNode(), null, home.getType().getDescription())); } else { context.put("schema", new SchemaBean(home.getRootNode(), home.getSchema(), schemaName, home.getType().getDescription())); } context.put("instruction", home.getInstruction()); FileWriter output = null; try { output = new FileWriter(jspFile); getVelocityTemplate().merge(context, output); } finally { try { output.close(); } catch (Exception e) { logger.warn("Could not clean up resource", e); } } return resultFile; } /** * Invoked on startup. Looks for a single VelocityConfig bean to * find the relevant VelocityEngine for this factory. */ protected void initApplicationContext() throws BeansException { super.initApplicationContext(); if (this.velocityEngine == null) { try { VelocityEngineFactory velocityConfig = (VelocityEngineFactory) BeanFactoryUtils.beanOfTypeIncludingAncestors(getApplicationContext(), VelocityEngineFactory.class, true, true); this.velocityEngine = velocityConfig.getVelocityEngine(); } catch (NoSuchBeanDefinitionException ex) { throw new ApplicationContextException("Must define a single VelocityConfig bean in this web application " + "context (may be inherited): VelocityConfigurer is the usual implementation. " + "This bean may be given any name.", ex); } } try { // check that we can get the template, even if we might subsequently get it again this.template = getVelocityTemplate(); } catch (ResourceNotFoundException ex) { throw new ApplicationContextException("Cannot find Velocity template for URL [" + getBaseUrl() + "]: Did you specify the correct resource loader path?", ex); } catch (Exception ex) { throw new ApplicationContextException("Cannot load Velocity template for URL [" + getBaseUrl() + "]", ex); } } /** * Retrieve the Velocity template. * * @return the Velocity template to process * @throws Exception if thrown by Velocity */ protected Template getVelocityTemplate() throws Exception { return this.velocityEngine.getTemplate(templateName); } public String getTemplateName() { return templateName; } public void setTemplateName(String templateName) { this.templateName = templateName; } public String getBaseUrl() { return baseUrl; } public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; } }