package com.psddev.cms.tool; import java.io.StringWriter; import javax.servlet.ServletContext; import com.psddev.dari.util.JspUtils; import com.psddev.dari.util.ObjectUtils; import com.psddev.dari.util.RoutingFilter; import com.psddev.dari.util.StringUtils; /** Widget controlled by a JSP file. */ public class JspWidget extends Widget { public static final String REMOTE_DISPLAY_API = "/_jspWidget.display"; public static final String REMOTE_UPDATE_API = "/_jspWidget.update"; private static final String ATTRIBUTE_PREFIX = JspWidget.class.getName() + "."; private static final String IS_UPDATING_ATTRIBUTE = ATTRIBUTE_PREFIX + "isUpdating"; private static final String OBJECT_ATTRIBUTE = ATTRIBUTE_PREFIX + "object"; private static final String WIDGET_ATTRIBUTE = ATTRIBUTE_PREFIX + "widget"; private String jsp; private boolean displayInNonPublishable; /** * Returns {@code true} if a widget is processing within the given * {@code page}. */ public static boolean isUpdating(ToolPageContext page) { return Boolean.TRUE.equals(page.getRequest().getAttribute(IS_UPDATING_ATTRIBUTE)); } /** Returns the object associated with the given {@code page}. */ public static Object getObject(ToolPageContext page) { return page.getRequest().getAttribute(OBJECT_ATTRIBUTE); } /** Returns the widget associated with the given {@code page}. */ public static JspWidget getWidget(ToolPageContext page) { return (JspWidget) page.getRequest().getAttribute(WIDGET_ATTRIBUTE); } /** Returns the original object associated with the given {@code page}. */ public static Object getOriginal(ToolPageContext page) { Object object = page.getRequest().getAttribute("original"); return object != null ? object : getObject(page); } /** Returns the JSP. */ public String getJsp() { return jsp; } /** Sets the JSP. */ public void setJsp(String jsp) { this.jsp = jsp; } public boolean isDisplayInNonPublishable() { return displayInNonPublishable; } public void setDisplayInNonPublishable(boolean displayInNonPublishable) { this.displayInNonPublishable = displayInNonPublishable; } // --- Widget support --- @Override public boolean shouldDisplayInNonPublishable() { return isDisplayInNonPublishable(); } @SuppressWarnings("deprecation") private String findApplicationJsp() { Tool tool = getTool(); String appName = tool.getApplicationName(); String appPath = null; if (appName != null) { appPath = RoutingFilter.Static.getApplicationPath(appName); } else if (ObjectUtils.isBlank(tool.getUrl())) { appPath = ""; } return appPath != null ? appPath + StringUtils.ensureStart(getJsp(), "/") : null; } private String includeJsp( ServletContext context, ToolPageContext page, Object object, String jsp, boolean updating) throws Exception { StringWriter writer = new StringWriter(); JspUtils.includeEmbedded( context, page.getRequest(), page.getResponse(), writer, jsp, IS_UPDATING_ATTRIBUTE, updating, OBJECT_ATTRIBUTE, object, WIDGET_ATTRIBUTE, this); return writer.toString(); } @Override public String display(ToolPageContext page, Object object) throws Exception { String jsp = findApplicationJsp(); if (jsp != null) { return includeJsp(null, page, object, jsp, false); } else if (ObjectUtils.equals(getTool(), page.getTool())) { return includeJsp(page.getServletContext(), page, object, getJsp(), false); } else { return RemoteWidget.displayWidget(this, REMOTE_DISPLAY_API, page, object); } } @Override public void update(ToolPageContext page, Object object) throws Exception { String jsp = findApplicationJsp(); if (jsp != null) { includeJsp(null, page, object, jsp, true); } else if (ObjectUtils.equals(getTool(), page.getTool())) { includeJsp(page.getServletContext(), page, object, getJsp(), true); } else { RemoteWidget.updateWithWidget(this, REMOTE_UPDATE_API, page, object); } } }