| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache 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.apache.org/licenses/LICENSE-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.ofbiz.widget.screen; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.ofbiz.base.util.Debug; |
| import org.ofbiz.base.util.GeneralException; |
| import org.ofbiz.base.util.StringUtil; |
| import org.ofbiz.base.util.UtilGenerics; |
| import org.ofbiz.base.util.UtilMisc; |
| import org.ofbiz.base.util.UtilXml; |
| import org.ofbiz.base.util.collections.MapStack; |
| import org.ofbiz.base.util.string.FlexibleStringExpander; |
| import org.ofbiz.entity.Delegator; |
| import org.ofbiz.entity.GenericEntityException; |
| import org.ofbiz.entity.GenericValue; |
| import org.ofbiz.entity.condition.EntityCondition; |
| import org.ofbiz.entity.util.EntityQuery; |
| import org.ofbiz.widget.ModelWidget; |
| import org.ofbiz.widget.ModelWidgetAction; |
| import org.ofbiz.widget.ModelWidgetVisitor; |
| import org.ofbiz.widget.PortalPageWorker; |
| import org.ofbiz.widget.WidgetFactory; |
| import org.ofbiz.widget.WidgetWorker; |
| import org.ofbiz.widget.form.FormFactory; |
| import org.ofbiz.widget.form.FormRenderer; |
| import org.ofbiz.widget.form.FormStringRenderer; |
| import org.ofbiz.widget.form.ModelForm; |
| import org.ofbiz.widget.menu.MenuFactory; |
| import org.ofbiz.widget.menu.MenuStringRenderer; |
| import org.ofbiz.widget.menu.ModelMenu; |
| import org.ofbiz.widget.tree.ModelTree; |
| import org.ofbiz.widget.tree.TreeFactory; |
| import org.ofbiz.widget.tree.TreeStringRenderer; |
| import org.w3c.dom.Element; |
| import org.xml.sax.SAXException; |
| |
| |
| /** |
| * Widget Library - Screen model class |
| */ |
| @SuppressWarnings("serial") |
| public abstract class ModelScreenWidget extends ModelWidget { |
| public static final String module = ModelScreenWidget.class.getName(); |
| |
| private final ModelScreen modelScreen; |
| |
| public ModelScreenWidget(ModelScreen modelScreen, Element widgetElement) { |
| super(widgetElement); |
| this.modelScreen = modelScreen; |
| if (Debug.verboseOn()) Debug.logVerbose("Reading Screen sub-widget with name: " + widgetElement.getNodeName(), module); |
| } |
| |
| public abstract void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException; |
| |
| protected static List<ModelScreenWidget> readSubWidgets(ModelScreen modelScreen, List<? extends Element> subElementList) { |
| if (subElementList.isEmpty()) { |
| return Collections.emptyList(); |
| } |
| List<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(subElementList.size()); |
| for (Element subElement: subElementList) { |
| subWidgets.add(WidgetFactory.getModelScreenWidget(modelScreen, subElement)); |
| } |
| return Collections.unmodifiableList(subWidgets); |
| } |
| |
| protected static void renderSubWidgetsString(List<ModelScreenWidget> subWidgets, Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| if (subWidgets == null) { |
| return; |
| } |
| for (ModelScreenWidget subWidget: subWidgets) { |
| if (Debug.verboseOn()) Debug.logVerbose("Rendering screen " + subWidget.getModelScreen().getName() + "; widget class is " + subWidget.getClass().getName(), module); |
| |
| // render the sub-widget itself |
| subWidget.renderWidgetString(writer, context, screenStringRenderer); |
| } |
| } |
| |
| public ModelScreen getModelScreen() { |
| return this.modelScreen; |
| } |
| |
| public static final class SectionsRenderer implements Map<String, ModelScreenWidget> { |
| private final Map<String, ModelScreenWidget> sectionMap; |
| private final ScreenStringRenderer screenStringRenderer; |
| private final Map<String, Object> context; |
| private final Appendable writer; |
| |
| public SectionsRenderer(Map<String, ModelScreenWidget> sectionMap, Map<String, Object> context, Appendable writer, |
| ScreenStringRenderer screenStringRenderer) { |
| Map<String, ModelScreenWidget> localMap = new HashMap<String, ModelScreenWidget>(); |
| localMap.putAll(sectionMap); |
| this.sectionMap = Collections.unmodifiableMap(localMap); |
| this.context = context; |
| this.writer = writer; |
| this.screenStringRenderer = screenStringRenderer; |
| } |
| |
| /** This is a lot like the ScreenRenderer class and returns an empty String so it can be used more easily with FreeMarker */ |
| public String render(String sectionName) throws GeneralException, IOException { |
| ModelScreenWidget section = sectionMap.get(sectionName); |
| // if no section by that name, write nothing |
| if (section != null) { |
| section.renderWidgetString(this.writer, this.context, this.screenStringRenderer); |
| } |
| return ""; |
| } |
| |
| @Override |
| public int size() { |
| return sectionMap.size(); |
| } |
| |
| @Override |
| public boolean isEmpty() { |
| return sectionMap.isEmpty(); |
| } |
| |
| @Override |
| public boolean containsKey(Object key) { |
| return sectionMap.containsKey(key); |
| } |
| |
| @Override |
| public boolean containsValue(Object value) { |
| return sectionMap.containsValue(value); |
| } |
| |
| @Override |
| public ModelScreenWidget get(Object key) { |
| return sectionMap.get(key); |
| } |
| |
| @Override |
| public ModelScreenWidget put(String key, ModelScreenWidget value) { |
| return sectionMap.put(key, value); |
| } |
| |
| @Override |
| public ModelScreenWidget remove(Object key) { |
| return sectionMap.remove(key); |
| } |
| |
| @Override |
| public void clear() { |
| sectionMap.clear(); |
| } |
| |
| @Override |
| public Set<String> keySet() { |
| return sectionMap.keySet(); |
| } |
| |
| @Override |
| public Collection<ModelScreenWidget> values() { |
| return sectionMap.values(); |
| } |
| |
| @Override |
| public Set<java.util.Map.Entry<String, ModelScreenWidget>> entrySet() { |
| return sectionMap.entrySet(); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| return sectionMap.equals(o); |
| } |
| |
| @Override |
| public int hashCode() { |
| return sectionMap.hashCode(); |
| } |
| |
| @Override |
| public void putAll(Map<? extends String, ? extends ModelScreenWidget> m) { |
| sectionMap.putAll(m); |
| } |
| } |
| |
| public static final class Section extends ModelScreenWidget { |
| public static final String TAG_NAME = "section"; |
| private final ModelScreenCondition condition; |
| private final List<ModelWidgetAction> actions; |
| private final List<ModelScreenWidget> subWidgets; |
| private final List<ModelScreenWidget> failWidgets; |
| private final boolean isMainSection; |
| |
| public Section(ModelScreen modelScreen, Element sectionElement) { |
| this(modelScreen, sectionElement, false); |
| } |
| |
| public Section(ModelScreen modelScreen, Element sectionElement, boolean isMainSection) { |
| super(modelScreen, sectionElement); |
| |
| // read condition under the "condition" element |
| Element conditionElement = UtilXml.firstChildElement(sectionElement, "condition"); |
| if (conditionElement != null) { |
| this.condition = new ModelScreenCondition(modelScreen, conditionElement); |
| } else { |
| this.condition = null; |
| } |
| |
| // read all actions under the "actions" element |
| Element actionsElement = UtilXml.firstChildElement(sectionElement, "actions"); |
| if (actionsElement != null) { |
| this.actions = ModelWidgetAction.readSubActions(modelScreen, actionsElement); |
| } else { |
| this.actions = Collections.emptyList(); |
| } |
| |
| // read sub-widgets |
| Element widgetsElement = UtilXml.firstChildElement(sectionElement, "widgets"); |
| if (widgetsElement != null) { |
| List<? extends Element> subElementList = UtilXml.childElementList(widgetsElement); |
| this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList); |
| } else { |
| this.subWidgets = Collections.emptyList(); |
| } |
| |
| // read fail-widgets |
| Element failWidgetsElement = UtilXml.firstChildElement(sectionElement, "fail-widgets"); |
| if (failWidgetsElement != null) { |
| List<? extends Element> failElementList = UtilXml.childElementList(failWidgetsElement); |
| this.failWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), failElementList); |
| } else { |
| this.failWidgets = Collections.emptyList(); |
| } |
| this.isMainSection = isMainSection; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| // check the condition, if there is one |
| boolean condTrue = true; |
| if (this.condition != null) { |
| if (!this.condition.eval(context)) { |
| condTrue = false; |
| } |
| } |
| |
| // if condition does not exist or evals to true run actions and render widgets, otherwise render fail-widgets |
| if (condTrue) { |
| // run the actions only if true |
| ModelWidgetAction.runSubActions(this.actions, context); |
| |
| try { |
| // section by definition do not themselves do anything, so this method will generally do nothing, but we'll call it anyway |
| screenStringRenderer.renderSectionBegin(writer, context, this); |
| |
| // render sub-widgets |
| renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer); |
| |
| screenStringRenderer.renderSectionEnd(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering widgets section [" + getName() + "] in screen named [" + getModelScreen().getName() + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } else { |
| try { |
| // section by definition do not themselves do anything, so this method will generally do nothing, but we'll call it anyway |
| screenStringRenderer.renderSectionBegin(writer, context, this); |
| |
| // render sub-widgets |
| renderSubWidgetsString(this.failWidgets, writer, context, screenStringRenderer); |
| |
| screenStringRenderer.renderSectionEnd(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering fail-widgets section [" + this.getName() + "] in screen named [" + getModelScreen().getName() + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| } |
| |
| @Override |
| public String getBoundaryCommentName() { |
| if (isMainSection) { |
| return getModelScreen().getSourceLocation() + "#" + getModelScreen().getName(); |
| } else { |
| return getName(); |
| } |
| } |
| |
| public List<ModelWidgetAction> getActions() { |
| return actions; |
| } |
| |
| public List<ModelScreenWidget> getSubWidgets() { |
| return subWidgets; |
| } |
| |
| public List<ModelScreenWidget> getFailWidgets() { |
| return failWidgets; |
| } |
| |
| public boolean isMainSection() { |
| return isMainSection; |
| } |
| } |
| |
| public static final class ColumnContainer extends ModelScreenWidget { |
| public static final String TAG_NAME = "column-container"; |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander styleExdr; |
| private final List<Column> columns; |
| |
| public ColumnContainer(ModelScreen modelScreen, Element containerElement) { |
| super(modelScreen, containerElement); |
| this.idExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("id")); |
| this.styleExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("style")); |
| List<? extends Element> subElementList = UtilXml.childElementList(containerElement, "column"); |
| List<Column> columns = new ArrayList<Column>(subElementList.size()); |
| for (Element element : subElementList) { |
| columns.add(new Column(modelScreen, element)); |
| } |
| this.columns = Collections.unmodifiableList(columns); |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| try { |
| screenStringRenderer.renderColumnContainer(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering container in screen named [" + getModelScreen().getName() + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| public List<Column> getColumns() { |
| return this.columns; |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public String getStyle(Map<String, Object> context) { |
| return this.styleExdr.expandString(context); |
| } |
| } |
| |
| public static final class Column { |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander styleExdr; |
| private final List<ModelScreenWidget> subWidgets; |
| |
| public Column(ModelScreen modelScreen, Element columnElement) { |
| this.idExdr = FlexibleStringExpander.getInstance(columnElement.getAttribute("id")); |
| this.styleExdr = FlexibleStringExpander.getInstance(columnElement.getAttribute("style")); |
| List<? extends Element> subElementList = UtilXml.childElementList(columnElement); |
| this.subWidgets = Collections.unmodifiableList(readSubWidgets(modelScreen, subElementList)); |
| } |
| |
| public List<ModelScreenWidget> getSubWidgets() { |
| return this.subWidgets; |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public String getStyle(Map<String, Object> context) { |
| return this.styleExdr.expandString(context); |
| } |
| } |
| |
| public static final class Container extends ModelScreenWidget { |
| public static final String TAG_NAME = "container"; |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander styleExdr; |
| private final FlexibleStringExpander autoUpdateTargetExdr; |
| private final FlexibleStringExpander autoUpdateInterval; |
| private final List<ModelScreenWidget> subWidgets; |
| |
| public Container(ModelScreen modelScreen, Element containerElement) { |
| super(modelScreen, containerElement); |
| this.idExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("id")); |
| this.styleExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("style")); |
| this.autoUpdateTargetExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("auto-update-target")); |
| String autoUpdateInterval = containerElement.getAttribute("auto-update-interval"); |
| if (autoUpdateInterval.isEmpty()) { |
| autoUpdateInterval = "2"; |
| } |
| this.autoUpdateInterval = FlexibleStringExpander.getInstance(autoUpdateInterval); |
| // read sub-widgets |
| List<? extends Element> subElementList = UtilXml.childElementList(containerElement); |
| this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| try { |
| screenStringRenderer.renderContainerBegin(writer, context, this); |
| |
| // render sub-widgets |
| renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer); |
| |
| screenStringRenderer.renderContainerEnd(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering container in screen named [" + getModelScreen().getName() + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public String getStyle(Map<String, Object> context) { |
| return this.styleExdr.expandString(context); |
| } |
| |
| public String getAutoUpdateTargetExdr(Map<String, Object> context) { |
| return this.autoUpdateTargetExdr.expandString(context); |
| } |
| |
| public String getAutoUpdateInterval(Map<String, Object> context) { |
| return this.autoUpdateInterval.expandString(context); |
| } |
| |
| public List<ModelScreenWidget> getSubWidgets() { |
| return subWidgets; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class Screenlet extends ModelScreenWidget { |
| public static final String TAG_NAME = "screenlet"; |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander titleExdr; |
| private final Menu navigationMenu; |
| private final Menu tabMenu; |
| private final Form navigationForm; |
| private final boolean collapsible; |
| private final FlexibleStringExpander initiallyCollapsed; |
| private final boolean saveCollapsed; |
| private final boolean padded; |
| private final List<ModelScreenWidget> subWidgets; |
| |
| public Screenlet(ModelScreen modelScreen, Element screenletElement) { |
| super(modelScreen, screenletElement); |
| this.idExdr = FlexibleStringExpander.getInstance(screenletElement.getAttribute("id")); |
| boolean collapsible = "true".equals(screenletElement.getAttribute("collapsible")); |
| this.initiallyCollapsed = FlexibleStringExpander.getInstance(screenletElement.getAttribute("initially-collapsed")); |
| if ("true".equals(this.initiallyCollapsed.getOriginal())) { |
| collapsible = true; |
| } |
| this.collapsible = collapsible; |
| // By default, for a collapsible screenlet, the collapsed/expanded status must be saved |
| this.saveCollapsed = !("false".equals(screenletElement.getAttribute("save-collapsed"))); |
| |
| boolean padded = !"false".equals(screenletElement.getAttribute("padded")); |
| if (this.collapsible && getName().isEmpty() && idExdr.isEmpty()) { |
| throw new IllegalArgumentException("Collapsible screenlets must have a name or id [" + getModelScreen().getName() + "]"); |
| } |
| this.titleExdr = FlexibleStringExpander.getInstance(screenletElement.getAttribute("title")); |
| List<? extends Element> subElementList = UtilXml.childElementList(screenletElement); |
| // Make a copy of the unmodifiable List so we can modify it. |
| ArrayList<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList)); |
| Menu navigationMenu = null; |
| String navMenuName = screenletElement.getAttribute("navigation-menu-name"); |
| if (!navMenuName.isEmpty()) { |
| for (ModelWidget subWidget : subWidgets) { |
| if (navMenuName.equals(subWidget.getName()) && subWidget instanceof Menu) { |
| navigationMenu = (Menu) subWidget; |
| subWidgets.remove(subWidget); |
| break; |
| } |
| } |
| } |
| this.navigationMenu = navigationMenu; |
| Menu tabMenu = null; |
| String tabMenuName = screenletElement.getAttribute("tab-menu-name"); |
| if (!tabMenuName.isEmpty()) { |
| for (ModelWidget subWidget : subWidgets) { |
| if (tabMenuName.equals(subWidget.getName()) && subWidget instanceof Menu) { |
| tabMenu = (Menu) subWidget; |
| subWidgets.remove(subWidget); |
| break; |
| } |
| } |
| } |
| this.tabMenu = tabMenu; |
| Form navigationForm = null; |
| String formName = screenletElement.getAttribute("navigation-form-name"); |
| if (!formName.isEmpty() && this.navigationMenu == null) { |
| for (ModelWidget subWidget : subWidgets) { |
| if (formName.equals(subWidget.getName()) && subWidget instanceof Form) { |
| navigationForm = (Form) subWidget; |
| padded = false; |
| break; |
| } |
| } |
| } |
| this.subWidgets = Collections.unmodifiableList(subWidgets); |
| this.navigationForm = navigationForm; |
| this.padded = padded; |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| boolean collapsed = getInitiallyCollapsed(context); |
| if (this.collapsible) { |
| String preferenceKey = getPreferenceKey(context) + "_collapsed"; |
| Map<String, Object> requestParameters = UtilGenerics.checkMap(context.get("requestParameters")); |
| if (requestParameters != null) { |
| String collapsedParam = (String) requestParameters.get(preferenceKey); |
| collapsed = "true".equals(collapsedParam); |
| } |
| } |
| try { |
| screenStringRenderer.renderScreenletBegin(writer, context, collapsed, this); |
| for (ModelScreenWidget subWidget : this.subWidgets) { |
| screenStringRenderer.renderScreenletSubWidget(writer, context, subWidget, this); |
| } |
| screenStringRenderer.renderScreenletEnd(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering screenlet in screen named [" + getModelScreen().getName() + "]: "; |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg + e); |
| } |
| } |
| |
| public boolean collapsible() { |
| return this.collapsible; |
| } |
| |
| //initially-collapsed status, which may be overriden by user preference |
| public boolean getInitiallyCollapsed(Map<String, Object> context) { |
| String screenletId = this.getId(context) + "_collapsed"; |
| Map<String, ? extends Object> userPreferences = UtilGenerics.checkMap(context.get("userPreferences")); |
| if (userPreferences != null && userPreferences.containsKey(screenletId)) { |
| return Boolean.valueOf((String)userPreferences.get(screenletId)).booleanValue() ; |
| } |
| |
| return "true".equals(this.initiallyCollapsed.expand(context)); |
| } |
| |
| public boolean saveCollapsed() { |
| return this.saveCollapsed; |
| } |
| public boolean padded() { |
| return this.padded; |
| } |
| |
| public String getPreferenceKey(Map<String, Object> context) { |
| String name = this.idExdr.expandString(context); |
| if (name.isEmpty()) { |
| name = "screenlet" + "_" + Integer.toHexString(hashCode()); |
| } |
| return name; |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public List<ModelScreenWidget> getSubWidgets() { |
| return subWidgets; |
| } |
| |
| public String getTitle(Map<String, Object> context) { |
| String title = this.titleExdr.expandString(context); |
| StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder"); |
| if (simpleEncoder != null) { |
| title = simpleEncoder.encode(title); |
| } |
| return title; |
| } |
| |
| public Menu getNavigationMenu() { |
| return this.navigationMenu; |
| } |
| |
| public Form getNavigationForm() { |
| return this.navigationForm; |
| } |
| |
| public Menu getTabMenu() { |
| return this.tabMenu; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class HorizontalSeparator extends ModelScreenWidget { |
| public static final String TAG_NAME = "horizontal-separator"; |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander styleExdr; |
| |
| public HorizontalSeparator(ModelScreen modelScreen, Element separatorElement) { |
| super(modelScreen, separatorElement); |
| this.idExdr = FlexibleStringExpander.getInstance(separatorElement.getAttribute("id")); |
| this.styleExdr = FlexibleStringExpander.getInstance(separatorElement.getAttribute("style")); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| screenStringRenderer.renderHorizontalSeparator(writer, context, this); |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public String getStyle(Map<String, Object> context) { |
| return this.styleExdr.expandString(context); |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class IncludeScreen extends ModelScreenWidget { |
| public static final String TAG_NAME = "include-screen"; |
| private final FlexibleStringExpander nameExdr; |
| private final FlexibleStringExpander locationExdr; |
| private final FlexibleStringExpander shareScopeExdr; |
| |
| public IncludeScreen(ModelScreen modelScreen, Element includeScreenElement) { |
| super(modelScreen, includeScreenElement); |
| this.nameExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("name")); |
| this.locationExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("location")); |
| this.shareScopeExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("share-scope")); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| // if we are not sharing the scope, protect it using the MapStack |
| boolean protectScope = !shareScope(context); |
| if (protectScope) { |
| if (!(context instanceof MapStack<?>)) { |
| context = MapStack.create(context); |
| } |
| |
| UtilGenerics.<MapStack<String>>cast(context).push(); |
| |
| // build the widgetpath |
| List<String> widgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_")); |
| if (widgetTrail == null) { |
| widgetTrail = new LinkedList<String>(); |
| } |
| |
| String thisName = nameExdr.expandString(context); |
| widgetTrail.add(thisName); |
| context.put("_WIDGETTRAIL_", widgetTrail); |
| } |
| |
| // don't need the renderer here, will just pass this on down to another screen call; screenStringRenderer.renderContainerBegin(writer, context, this); |
| String name = this.getName(context); |
| String location = this.getLocation(context); |
| |
| if (name.isEmpty()) { |
| if (Debug.verboseOn()) Debug.logVerbose("In the include-screen tag the screen name was empty, ignoring include; in screen [" + getModelScreen().getName() + "]", module); |
| return; |
| } |
| |
| ScreenFactory.renderReferencedScreen(name, location, this, writer, context, screenStringRenderer); |
| |
| if (protectScope) { |
| UtilGenerics.<MapStack<String>>cast(context).pop(); |
| } |
| } |
| |
| public String getName(Map<String, Object> context) { |
| return this.nameExdr.expandString(context); |
| } |
| |
| public String getLocation(Map<String, Object> context) { |
| return this.locationExdr.expandString(context); |
| } |
| |
| public boolean shareScope(Map<String, Object> context) { |
| String shareScopeString = this.shareScopeExdr.expandString(context); |
| // defaults to false, so anything but true is false |
| return "true".equals(shareScopeString); |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class DecoratorScreen extends ModelScreenWidget { |
| public static final String TAG_NAME = "decorator-screen"; |
| private final FlexibleStringExpander nameExdr; |
| private final FlexibleStringExpander locationExdr; |
| private final Map<String, ModelScreenWidget> sectionMap; |
| |
| public DecoratorScreen(ModelScreen modelScreen, Element decoratorScreenElement) { |
| super(modelScreen, decoratorScreenElement); |
| this.nameExdr = FlexibleStringExpander.getInstance(decoratorScreenElement.getAttribute("name")); |
| this.locationExdr = FlexibleStringExpander.getInstance(decoratorScreenElement.getAttribute("location")); |
| Map<String, ModelScreenWidget> sectionMap = new HashMap<String, ModelScreenWidget>(); |
| List<? extends Element> decoratorSectionElementList = UtilXml.childElementList(decoratorScreenElement, "decorator-section"); |
| for (Element decoratorSectionElement: decoratorSectionElementList) { |
| DecoratorSection decoratorSection = new DecoratorSection(modelScreen, decoratorSectionElement); |
| sectionMap.put(decoratorSection.getName(), decoratorSection); |
| } |
| this.sectionMap = Collections.unmodifiableMap(sectionMap); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| // isolate the scope |
| if (!(context instanceof MapStack)) { |
| context = MapStack.create(context); |
| } |
| |
| MapStack contextMs = (MapStack) context; |
| |
| // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down |
| MapStack standAloneStack = contextMs.standAloneChildStack(); |
| standAloneStack.put("screens", new ScreenRenderer(writer, standAloneStack, screenStringRenderer)); |
| SectionsRenderer sections = new SectionsRenderer(this.sectionMap, standAloneStack, writer, screenStringRenderer); |
| |
| // put the sectionMap in the context, make sure it is in the sub-scope, ie after calling push on the MapStack |
| contextMs.push(); |
| context.put("sections", sections); |
| |
| String name = this.getName(context); |
| String location = this.getLocation(context); |
| |
| ScreenFactory.renderReferencedScreen(name, location, this, writer, context, screenStringRenderer); |
| |
| contextMs.pop(); |
| } |
| |
| public String getName(Map<String, Object> context) { |
| return this.nameExdr.expandString(context); |
| } |
| |
| public String getLocation(Map<String, Object> context) { |
| return this.locationExdr.expandString(context); |
| } |
| |
| public Map<String, ModelScreenWidget> getSectionMap() { |
| return sectionMap; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class DecoratorSection extends ModelScreenWidget { |
| public static final String TAG_NAME = "decorator-section"; |
| private final List<ModelScreenWidget> subWidgets; |
| |
| public DecoratorSection(ModelScreen modelScreen, Element decoratorSectionElement) { |
| super(modelScreen, decoratorSectionElement); |
| // read sub-widgets |
| List<? extends Element> subElementList = UtilXml.childElementList(decoratorSectionElement); |
| this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| // render sub-widgets |
| renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer); |
| } |
| |
| public List<ModelScreenWidget> getSubWidgets() { |
| return subWidgets; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class DecoratorSectionInclude extends ModelScreenWidget { |
| public static final String TAG_NAME = "decorator-section-include"; |
| |
| public DecoratorSectionInclude(ModelScreen modelScreen, Element decoratorSectionElement) { |
| super(modelScreen, decoratorSectionElement); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| Map<String, ? extends Object> preRenderedContent = UtilGenerics.checkMap(context.get("preRenderedContent")); |
| if (preRenderedContent != null && preRenderedContent.containsKey(getName())) { |
| try { |
| writer.append((String) preRenderedContent.get(getName())); |
| } catch (IOException e) { |
| String errMsg = "Error rendering pre-rendered content in screen named [" + getModelScreen().getName() + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } else { |
| SectionsRenderer sections = (SectionsRenderer) context.get("sections"); |
| // for now if sections is null, just log a warning; may be permissible to make the screen for flexible |
| if (sections == null) { |
| Debug.logWarning("In decorator-section-include could not find sections object in the context, not rendering section with name [" + getName() + "]", module); |
| } else { |
| sections.render(getName()); |
| } |
| } |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class Label extends ModelScreenWidget { |
| public static final String TAG_NAME = "label"; |
| private final FlexibleStringExpander textExdr; |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander styleExdr; |
| |
| public Label(ModelScreen modelScreen, Element labelElement) { |
| super(modelScreen, labelElement); |
| |
| // put the text attribute first, then the pcdata under the element, if both are there of course |
| String textAttr = labelElement.getAttribute("text"); |
| String pcdata = UtilXml.elementValue(labelElement); |
| if (pcdata == null) { |
| pcdata = ""; |
| } |
| this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata); |
| |
| this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id")); |
| this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style")); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) { |
| try { |
| screenStringRenderer.renderLabel(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering label in screen named [" + getModelScreen().getName() + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| public String getText(Map<String, Object> context) { |
| String text = this.textExdr.expandString(context); |
| StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder"); |
| if (simpleEncoder != null) { |
| text = simpleEncoder.encode(text); |
| } |
| return text; |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public String getStyle(Map<String, Object> context) { |
| return this.styleExdr.expandString(context); |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class Form extends ModelScreenWidget { |
| public static final String TAG_NAME = "include-form"; |
| private final FlexibleStringExpander nameExdr; |
| private final FlexibleStringExpander locationExdr; |
| private final FlexibleStringExpander shareScopeExdr; |
| |
| public Form(ModelScreen modelScreen, Element formElement) { |
| super(modelScreen, formElement); |
| this.nameExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("name")); |
| this.locationExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("location")); |
| this.shareScopeExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("share-scope")); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) { |
| // Output format might not support forms, so make form rendering optional. |
| FormStringRenderer formStringRenderer = (FormStringRenderer) context.get("formStringRenderer"); |
| if (formStringRenderer == null) { |
| Debug.logVerbose("FormStringRenderer instance not found in rendering context, form not rendered.", module); |
| return; |
| } |
| boolean protectScope = !shareScope(context); |
| if (protectScope) { |
| if (!(context instanceof MapStack<?>)) { |
| context = MapStack.create(context); |
| } |
| UtilGenerics.<MapStack<String>>cast(context).push(); |
| } |
| ModelForm modelForm = getModelForm(context); |
| FormRenderer renderer = new FormRenderer(modelForm, formStringRenderer); |
| try { |
| renderer.render(writer, context); |
| } catch (Exception e) { |
| String errMsg = "Error rendering included form named [" + getName() + "] at location [" + this.getLocation(context) + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg + e); |
| } |
| |
| if (protectScope) { |
| UtilGenerics.<MapStack<String>>cast(context).pop(); |
| } |
| } |
| |
| public ModelForm getModelForm(Map<String, Object> context) { |
| ModelForm modelForm = null; |
| String name = this.getName(context); |
| String location = this.getLocation(context); |
| try { |
| modelForm = FormFactory.getFormFromLocation(location, name, getModelScreen().getDelegator(context).getModelReader(), getModelScreen().getDispatcher(context).getDispatchContext()); |
| } catch (Exception e) { |
| String errMsg = "Error rendering included form named [" + name + "] at location [" + location + "]: "; |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg + e); |
| } |
| return modelForm; |
| } |
| |
| public String getName(Map<String, Object> context) { |
| return this.nameExdr.expandString(context); |
| } |
| |
| public String getLocation() { |
| return locationExdr.getOriginal(); |
| } |
| |
| public String getLocation(Map<String, Object> context) { |
| return this.locationExdr.expandString(context); |
| } |
| |
| public boolean shareScope(Map<String, Object> context) { |
| String shareScopeString = this.shareScopeExdr.expandString(context); |
| // defaults to false, so anything but true is false |
| return "true".equals(shareScopeString); |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class Tree extends ModelScreenWidget { |
| public static final String TAG_NAME = "include-tree"; |
| private final FlexibleStringExpander nameExdr; |
| private final FlexibleStringExpander locationExdr; |
| private final FlexibleStringExpander shareScopeExdr; |
| |
| public Tree(ModelScreen modelScreen, Element treeElement) { |
| super(modelScreen, treeElement); |
| this.nameExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("name")); |
| this.locationExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("location")); |
| this.shareScopeExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("share-scope")); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| // Output format might not support trees, so make tree rendering optional. |
| TreeStringRenderer treeStringRenderer = (TreeStringRenderer) context.get("treeStringRenderer"); |
| if (treeStringRenderer == null) { |
| Debug.logVerbose("TreeStringRenderer instance not found in rendering context, tree not rendered.", module); |
| return; |
| } |
| boolean protectScope = !shareScope(context); |
| if (protectScope) { |
| if (!(context instanceof MapStack<?>)) { |
| context = MapStack.create(context); |
| } |
| UtilGenerics.<MapStack<String>>cast(context).push(); |
| } |
| |
| String name = this.getName(context); |
| String location = this.getLocation(context); |
| ModelTree modelTree = null; |
| try { |
| modelTree = TreeFactory.getTreeFromLocation(this.getLocation(context), this.getName(context), getModelScreen().getDelegator(context), getModelScreen().getDispatcher(context)); |
| } catch (IOException e) { |
| String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } catch (SAXException e) { |
| String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } catch (ParserConfigurationException e) { |
| String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| StringBuffer renderBuffer = new StringBuffer(); |
| modelTree.renderTreeString(renderBuffer, context, treeStringRenderer); |
| try { |
| writer.append(renderBuffer.toString()); |
| } catch (IOException e) { |
| String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| |
| if (protectScope) { |
| UtilGenerics.<MapStack<String>>cast(context).pop(); |
| } |
| } |
| |
| public String getName(Map<String, Object> context) { |
| return this.nameExdr.expandString(context); |
| } |
| |
| public String getLocation(Map<String, Object> context) { |
| return this.locationExdr.expandString(context); |
| } |
| |
| public boolean shareScope(Map<String, Object> context) { |
| String shareScopeString = this.shareScopeExdr.expandString(context); |
| // defaults to false, so anything but true is false |
| return "true".equals(shareScopeString); |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class PlatformSpecific extends ModelScreenWidget { |
| public static final String TAG_NAME = "platform-specific"; |
| private final Map<String, ModelScreenWidget> subWidgets; |
| |
| public PlatformSpecific(ModelScreen modelScreen, Element platformSpecificElement) { |
| super(modelScreen, platformSpecificElement); |
| Map<String, ModelScreenWidget> subWidgets = new HashMap<String, ModelScreenWidget>(); |
| List<? extends Element> childElements = UtilXml.childElementList(platformSpecificElement); |
| if (childElements != null) { |
| for (Element childElement: childElements) { |
| if ("html".equals(childElement.getNodeName())) { |
| subWidgets.put("html", new HtmlWidget(modelScreen, childElement)); |
| } else if ("xsl-fo".equals(childElement.getNodeName())) { |
| subWidgets.put("xsl-fo", new HtmlWidget(modelScreen, childElement)); |
| } else if ("xml".equals(childElement.getNodeName())) { |
| subWidgets.put("xml", new HtmlWidget(modelScreen, childElement)); |
| } else { |
| throw new IllegalArgumentException("Tag not supported under the platform-specific tag with name: " + childElement.getNodeName()); |
| } |
| } |
| } |
| this.subWidgets = Collections.unmodifiableMap(subWidgets); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| ModelScreenWidget subWidget = null; |
| subWidget = subWidgets.get(screenStringRenderer.getRendererName()); |
| if (subWidget == null) { |
| // This is here for backward compatibility |
| Debug.logWarning("In platform-dependent could not find template for " + screenStringRenderer.getRendererName() + ", using the one for html.", module); |
| subWidget = subWidgets.get("html"); |
| } |
| if (subWidget != null) { |
| subWidget.renderWidgetString(writer, context, screenStringRenderer); |
| } |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| |
| public Map<String, ModelScreenWidget> getSubWidgets() { |
| return subWidgets; |
| } |
| } |
| |
| public static final class Content extends ModelScreenWidget { |
| public static final String TAG_NAME = "content"; |
| |
| private final FlexibleStringExpander contentId; |
| private final FlexibleStringExpander editRequest; |
| private final FlexibleStringExpander editContainerStyle; |
| private final FlexibleStringExpander enableEditName; |
| private final boolean xmlEscape; |
| private final FlexibleStringExpander dataResourceId; |
| private final String width; |
| private final String height; |
| private final String border; |
| |
| public Content(ModelScreen modelScreen, Element subContentElement) { |
| super(modelScreen, subContentElement); |
| this.contentId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("content-id")); |
| this.dataResourceId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("dataresource-id")); |
| this.editRequest = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-request")); |
| this.editContainerStyle = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-container-style")); |
| this.enableEditName = FlexibleStringExpander.getInstance(subContentElement.getAttribute("enable-edit-name")); |
| this.xmlEscape = "true".equals(subContentElement.getAttribute("xml-escape")); |
| String width = subContentElement.getAttribute("width"); |
| if (width.isEmpty()) |
| width = "60%"; |
| this.height = subContentElement.getAttribute("height"); |
| if (this.height.isEmpty()) |
| width = "400px"; |
| this.width = width; |
| this.border = subContentElement.getAttribute("border"); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) { |
| try { |
| // pushing the contentId on the context as "contentId" is done |
| // because many times there will be embedded "subcontent" elements |
| // that use the syntax: <subcontent content-id="${contentId}"... |
| // and this is a step to make sure that it is there. |
| Delegator delegator = (Delegator) context.get("delegator"); |
| GenericValue content = null; |
| String expandedDataResourceId = getDataResourceId(context); |
| String expandedContentId = getContentId(context); |
| if (!(context instanceof MapStack<?>)) { |
| context = MapStack.create(context); |
| } |
| |
| // This is an important step to make sure that the current contentId is in the context |
| // as templates that contain "subcontent" elements will expect to find the master |
| // contentId in the context as "contentId". |
| UtilGenerics.<MapStack<String>>cast(context).push(); |
| context.put("contentId", expandedContentId); |
| |
| if (expandedDataResourceId.isEmpty()) { |
| if (!expandedContentId.isEmpty()) { |
| content = EntityQuery.use(delegator).from("Content").where("contentId", expandedContentId).cache().queryOne(); |
| } else { |
| String errMsg = "contentId is empty."; |
| Debug.logError(errMsg, module); |
| return; |
| } |
| if (content != null) { |
| expandedDataResourceId = content.getString("dataResourceId"); |
| } else { |
| String errMsg = "Could not find content with contentId [" + expandedContentId + "] "; |
| Debug.logError(errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| GenericValue dataResource = null; |
| if (!expandedDataResourceId.isEmpty()) { |
| dataResource = EntityQuery.use(delegator).from("DataResource").where("dataResourceId", expandedDataResourceId).cache().queryOne(); |
| } |
| |
| String mimeTypeId = null; |
| if (dataResource != null) { |
| mimeTypeId = dataResource.getString("mimeTypeId"); |
| } |
| if (content != null) { |
| mimeTypeId = content.getString("mimeTypeId"); |
| } |
| |
| if (!(mimeTypeId != null |
| && ((mimeTypeId.indexOf("application") >= 0) || (mimeTypeId.indexOf("image")) >= 0))) { |
| screenStringRenderer.renderContentBegin(writer, context, this); |
| screenStringRenderer.renderContentBody(writer, context, this); |
| screenStringRenderer.renderContentEnd(writer, context, this); |
| } |
| UtilGenerics.<MapStack<String>>cast(context).pop(); |
| } catch (IOException e) { |
| String errMsg = "Error rendering content with contentId [" + getContentId(context) + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } catch (GenericEntityException e) { |
| String errMsg = "Error obtaining content with contentId [" + getContentId(context) + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| |
| } |
| |
| public String getContentId(Map<String, Object> context) { |
| return this.contentId.expandString(context); |
| } |
| |
| public String getDataResourceId() { |
| return this.dataResourceId.getOriginal(); |
| } |
| |
| public String getDataResourceId(Map<String, Object> context) { |
| return this.dataResourceId.expandString(context); |
| } |
| |
| public String getEditRequest(Map<String, Object> context) { |
| return this.editRequest.expandString(context); |
| } |
| |
| public String getEditContainerStyle(Map<String, Object> context) { |
| return this.editContainerStyle.expandString(context); |
| } |
| |
| public String getEnableEditName(Map<String, Object> context) { |
| return this.enableEditName.expandString(context); |
| } |
| |
| public boolean xmlEscape() { |
| return this.xmlEscape; |
| } |
| |
| public String getWidth() { |
| return this.width; |
| } |
| |
| public String getHeight() { |
| return this.height; |
| } |
| |
| public String getBorder() { |
| return this.border; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class SubContent extends ModelScreenWidget { |
| public static final String TAG_NAME = "sub-content"; |
| private final FlexibleStringExpander contentId; |
| private final FlexibleStringExpander mapKey; |
| private final FlexibleStringExpander editRequest; |
| private final FlexibleStringExpander editContainerStyle; |
| private final FlexibleStringExpander enableEditName; |
| private final boolean xmlEscape; |
| |
| public SubContent(ModelScreen modelScreen, Element subContentElement) { |
| super(modelScreen, subContentElement); |
| this.contentId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("content-id")); |
| String mapKey = subContentElement.getAttribute("map-key"); |
| if (mapKey.isEmpty()) { |
| mapKey = subContentElement.getAttribute("assoc-name"); |
| } |
| this.mapKey = FlexibleStringExpander.getInstance(mapKey); |
| this.editRequest = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-request")); |
| this.editContainerStyle = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-container-style")); |
| this.enableEditName = FlexibleStringExpander.getInstance(subContentElement.getAttribute("enable-edit-name")); |
| this.xmlEscape = "true".equals(subContentElement.getAttribute("xml-escape")); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) { |
| try { |
| screenStringRenderer.renderSubContentBegin(writer, context, this); |
| screenStringRenderer.renderSubContentBody(writer, context, this); |
| screenStringRenderer.renderSubContentEnd(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering subContent with contentId [" + getContentId(context) + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| public String getContentId(Map<String, Object> context) { |
| return this.contentId.expandString(context); |
| } |
| |
| public String getMapKey(Map<String, Object> context) { |
| return this.mapKey.expandString(context); |
| } |
| |
| public String getEditRequest(Map<String, Object> context) { |
| return this.editRequest.expandString(context); |
| } |
| |
| public String getEditContainerStyle(Map<String, Object> context) { |
| return this.editContainerStyle.expandString(context); |
| } |
| |
| public String getEnableEditName(Map<String, Object> context) { |
| return this.enableEditName.expandString(context); |
| } |
| |
| public boolean xmlEscape() { |
| return this.xmlEscape; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| // TODO Auto-generated method stub |
| |
| } |
| } |
| |
| public static final class Menu extends ModelScreenWidget { |
| public static final String TAG_NAME = "include-menu"; |
| private final FlexibleStringExpander nameExdr; |
| private final FlexibleStringExpander locationExdr; |
| |
| public Menu(ModelScreen modelScreen, Element menuElement) { |
| super(modelScreen, menuElement); |
| this.nameExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("name")); |
| this.locationExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("location")); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws IOException { |
| // Output format might not support menus, so make menu rendering optional. |
| MenuStringRenderer menuStringRenderer = (MenuStringRenderer) context.get("menuStringRenderer"); |
| if (menuStringRenderer == null) { |
| Debug.logVerbose("MenuStringRenderer instance not found in rendering context, menu not rendered.", module); |
| return; |
| } |
| ModelMenu modelMenu = getModelMenu(context); |
| modelMenu.renderMenuString(writer, context, menuStringRenderer); |
| } |
| |
| public ModelMenu getModelMenu(Map<String, Object> context) { |
| String name = this.getName(context); |
| String location = this.getLocation(context); |
| ModelMenu modelMenu = null; |
| try { |
| modelMenu = MenuFactory.getMenuFromLocation(location, name); |
| } catch (Exception e) { |
| String errMsg = "Error rendering included menu named [" + name + "] at location [" + location + "]: "; |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg + e); |
| } |
| return modelMenu; |
| } |
| |
| public String getName(Map<String, Object> context) { |
| return this.nameExdr.expandString(context); |
| } |
| |
| public String getLocation(Map<String, Object> context) { |
| return this.locationExdr.expandString(context); |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class Link extends ModelScreenWidget { |
| public static final String TAG_NAME = "link"; |
| private final FlexibleStringExpander textExdr; |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander styleExdr; |
| private final FlexibleStringExpander targetExdr; |
| private final FlexibleStringExpander targetWindowExdr; |
| private final FlexibleStringExpander prefixExdr; |
| private final FlexibleStringExpander nameExdr; |
| private final Image image; |
| private final String urlMode; |
| private final boolean fullPath; |
| private final boolean secure; |
| private final boolean encode; |
| private final String linkType; |
| private final String width; |
| private final String height; |
| private final List<WidgetWorker.Parameter> parameterList; |
| private final WidgetWorker.AutoServiceParameters autoServiceParameters; |
| private final WidgetWorker.AutoEntityParameters autoEntityParameters; |
| |
| public Link(ModelScreen modelScreen, Element linkElement) { |
| super(modelScreen, linkElement); |
| this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text")); |
| this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id")); |
| this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style")); |
| this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name")); |
| this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target")); |
| this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window")); |
| this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix")); |
| this.urlMode = linkElement.getAttribute("url-mode"); |
| this.fullPath = "true".equals(linkElement.getAttribute("full-path")); |
| this.secure = "true".equals(linkElement.getAttribute("secure")); |
| this.encode = "true".equals(linkElement.getAttribute("encode")); |
| Element imageElement = UtilXml.firstChildElement(linkElement, "image"); |
| if (imageElement != null) { |
| this.image = new Image(modelScreen, imageElement); |
| } else { |
| this.image = null; |
| } |
| this.linkType = linkElement.getAttribute("link-type"); |
| List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter"); |
| if (parameterElementList.isEmpty()) { |
| this.parameterList = Collections.emptyList(); |
| } else { |
| List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>(parameterElementList.size()); |
| for (Element parameterElement : parameterElementList) { |
| parameterList.add(new WidgetWorker.Parameter(parameterElement)); |
| } |
| this.parameterList = Collections.unmodifiableList(parameterList); |
| } |
| Element autoServiceParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-service"); |
| if (autoServiceParamsElement != null) { |
| this.autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement); |
| } else { |
| this.autoServiceParameters = null; |
| } |
| Element autoEntityParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-entity"); |
| if (autoEntityParamsElement != null) { |
| this.autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement); |
| } else { |
| this.autoEntityParameters = null; |
| } |
| this.width = linkElement.getAttribute("width"); |
| this.height = linkElement.getAttribute("height"); |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) { |
| try { |
| screenStringRenderer.renderLink(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering link with id [" + getId(context) + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| public String getText(Map<String, Object> context) { |
| String text = this.textExdr.expandString(context); |
| StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder"); |
| if (simpleEncoder != null) { |
| text = simpleEncoder.encode(text); |
| } |
| return text; |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public String getStyle(Map<String, Object> context) { |
| return this.styleExdr.expandString(context); |
| } |
| |
| public String getTarget(Map<String, Object> context) { |
| Map<String, Object> expanderContext = context; |
| StringUtil.SimpleEncoder simpleEncoder = context == null ? null : (StringUtil.SimpleEncoder) context.get("simpleEncoder"); |
| if (simpleEncoder != null) { |
| expanderContext = StringUtil.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder); |
| } |
| return this.targetExdr.expandString(expanderContext); |
| } |
| |
| public String getName(Map<String, Object> context) { |
| return this.nameExdr.expandString(context); |
| } |
| |
| public String getTargetWindow(Map<String, Object> context) { |
| return this.targetWindowExdr.expandString(context); |
| } |
| |
| public String getUrlMode() { |
| return this.urlMode; |
| } |
| |
| public String getPrefix(Map<String, Object> context) { |
| return this.prefixExdr.expandString(context); |
| } |
| |
| public boolean getFullPath() { |
| return this.fullPath; |
| } |
| |
| public boolean getSecure() { |
| return this.secure; |
| } |
| |
| public boolean getEncode() { |
| return this.encode; |
| } |
| |
| public Image getImage() { |
| return this.image; |
| } |
| |
| public String getLinkType() { |
| return this.linkType; |
| } |
| |
| public String getWidth() { |
| return this.width; |
| } |
| |
| public String getHeight() { |
| return this.height; |
| } |
| |
| public Map<String, String> getParameterMap(Map<String, Object> context) { |
| Map<String, String> fullParameterMap = new HashMap<String, String>(); |
| |
| /* leaving this here... may want to add it at some point like the hyperlink element: |
| Map<String, String> addlParamMap = this.parametersMapAcsr.get(context); |
| if (addlParamMap != null) { |
| fullParameterMap.putAll(addlParamMap); |
| } |
| */ |
| |
| for (WidgetWorker.Parameter parameter: this.parameterList) { |
| fullParameterMap.put(parameter.getName(), parameter.getValue(context)); |
| } |
| |
| if (autoServiceParameters != null) { |
| fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, null)); |
| } |
| if (autoEntityParameters != null) { |
| fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, null)); |
| } |
| |
| return fullParameterMap; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class Image extends ModelScreenWidget { |
| public static final String TAG_NAME = "image"; |
| private final FlexibleStringExpander srcExdr; |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander styleExdr; |
| private final FlexibleStringExpander widthExdr; |
| private final FlexibleStringExpander heightExdr; |
| private final FlexibleStringExpander borderExdr; |
| private final FlexibleStringExpander alt; |
| private final String urlMode; |
| |
| public Image(ModelScreen modelScreen, Element imageElement) { |
| super(modelScreen, imageElement); |
| this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("src")); |
| this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id")); |
| this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style")); |
| this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width")); |
| this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height")); |
| this.borderExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("border")); |
| this.alt = FlexibleStringExpander.getInstance(imageElement.getAttribute("alt")); |
| String urlMode = imageElement.getAttribute("url-mode"); |
| if (urlMode.isEmpty()) { |
| urlMode = "content"; |
| } |
| this.urlMode = urlMode; |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) { |
| try { |
| screenStringRenderer.renderImage(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering image with id [" + getId(context) + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| public String getSrc(Map<String, Object> context) { |
| return this.srcExdr.expandString(context); |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public String getStyle(Map<String, Object> context) { |
| return this.styleExdr.expandString(context); |
| } |
| |
| public String getWidth(Map<String, Object> context) { |
| return this.widthExdr.expandString(context); |
| } |
| |
| public String getHeight(Map<String, Object> context) { |
| return this.heightExdr.expandString(context); |
| } |
| |
| public String getBorder(Map<String, Object> context) { |
| return this.borderExdr.expandString(context); |
| } |
| |
| public String getAlt(Map<String, Object> context) { |
| String alt = this.alt.expandString(context); |
| StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder"); |
| if (simpleEncoder != null) { |
| alt = simpleEncoder.encode(alt); |
| } |
| return alt; |
| } |
| |
| public String getUrlMode() { |
| return this.urlMode; |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| public static final class PortalPage extends ModelScreenWidget { |
| public static final String TAG_NAME = "include-portal-page"; |
| private final FlexibleStringExpander idExdr; |
| private final FlexibleStringExpander confModeExdr; |
| private final Boolean usePrivate; |
| |
| public PortalPage(ModelScreen modelScreen, Element portalPageElement) { |
| super(modelScreen, portalPageElement); |
| this.idExdr = FlexibleStringExpander.getInstance(portalPageElement.getAttribute("id")); |
| this.confModeExdr = FlexibleStringExpander.getInstance(portalPageElement.getAttribute("conf-mode")); |
| this.usePrivate = !("false".equals(portalPageElement.getAttribute("use-private"))); |
| } |
| |
| private GenericValue getPortalPageValue(Map<String, Object> context) { |
| Delegator delegator = (Delegator) context.get("delegator"); |
| String expandedPortalPageId = getId(context); |
| GenericValue portalPage = null; |
| if (!expandedPortalPageId.isEmpty()) { |
| if (usePrivate) { |
| portalPage = PortalPageWorker.getPortalPage(expandedPortalPageId, context); |
| } else { |
| try { |
| portalPage = EntityQuery.use(delegator).from("PortalPage").where("portalPageId", expandedPortalPageId) |
| .cache().queryOne(); |
| } catch (GenericEntityException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| } |
| if (portalPage == null) { |
| String errMsg = "Could not find PortalPage with portalPageId [" + expandedPortalPageId + "] "; |
| Debug.logError(errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| return portalPage; |
| } |
| |
| @Override |
| public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { |
| try { |
| Delegator delegator = (Delegator) context.get("delegator"); |
| List<GenericValue> portalPageColumns = null; |
| List<GenericValue> portalPagePortlets = null; |
| List<GenericValue> portletAttributes = null; |
| GenericValue portalPage = getPortalPageValue(context); |
| String actualPortalPageId = portalPage.getString("portalPageId"); |
| portalPageColumns = delegator.findByAnd("PortalPageColumn", UtilMisc.toMap("portalPageId", actualPortalPageId), |
| UtilMisc.toList("columnSeqId"), true); |
| |
| // Renders the portalPage header |
| screenStringRenderer.renderPortalPageBegin(writer, context, this); |
| |
| // First column has no previous column |
| String prevColumnSeqId = ""; |
| |
| // Iterates through the PortalPage columns |
| ListIterator <GenericValue>columnsIterator = portalPageColumns.listIterator(); |
| while(columnsIterator.hasNext()) { |
| GenericValue columnValue = columnsIterator.next(); |
| String columnSeqId = columnValue.getString("columnSeqId"); |
| |
| // Renders the portalPageColumn header |
| screenStringRenderer.renderPortalPageColumnBegin(writer, context, this, columnValue); |
| |
| // Get the Portlets located in the current column |
| portalPagePortlets = delegator.findByAnd("PortalPagePortletView", UtilMisc.toMap("portalPageId", portalPage.getString("portalPageId"), "columnSeqId", columnSeqId), UtilMisc.toList("sequenceNum"), false); |
| |
| // First Portlet in a Column has no previous Portlet |
| String prevPortletId = ""; |
| String prevPortletSeqId = ""; |
| |
| // If this is not the last column, get the next columnSeqId |
| String nextColumnSeqId = ""; |
| if (columnsIterator.hasNext()) { |
| nextColumnSeqId = portalPageColumns.get(columnsIterator.nextIndex()).getString("columnSeqId"); |
| } |
| |
| // Iterates through the Portlets in the Column |
| ListIterator <GenericValue>portletsIterator = portalPagePortlets.listIterator(); |
| while(portletsIterator.hasNext()) { |
| GenericValue portletValue = portletsIterator.next(); |
| |
| // If not the last portlet in the column, get the next nextPortletId and nextPortletSeqId |
| String nextPortletId = ""; |
| String nextPortletSeqId = ""; |
| if (portletsIterator.hasNext()) { |
| nextPortletId = portalPagePortlets.get(portletsIterator.nextIndex()).getString("portalPortletId"); |
| nextPortletSeqId = portalPagePortlets.get(portletsIterator.nextIndex()).getString("portletSeqId"); |
| } |
| |
| // Set info to allow portlet movement in the page |
| context.put("prevPortletId", prevPortletId); |
| context.put("prevPortletSeqId", prevPortletSeqId); |
| context.put("nextPortletId", nextPortletId); |
| context.put("nextPortletSeqId", nextPortletSeqId); |
| context.put("prevColumnSeqId", prevColumnSeqId); |
| context.put("nextColumnSeqId", nextColumnSeqId); |
| |
| // Get portlet's attributes |
| portletAttributes = delegator.findList("PortletAttribute", |
| EntityCondition.makeCondition(UtilMisc.toMap("portalPageId", portletValue.get("portalPageId"), "portalPortletId", portletValue.get("portalPortletId"), "portletSeqId", portletValue.get("portletSeqId"))), |
| null, null, null, false); |
| ListIterator <GenericValue>attributesIterator = portletAttributes.listIterator(); |
| while (attributesIterator.hasNext()) { |
| GenericValue attribute = attributesIterator.next(); |
| context.put(attribute.getString("attrName"), attribute.getString("attrValue")); |
| } |
| |
| // Renders the portalPagePortlet |
| screenStringRenderer.renderPortalPagePortletBegin(writer, context, this, portletValue); |
| screenStringRenderer.renderPortalPagePortletBody(writer, context, this, portletValue); |
| screenStringRenderer.renderPortalPagePortletEnd(writer, context, this, portletValue); |
| |
| // Remove the portlet's attributes so that these are not available for other portlets |
| while (attributesIterator.hasPrevious()) { |
| GenericValue attribute = attributesIterator.previous(); |
| context.remove(attribute.getString("attrName")); |
| } |
| |
| // Uses the actual portlet as prevPortlet for next iteration |
| prevPortletId = (String) portletValue.get("portalPortletId"); |
| prevPortletSeqId = (String) portletValue.get("portletSeqId"); |
| } |
| // Renders the portalPageColumn footer |
| screenStringRenderer.renderPortalPageColumnEnd(writer, context, this, columnValue); |
| |
| // Uses the actual columnSeqId as prevColumnSeqId for next iteration |
| prevColumnSeqId = columnSeqId; |
| } |
| // Renders the portalPage footer |
| screenStringRenderer.renderPortalPageEnd(writer, context, this); |
| } catch (IOException e) { |
| String errMsg = "Error rendering PortalPage with portalPageId [" + getId(context) + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } catch (GenericEntityException e) { |
| String errMsg = "Error obtaining PortalPage with portalPageId [" + getId(context) + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new RuntimeException(errMsg); |
| } |
| } |
| |
| public String getId(Map<String, Object> context) { |
| return this.idExdr.expandString(context); |
| } |
| |
| public String getOriginalPortalPageId(Map<String, Object> context) { |
| GenericValue portalPage = getPortalPageValue(context); |
| return portalPage.getString("originalPortalPageId"); |
| } |
| |
| public String getActualPortalPageId(Map<String, Object> context) { |
| GenericValue portalPage = getPortalPageValue(context); |
| return portalPage.getString("portalPageId"); |
| } |
| |
| public String getConfMode(Map<String, Object> context) { |
| return this.confModeExdr.expandString(context); |
| } |
| |
| public String getUsePrivate() { |
| return Boolean.toString(this.usePrivate); |
| } |
| |
| @Override |
| public void accept(ModelWidgetVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| } |
| |
| } |