Save This Page
Home » apache-ofbiz-09.04 » org.ofbiz.widget.screen » [javadoc | source]
    1   /*******************************************************************************
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    *******************************************************************************/
   19   package org.ofbiz.widget.screen;
   20   
   21   import java.io.IOException;
   22   import java.io.Serializable;
   23   import java.util.Collection;
   24   import java.util.HashMap;
   25   import java.util.List;
   26   import java.util.Map;
   27   
   28   import javax.servlet.http.HttpServletRequest;
   29   import javax.servlet.http.HttpServletResponse;
   30   import javax.xml.parsers.ParserConfigurationException;
   31   
   32   import javolution.util.FastList;
   33   
   34   import org.ofbiz.base.util.Debug;
   35   import org.ofbiz.base.util.GeneralException;
   36   import org.ofbiz.base.util.StringUtil;
   37   import org.ofbiz.base.util.UtilFormatOut;
   38   import org.ofbiz.base.util.UtilGenerics;
   39   import org.ofbiz.base.util.UtilMisc;
   40   import org.ofbiz.base.util.UtilValidate;
   41   import org.ofbiz.base.util.UtilXml;
   42   import org.ofbiz.base.util.collections.MapStack;
   43   import org.ofbiz.base.util.string.FlexibleStringExpander;
   44   import org.ofbiz.entity.GenericDelegator;
   45   import org.ofbiz.entity.GenericEntityException;
   46   import org.ofbiz.entity.GenericValue;
   47   import org.ofbiz.widget.ModelWidget;
   48   import org.ofbiz.widget.WidgetWorker;
   49   import org.ofbiz.widget.fo.FoScreenRenderer;
   50   import org.ofbiz.widget.form.FormFactory;
   51   import org.ofbiz.widget.form.FormStringRenderer;
   52   import org.ofbiz.widget.form.ModelForm;
   53   import org.ofbiz.widget.html.HtmlFormRenderer;
   54   import org.ofbiz.widget.html.HtmlMenuRenderer;
   55   import org.ofbiz.widget.html.HtmlTreeRenderer;
   56   import org.ofbiz.widget.menu.MenuFactory;
   57   import org.ofbiz.widget.menu.MenuStringRenderer;
   58   import org.ofbiz.widget.menu.ModelMenu;
   59   import org.ofbiz.widget.tree.ModelTree;
   60   import org.ofbiz.widget.tree.TreeFactory;
   61   import org.ofbiz.widget.tree.TreeStringRenderer;
   62   import org.ofbiz.widget.xml.XmlFormRenderer;
   63   import org.w3c.dom.Element;
   64   import org.xml.sax.SAXException;
   65   
   66   /**
   67    * Widget Library - Screen model class
   68    */
   69   @SuppressWarnings("serial")
   70   public abstract class ModelScreenWidget extends ModelWidget implements Serializable {
   71       public static final String module = ModelScreenWidget.class.getName();
   72   
   73       protected ModelScreen modelScreen;
   74   
   75       public ModelScreenWidget(ModelScreen modelScreen, Element widgetElement) {
   76           super(widgetElement);
   77           this.modelScreen = modelScreen;
   78           if (Debug.verboseOn()) Debug.logVerbose("Reading Screen sub-widget with name: " + widgetElement.getNodeName(), module);
   79       }
   80   
   81       public abstract void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException;
   82   
   83       public abstract String rawString();
   84   
   85       public static List<ModelScreenWidget> readSubWidgets(ModelScreen modelScreen, List<? extends Element> subElementList) {
   86           List<ModelScreenWidget> subWidgets = FastList.newInstance();
   87           for (Element subElement: subElementList) {
   88               if ("section".equals(subElement.getNodeName())) {
   89                   subWidgets.add(new Section(modelScreen, subElement));
   90               } else if ("container".equals(subElement.getNodeName())) {
   91                   subWidgets.add(new Container(modelScreen, subElement));
   92               } else if ("screenlet".equals(subElement.getNodeName())) {
   93                   subWidgets.add(new Screenlet(modelScreen, subElement));
   94               } else if ("include-screen".equals(subElement.getNodeName())) {
   95                   subWidgets.add(new IncludeScreen(modelScreen, subElement));
   96               } else if ("decorator-screen".equals(subElement.getNodeName())) {
   97                   subWidgets.add(new DecoratorScreen(modelScreen, subElement));
   98               } else if ("decorator-section-include".equals(subElement.getNodeName())) {
   99                   subWidgets.add(new DecoratorSectionInclude(modelScreen, subElement));
  100               } else if ("label".equals(subElement.getNodeName())) {
  101                   subWidgets.add(new Label(modelScreen, subElement));
  102               } else if ("include-form".equals(subElement.getNodeName())) {
  103                   subWidgets.add(new Form(modelScreen, subElement));
  104               } else if ("include-menu".equals(subElement.getNodeName())) {
  105                   subWidgets.add(new Menu(modelScreen, subElement));
  106               } else if ("include-tree".equals(subElement.getNodeName())) {
  107                   subWidgets.add(new Tree(modelScreen, subElement));
  108               } else if ("content".equals(subElement.getNodeName())) {
  109                   subWidgets.add(new Content(modelScreen, subElement));
  110               } else if ("sub-content".equals(subElement.getNodeName())) {
  111                   subWidgets.add(new SubContent(modelScreen, subElement));
  112               } else if ("platform-specific".equals(subElement.getNodeName())) {
  113                   subWidgets.add(new PlatformSpecific(modelScreen, subElement));
  114               } else if ("link".equals(subElement.getNodeName())) {
  115                   subWidgets.add(new Link(modelScreen, subElement));
  116               } else if ("image".equals(subElement.getNodeName())) {
  117                   subWidgets.add(new Image(modelScreen, subElement));
  118               } else if ("iterate-section".equals(subElement.getNodeName())) {
  119                   subWidgets.add(new IterateSectionWidget(modelScreen, subElement));
  120               } else if ("horizontal-separator".equals(subElement.getNodeName())) {
  121                   subWidgets.add(new HorizontalSeparator(modelScreen, subElement));
  122               } else {
  123                   throw new IllegalArgumentException("Found invalid screen widget element with name: " + subElement.getNodeName());
  124               }
  125           }
  126   
  127           return subWidgets;
  128       }
  129   
  130       public static void renderSubWidgetsString(List<ModelScreenWidget> subWidgets, Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  131           if (subWidgets == null) {
  132               return;
  133           }
  134           for (ModelScreenWidget subWidget: subWidgets) {
  135               if (Debug.verboseOn()) Debug.logVerbose("Rendering screen " + subWidget.modelScreen.getName() + "; widget class is " + subWidget.getClass().getName(), module);
  136   
  137               // render the sub-widget itself
  138               subWidget.renderWidgetString(writer, context, screenStringRenderer);
  139           }
  140       }
  141   
  142       public boolean boundaryCommentsEnabled() {
  143           return modelScreen.boundaryCommentsEnabled();
  144       }
  145   
  146       public ModelScreen getModelScreen() {
  147           return this.modelScreen;
  148       }
  149   
  150       public static class SectionsRenderer extends HashMap<String, Object> {
  151           protected ScreenStringRenderer screenStringRenderer;
  152           protected Map<String, Object> context;
  153           protected Appendable writer;
  154   
  155           public SectionsRenderer(Map<String, ? extends Object> sectionMap, Map<String, Object> context, Appendable writer, ScreenStringRenderer screenStringRenderer) {
  156               this.putAll(sectionMap);
  157               this.context = context;
  158               this.writer = writer;
  159               this.screenStringRenderer = screenStringRenderer;
  160           }
  161   
  162           /** This is a lot like the ScreenRenderer class and returns an empty String so it can be used more easily with FreeMarker */
  163           public String render(String sectionName) throws GeneralException, IOException {
  164               ModelScreenWidget section = (ModelScreenWidget) this.get(sectionName);
  165               // if no section by that name, write nothing
  166               if (section != null) {
  167                   section.renderWidgetString(this.writer, this.context, this.screenStringRenderer);
  168               }
  169               return "";
  170           }
  171       }
  172   
  173       public static class Section extends ModelScreenWidget {
  174           protected ModelScreenCondition condition;
  175           protected List<ModelScreenAction> actions;
  176           protected List<ModelScreenWidget> subWidgets;
  177           protected List<ModelScreenWidget> failWidgets;
  178           public boolean isMainSection = false;
  179   
  180           public Section(ModelScreen modelScreen, Element sectionElement) {
  181               super(modelScreen, sectionElement);
  182   
  183               // read condition under the "condition" element
  184               Element conditionElement = UtilXml.firstChildElement(sectionElement, "condition");
  185               if (conditionElement != null) {
  186                   this.condition = new ModelScreenCondition(modelScreen, conditionElement);
  187               }
  188   
  189               // read all actions under the "actions" element
  190               Element actionsElement = UtilXml.firstChildElement(sectionElement, "actions");
  191               if (actionsElement != null) {
  192                   this.actions = ModelScreenAction.readSubActions(modelScreen, actionsElement);
  193               }
  194   
  195               // read sub-widgets
  196               Element widgetsElement = UtilXml.firstChildElement(sectionElement, "widgets");
  197               List<? extends Element> subElementList = UtilXml.childElementList(widgetsElement);
  198               this.subWidgets = ModelScreenWidget.readSubWidgets(this.modelScreen, subElementList);
  199   
  200               // read fail-widgets
  201               Element failWidgetsElement = UtilXml.firstChildElement(sectionElement, "fail-widgets");
  202               if (failWidgetsElement != null) {
  203                   List<? extends Element> failElementList = UtilXml.childElementList(failWidgetsElement);
  204                   this.failWidgets = ModelScreenWidget.readSubWidgets(this.modelScreen, failElementList);
  205               }
  206           }
  207   
  208           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  209               // check the condition, if there is one
  210               boolean condTrue = true;
  211               if (this.condition != null) {
  212                   if (!this.condition.eval(context)) {
  213                       condTrue = false;
  214                   }
  215               }
  216   
  217               // if condition does not exist or evals to true run actions and render widgets, otherwise render fail-widgets
  218               if (condTrue) {
  219                   // run the actions only if true
  220                   ModelScreenAction.runSubActions(this.actions, context);
  221   
  222                   try {
  223                       // section by definition do not themselves do anything, so this method will generally do nothing, but we'll call it anyway
  224                       screenStringRenderer.renderSectionBegin(writer, context, this);
  225   
  226                       // render sub-widgets
  227                       renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
  228   
  229                       screenStringRenderer.renderSectionEnd(writer, context, this);
  230                   } catch (IOException e) {
  231                       String errMsg = "Error rendering widgets section [" + this.getName() + "] in screen named [" + this.modelScreen.getName() + "]: " + e.toString();
  232                       Debug.logError(e, errMsg, module);
  233                       throw new RuntimeException(errMsg);
  234                   }
  235               } else {
  236                   try {
  237                       // section by definition do not themselves do anything, so this method will generally do nothing, but we'll call it anyway
  238                       screenStringRenderer.renderSectionBegin(writer, context, this);
  239   
  240                       // render sub-widgets
  241                       renderSubWidgetsString(this.failWidgets, writer, context, screenStringRenderer);
  242   
  243                       screenStringRenderer.renderSectionEnd(writer, context, this);
  244                   } catch (IOException e) {
  245                       String errMsg = "Error rendering fail-widgets section [" + this.getName() + "] in screen named [" + this.modelScreen.getName() + "]: " + e.toString();
  246                       Debug.logError(e, errMsg, module);
  247                       throw new RuntimeException(errMsg);
  248                   }
  249               }
  250   
  251           }
  252   
  253           public String getBoundaryCommentName() {
  254               if (isMainSection) {
  255                   return modelScreen.getSourceLocation() + "#" + modelScreen.getName();
  256               } else {
  257                   return name;
  258               }
  259           }
  260   
  261           public String rawString() {
  262               return "<section" + (UtilValidate.isNotEmpty(this.name)?" name=\"" + this.name + "\"":"") + ">";
  263           }
  264       }
  265   
  266       public static class Container extends ModelScreenWidget {
  267           protected FlexibleStringExpander idExdr;
  268           protected FlexibleStringExpander styleExdr;
  269           protected FlexibleStringExpander autoUpdateTargetExdr;
  270           protected String autoUpdateInterval = "2";
  271           protected List<ModelScreenWidget> subWidgets;
  272   
  273           public Container(ModelScreen modelScreen, Element containerElement) {
  274               super(modelScreen, containerElement);
  275               this.idExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("id"));
  276               this.styleExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("style"));
  277               this.autoUpdateTargetExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("auto-update-target"));
  278               if (containerElement.hasAttribute("auto-update-interval")) {
  279                   this.autoUpdateInterval = containerElement.getAttribute("auto-update-interval");
  280               }
  281   
  282               // read sub-widgets
  283               List<? extends Element> subElementList = UtilXml.childElementList(containerElement);
  284               this.subWidgets = ModelScreenWidget.readSubWidgets(this.modelScreen, subElementList);
  285           }
  286   
  287           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  288               try {
  289                   screenStringRenderer.renderContainerBegin(writer, context, this);
  290   
  291                   // render sub-widgets
  292                   renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
  293   
  294                   screenStringRenderer.renderContainerEnd(writer, context, this);
  295               } catch (IOException e) {
  296                   String errMsg = "Error rendering container in screen named [" + this.modelScreen.getName() + "]: " + e.toString();
  297                   Debug.logError(e, errMsg, module);
  298                   throw new RuntimeException(errMsg);
  299               }
  300           }
  301   
  302           public String getId(Map<String, Object> context) {
  303               return this.idExdr.expandString(context);
  304           }
  305   
  306           public String getStyle(Map<String, Object> context) {
  307               return this.styleExdr.expandString(context);
  308           }
  309   
  310           public String getAutoUpdateTargetExdr(Map<String, Object> context) {
  311               return this.autoUpdateTargetExdr.expandString(context);
  312           }
  313   
  314           public String getAutoUpdateInterval() {
  315               return this.autoUpdateInterval;
  316           }
  317   
  318           public String rawString() {
  319               return "<container id=\"" + this.idExdr.getOriginal() + "\" style=\"" + this.styleExdr.getOriginal() + "\" auto-update-target=\"" + this.autoUpdateTargetExdr.getOriginal() + "\">";
  320           }
  321       }
  322   
  323       public static class Screenlet extends ModelScreenWidget {
  324           protected FlexibleStringExpander idExdr;
  325           protected FlexibleStringExpander titleExdr;
  326           protected Menu navigationMenu = null;
  327           protected Menu tabMenu = null;
  328           protected Form navigationForm = null;
  329           protected boolean collapsible = false;
  330           protected boolean initiallyCollapsed = false;
  331           protected boolean padded = true;
  332           protected List<ModelScreenWidget> subWidgets;
  333   
  334           public Screenlet(ModelScreen modelScreen, Element screenletElement) {
  335               super(modelScreen, screenletElement);
  336               this.idExdr = FlexibleStringExpander.getInstance(screenletElement.getAttribute("id"));
  337               this.collapsible = "true".equals(screenletElement.getAttribute("collapsible"));
  338               this.initiallyCollapsed = "true".equals(screenletElement.getAttribute("initially-collapsed"));
  339               if (this.initiallyCollapsed) {
  340                   this.collapsible = true;
  341               }
  342               this.padded = !"false".equals(screenletElement.getAttribute("padded"));
  343               if (this.collapsible && UtilValidate.isEmpty(this.name) && idExdr.isEmpty()) {
  344                   throw new IllegalArgumentException("Collapsible screenlets must have a name or id [" + this.modelScreen.getName() + "]");
  345               }
  346               this.titleExdr = FlexibleStringExpander.getInstance(screenletElement.getAttribute("title"));
  347               List<? extends Element> subElementList = UtilXml.childElementList(screenletElement);
  348               this.subWidgets = ModelScreenWidget.readSubWidgets(this.modelScreen, subElementList);
  349               String navMenuName = screenletElement.getAttribute("navigation-menu-name");
  350               if (UtilValidate.isNotEmpty(navMenuName)) {
  351                   for (ModelWidget subWidget : this.subWidgets) {
  352                       if (navMenuName.equals(subWidget.getName()) && subWidget instanceof Menu) {
  353                           this.navigationMenu = (Menu) subWidget;
  354                           subWidgets.remove(subWidget);
  355                           break;
  356                       }
  357                   }
  358               }
  359               String tabMenuName = screenletElement.getAttribute("tab-menu-name");
  360               if (UtilValidate.isNotEmpty(tabMenuName)) {
  361                   for (ModelWidget subWidget : this.subWidgets) {
  362                       if (tabMenuName.equals(subWidget.getName()) && subWidget instanceof Menu) {
  363                           this.tabMenu = (Menu) subWidget;
  364                           subWidgets.remove(subWidget);
  365                           break;
  366                       }
  367                   }
  368               }
  369               String formName = screenletElement.getAttribute("navigation-form-name");
  370               if (UtilValidate.isNotEmpty(formName) && this.navigationMenu == null) {
  371                   for (ModelWidget subWidget : this.subWidgets) {
  372                       if (formName.equals(subWidget.getName()) && subWidget instanceof Form) {
  373                           this.navigationForm = (Form) subWidget;
  374                           // Let's give this a try, it can be removed later if it
  375                           // proves to cause problems
  376                           this.padded = false;
  377                           break;
  378                       }
  379                   }
  380               }
  381           }
  382   
  383           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  384               boolean collapsed = initiallyCollapsed;
  385               if (this.collapsible) {
  386                   String preferenceKey = getPreferenceKey(context) + "_collapsed";
  387                   Map<String, Object> requestParameters = UtilGenerics.checkMap(context.get("requestParameters"));
  388                   if (requestParameters != null) {
  389                       String collapsedParam = (String) requestParameters.get(preferenceKey);
  390                       if (UtilValidate.isNotEmpty(collapsedParam)) {
  391                           collapsed = "true".equals(collapsedParam);
  392                       }
  393                   }
  394               }
  395               try {
  396                   screenStringRenderer.renderScreenletBegin(writer, context, collapsed, this);
  397                   for (ModelScreenWidget subWidget : this.subWidgets) {
  398                       screenStringRenderer.renderScreenletSubWidget(writer, context, subWidget, this);
  399                   }
  400                   screenStringRenderer.renderScreenletEnd(writer, context, this);
  401               } catch (IOException e) {
  402                   String errMsg = "Error rendering screenlet in screen named [" + this.modelScreen.getName() + "]: ";
  403                   Debug.logError(e, errMsg, module);
  404                   throw new RuntimeException(errMsg + e);
  405               }
  406           }
  407   
  408           public boolean collapsible() {
  409               return this.collapsible;
  410           }
  411   
  412           public boolean initiallyCollapsed() {
  413               return this.initiallyCollapsed;
  414           }
  415   
  416           public boolean padded() {
  417               return this.padded;
  418           }
  419   
  420           public String getPreferenceKey(Map<String, Object> context) {
  421               String name = this.idExdr.expandString(context);
  422               if (UtilValidate.isEmpty(name)) {
  423                   name = "screenlet" + "_" + Integer.toHexString(hashCode());
  424               }
  425               return name;
  426           }
  427   
  428           public String getId(Map<String, Object> context) {
  429               return this.idExdr.expandString(context);
  430           }
  431   
  432           public String getTitle(Map<String, Object> context) {
  433               return this.titleExdr.expandString(context);
  434           }
  435   
  436           public Menu getNavigationMenu() {
  437               return this.navigationMenu;
  438           }
  439   
  440           public Form getNavigationForm() {
  441               return this.navigationForm;
  442           }
  443   
  444           public Menu getTabMenu() {
  445               return this.tabMenu;
  446           }
  447   
  448           public String rawString() {
  449               return "<screenlet id=\"" + this.idExdr.getOriginal() + "\" title=\"" + this.titleExdr.getOriginal() + "\">";
  450           }
  451       }
  452   
  453       public static class HorizontalSeparator extends ModelScreenWidget {
  454           protected FlexibleStringExpander idExdr;
  455           protected FlexibleStringExpander styleExdr;
  456   
  457           public HorizontalSeparator(ModelScreen modelScreen, Element separatorElement) {
  458               super(modelScreen, separatorElement);
  459               this.idExdr = FlexibleStringExpander.getInstance(separatorElement.getAttribute("id"));
  460               this.styleExdr = FlexibleStringExpander.getInstance(separatorElement.getAttribute("style"));
  461           }
  462   
  463           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  464               screenStringRenderer.renderHorizontalSeparator(writer, context, this);
  465           }
  466   
  467           public String getId(Map<String, Object> context) {
  468               return this.idExdr.expandString(context);
  469           }
  470   
  471           public String getStyle(Map<String, Object> context) {
  472               return this.styleExdr.expandString(context);
  473           }
  474   
  475           public String rawString() {
  476               return "<horizontal-separator id=\"" + this.idExdr.getOriginal() + "\" name=\"" + this.idExdr.getOriginal() + "\" style=\"" + this.styleExdr.getOriginal() + "\">";
  477           }
  478       }
  479   
  480       public static class IncludeScreen extends ModelScreenWidget {
  481           protected FlexibleStringExpander nameExdr;
  482           protected FlexibleStringExpander locationExdr;
  483           protected FlexibleStringExpander shareScopeExdr;
  484   
  485           public IncludeScreen(ModelScreen modelScreen, Element includeScreenElement) {
  486               super(modelScreen, includeScreenElement);
  487               this.nameExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("name"));
  488               this.locationExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("location"));
  489               this.shareScopeExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("share-scope"));
  490           }
  491   
  492           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  493               // if we are not sharing the scope, protect it using the MapStack
  494               boolean protectScope = !shareScope(context);
  495               if (protectScope) {
  496                   if (!(context instanceof MapStack)) {
  497                       context = MapStack.create(context);
  498                   }
  499   
  500                   ((MapStack) context).push();
  501   
  502                   // build the widgetpath
  503                   List<String> widgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
  504                   if (widgetTrail == null) {
  505                       widgetTrail = FastList.newInstance();
  506                   }
  507   
  508                   String thisName = nameExdr.expandString(context);
  509                   widgetTrail.add(thisName);
  510                   context.put("_WIDGETTRAIL_", widgetTrail);
  511               }
  512   
  513               // dont need the renderer here, will just pass this on down to another screen call; screenStringRenderer.renderContainerBegin(writer, context, this);
  514               String name = this.getName(context);
  515               String location = this.getLocation(context);
  516   
  517               if (UtilValidate.isEmpty(name)) {
  518                   if (Debug.verboseOn()) Debug.logVerbose("In the include-screen tag the screen name was empty, ignoring include; in screen [" + this.modelScreen.getName() + "]", module);
  519                   return;
  520               }
  521   
  522               // check to see if the name is a composite name separated by a #, if so split it up and get it by the full loc#name
  523               if (ScreenFactory.isCombinedName(name)) {
  524                   String combinedName = name;
  525                   location = ScreenFactory.getResourceNameFromCombined(combinedName);
  526                   name = ScreenFactory.getScreenNameFromCombined(combinedName);
  527               }
  528   
  529               ModelScreen modelScreen = null;
  530               if (UtilValidate.isNotEmpty(location)) {
  531                   try {
  532                       modelScreen = ScreenFactory.getScreenFromLocation(location, name);
  533                   } catch (IOException e) {
  534                       String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
  535                       Debug.logError(e, errMsg, module);
  536                       throw new RuntimeException(errMsg);
  537                   } catch (SAXException e) {
  538                       String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
  539                       Debug.logError(e, errMsg, module);
  540                       throw new RuntimeException(errMsg);
  541                   } catch (ParserConfigurationException e) {
  542                       String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
  543                       Debug.logError(e, errMsg, module);
  544                       throw new RuntimeException(errMsg);
  545                   }
  546               } else {
  547                   modelScreen = this.modelScreen.modelScreenMap.get(name);
  548                   if (modelScreen == null) {
  549                       throw new IllegalArgumentException("Could not find screen with name [" + name + "] in the same file as the screen with name [" + this.modelScreen.getName() + "]");
  550                   }
  551               }
  552               modelScreen.renderScreenString(writer, context, screenStringRenderer);
  553   
  554               if (protectScope) {
  555                   ((MapStack) context).pop();
  556               }
  557           }
  558   
  559           public String getName(Map<String, Object> context) {
  560               return this.nameExdr.expandString(context);
  561           }
  562   
  563           public String getLocation(Map<String, Object> context) {
  564               return this.locationExdr.expandString(context);
  565           }
  566   
  567           public boolean shareScope(Map<String, Object> context) {
  568               String shareScopeString = this.shareScopeExdr.expandString(context);
  569               // defaults to false, so anything but true is false
  570               return "true".equals(shareScopeString);
  571           }
  572   
  573           public String rawString() {
  574               return "<include-screen name=\"" + this.nameExdr.getOriginal() + "\" location=\"" + this.locationExdr.getOriginal() + "\" share-scope=\"" + this.shareScopeExdr.getOriginal() + "\"/>";
  575           }
  576       }
  577   
  578       public static class DecoratorScreen extends ModelScreenWidget {
  579           protected FlexibleStringExpander nameExdr;
  580           protected FlexibleStringExpander locationExdr;
  581           protected Map<String, DecoratorSection> sectionMap = new HashMap<String, DecoratorSection>();
  582   
  583           public DecoratorScreen(ModelScreen modelScreen, Element decoratorScreenElement) {
  584               super(modelScreen, decoratorScreenElement);
  585               this.nameExdr = FlexibleStringExpander.getInstance(decoratorScreenElement.getAttribute("name"));
  586               this.locationExdr = FlexibleStringExpander.getInstance(decoratorScreenElement.getAttribute("location"));
  587   
  588               List<? extends Element> decoratorSectionElementList = UtilXml.childElementList(decoratorScreenElement, "decorator-section");
  589               for (Element decoratorSectionElement: decoratorSectionElementList) {
  590                   String name = decoratorSectionElement.getAttribute("name");
  591                   this.sectionMap.put(name, new DecoratorSection(modelScreen, decoratorSectionElement));
  592               }
  593           }
  594   
  595           @SuppressWarnings("unchecked")
  596           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  597               // isolate the scope
  598               if (!(context instanceof MapStack)) {
  599                   context = MapStack.create(context);
  600               }
  601   
  602               MapStack contextMs = (MapStack) context;
  603   
  604               // 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
  605               MapStack standAloneStack = contextMs.standAloneChildStack();
  606               standAloneStack.put("screens", new ScreenRenderer(writer, standAloneStack, screenStringRenderer));
  607               SectionsRenderer sections = new SectionsRenderer(this.sectionMap, standAloneStack, writer, screenStringRenderer);
  608   
  609               // put the sectionMap in the context, make sure it is in the sub-scope, ie after calling push on the MapStack
  610               contextMs.push();
  611               context.put("sections", sections);
  612   
  613               String name = this.getName(context);
  614               String location = this.getLocation(context);
  615   
  616               // check to see if the name is a composite name separated by a #, if so split it up and get it by the full loc#name
  617               if (ScreenFactory.isCombinedName(name)) {
  618                   String combinedName = name;
  619                   location = ScreenFactory.getResourceNameFromCombined(combinedName);
  620                   name = ScreenFactory.getScreenNameFromCombined(combinedName);
  621               }
  622   
  623               ModelScreen modelScreen = null;
  624               if (UtilValidate.isNotEmpty(location)) {
  625                   try {
  626                       modelScreen = ScreenFactory.getScreenFromLocation(location, name);
  627                   } catch (IOException e) {
  628                       String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
  629                       Debug.logError(e, errMsg, module);
  630                       throw new RuntimeException(errMsg);
  631                   } catch (SAXException e) {
  632                       String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
  633                       Debug.logError(e, errMsg, module);
  634                       throw new RuntimeException(errMsg);
  635                   } catch (ParserConfigurationException e) {
  636                       String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
  637                       Debug.logError(e, errMsg, module);
  638                       throw new RuntimeException(errMsg);
  639                   }
  640               } else {
  641                   modelScreen = this.modelScreen.modelScreenMap.get(name);
  642                   if (modelScreen == null) {
  643                       throw new IllegalArgumentException("Could not find screen with name [" + name + "] in the same file as the screen with name [" + this.modelScreen.getName() + "]");
  644                   }
  645               }
  646               modelScreen.renderScreenString(writer, context, screenStringRenderer);
  647   
  648               contextMs.pop();
  649           }
  650   
  651           public String getName(Map<String, Object> context) {
  652               return this.nameExdr.expandString(context);
  653           }
  654   
  655           public String getLocation(Map<String, Object> context) {
  656               return this.locationExdr.expandString(context);
  657           }
  658   
  659           public String rawString() {
  660               return "<decorator-screen name=\"" + this.nameExdr.getOriginal() + "\" location=\"" + this.locationExdr.getOriginal() + "\"/>";
  661           }
  662       }
  663   
  664       public static class DecoratorSection extends ModelScreenWidget {
  665           protected List<ModelScreenWidget> subWidgets;
  666   
  667           public DecoratorSection(ModelScreen modelScreen, Element decoratorSectionElement) {
  668               super(modelScreen, decoratorSectionElement);
  669               // read sub-widgets
  670               List<? extends Element> subElementList = UtilXml.childElementList(decoratorSectionElement);
  671               this.subWidgets = ModelScreenWidget.readSubWidgets(this.modelScreen, subElementList);
  672           }
  673   
  674           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  675               // render sub-widgets
  676               renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
  677           }
  678   
  679           public String rawString() {
  680               return "<decorator-section name=\"" + this.name + "\">";
  681           }
  682       }
  683   
  684       public static class DecoratorSectionInclude extends ModelScreenWidget {
  685   
  686           public DecoratorSectionInclude(ModelScreen modelScreen, Element decoratorSectionElement) {
  687               super(modelScreen, decoratorSectionElement);
  688           }
  689   
  690           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  691               Map<String, ? extends Object> preRenderedContent = UtilGenerics.checkMap(context.get("preRenderedContent"));
  692               if (preRenderedContent != null && preRenderedContent.containsKey(this.name)) {
  693                   try {
  694                       writer.append((String) preRenderedContent.get(this.name));
  695                   } catch (IOException e) {
  696                       String errMsg = "Error rendering pre-rendered content in screen named [" + this.modelScreen.getName() + "]: " + e.toString();
  697                       Debug.logError(e, errMsg, module);
  698                       throw new RuntimeException(errMsg);
  699                   }
  700               } else {
  701                   SectionsRenderer sections = (SectionsRenderer) context.get("sections");
  702                   // for now if sections is null, just log a warning; may be permissible to make the screen for flexible
  703                   if (sections == null) {
  704                       Debug.logWarning("In decorator-section-include could not find sections object in the context, not rendering section with name [" + this.name + "]", module);
  705                   } else {
  706                       sections.render(this.name);
  707                   }
  708               }
  709           }
  710   
  711           public String rawString() {
  712               return "<decorator-section-include name=\"" + this.name + "\">";
  713           }
  714       }
  715   
  716       public static class Label extends ModelScreenWidget {
  717           protected FlexibleStringExpander textExdr;
  718   
  719           protected FlexibleStringExpander idExdr;
  720           protected FlexibleStringExpander styleExdr;
  721   
  722           public Label(ModelScreen modelScreen, Element labelElement) {
  723               super(modelScreen, labelElement);
  724   
  725               // put the text attribute first, then the pcdata under the element, if both are there of course
  726               String textAttr = UtilFormatOut.checkNull(labelElement.getAttribute("text"));
  727               String pcdata = UtilFormatOut.checkNull(UtilXml.elementValue(labelElement));
  728               this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata);
  729   
  730               this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id"));
  731               this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style"));
  732           }
  733   
  734           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
  735               try {
  736                   screenStringRenderer.renderLabel(writer, context, this);
  737               } catch (IOException e) {
  738                   String errMsg = "Error rendering label in screen named [" + this.modelScreen.getName() + "]: " + e.toString();
  739                   Debug.logError(e, errMsg, module);
  740                   throw new RuntimeException(errMsg);
  741               }
  742           }
  743   
  744           public String getText(Map<String, Object> context) {
  745               String text = this.textExdr.expandString(context);
  746               StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
  747               if (simpleEncoder != null) {
  748                   text = simpleEncoder.encode(text);
  749               }
  750               return text;
  751           }
  752   
  753           public String getId(Map<String, Object> context) {
  754               return this.idExdr.expandString(context);
  755           }
  756   
  757           public String getStyle(Map<String, Object> context) {
  758               return this.styleExdr.expandString(context);
  759           }
  760   
  761           public String rawString() {
  762               return "<label id=\"" + this.idExdr.getOriginal() + "\" style=\"" + this.styleExdr.getOriginal() + "\" text=\"" + this.textExdr.getOriginal() + "\"/>";
  763           }
  764       }
  765   
  766       public static class Form extends ModelScreenWidget {
  767           protected FlexibleStringExpander nameExdr;
  768           protected FlexibleStringExpander locationExdr;
  769           protected FlexibleStringExpander shareScopeExdr;
  770           protected ModelForm modelForm = null;
  771   
  772           public Form(ModelScreen modelScreen, Element formElement) {
  773               super(modelScreen, formElement);
  774   
  775               this.nameExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("name"));
  776               this.locationExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("location"));
  777               this.shareScopeExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("share-scope"));
  778           }
  779   
  780           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
  781               boolean protectScope = !shareScope(context);
  782               if (protectScope) {
  783                   if (!(context instanceof MapStack)) {
  784                       context = MapStack.create(context);
  785                   }
  786                   ((MapStack) context).push();
  787               }
  788   
  789               // try finding the formStringRenderer by name in the context in case one was prepared and put there
  790               FormStringRenderer formStringRenderer = (FormStringRenderer) context.get("formStringRenderer");
  791               // if there was no formStringRenderer put in place, now try finding the request/response in the context and creating a new one
  792               if (formStringRenderer == null) {
  793                   HttpServletRequest request = (HttpServletRequest) context.get("request");
  794                   HttpServletResponse response = (HttpServletResponse) context.get("response");
  795                   if (request != null && response != null) {
  796                       formStringRenderer = new HtmlFormRenderer(request, response);
  797                   }
  798               }
  799               // still null, throw an error
  800               if (formStringRenderer == null) {
  801                   throw new IllegalArgumentException("Could not find a formStringRenderer in the context, and could not find HTTP request/response objects need to create one.");
  802               }
  803   
  804               ModelForm modelForm = getModelForm(context);
  805               //Debug.logInfo("before renderFormString, context:" + context, module);
  806               try {
  807                   modelForm.renderFormString(writer, context, formStringRenderer);
  808               } catch (IOException e) {
  809                   String errMsg = "Error rendering included form named [" + name + "] at location [" + this.getLocation(context) + "]: " + e.toString();
  810                   Debug.logError(e, errMsg, module);
  811                   throw new RuntimeException(errMsg + e);
  812               }
  813   
  814               if (protectScope) {
  815                   ((MapStack) context).pop();
  816               }
  817           }
  818   
  819           public ModelForm getModelForm(Map<String, Object> context) {
  820               ModelForm modelForm = null;
  821               String name = this.getName(context);
  822               String location = this.getLocation(context);
  823               try {
  824                   modelForm = FormFactory.getFormFromLocation(location, name, this.modelScreen.getDelegator(context).getModelReader(), this.modelScreen.getDispatcher(context).getDispatchContext());
  825               } catch (Exception e) {
  826                   String errMsg = "Error rendering included form named [" + name + "] at location [" + location + "]: ";
  827                   Debug.logError(e, errMsg, module);
  828                   throw new RuntimeException(errMsg + e);
  829               }
  830               return modelForm;
  831           }
  832   
  833           public String getName(Map<String, Object> context) {
  834               return this.nameExdr.expandString(context);
  835           }
  836   
  837           public String getLocation(Map<String, Object> context) {
  838               return this.locationExdr.expandString(context);
  839           }
  840   
  841           public boolean shareScope(Map<String, Object> context) {
  842               String shareScopeString = this.shareScopeExdr.expandString(context);
  843               // defaults to false, so anything but true is false
  844               return "true".equals(shareScopeString);
  845           }
  846   
  847           public String rawString() {
  848               return "<include-form name=\"" + this.nameExdr.getOriginal() + "\" location=\"" + this.locationExdr.getOriginal() + "\" share-scope=\"" + this.shareScopeExdr.getOriginal() + "\"/>";
  849           }
  850       }
  851   
  852       public static class Tree extends ModelScreenWidget {
  853           protected FlexibleStringExpander nameExdr;
  854           protected FlexibleStringExpander locationExdr;
  855           protected FlexibleStringExpander shareScopeExdr;
  856   
  857           public Tree(ModelScreen modelScreen, Element treeElement) {
  858               super(modelScreen, treeElement);
  859   
  860               this.nameExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("name"));
  861               this.locationExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("location"));
  862               this.shareScopeExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("share-scope"));
  863           }
  864   
  865           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  866               boolean protectScope = !shareScope(context);
  867               if (protectScope) {
  868                   if (!(context instanceof MapStack)) {
  869                       context = MapStack.create(context);
  870                   }
  871                   ((MapStack) context).push();
  872               }
  873   
  874               String name = this.getName(context);
  875               String location = this.getLocation(context);
  876               ModelTree modelTree = null;
  877               try {
  878                   modelTree = TreeFactory.getTreeFromLocation(this.getLocation(context), this.getName(context), this.modelScreen.getDelegator(context), this.modelScreen.getDispatcher(context));
  879               } catch (IOException e) {
  880                   String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
  881                   Debug.logError(e, errMsg, module);
  882                   throw new RuntimeException(errMsg);
  883               } catch (SAXException e) {
  884                   String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
  885                   Debug.logError(e, errMsg, module);
  886                   throw new RuntimeException(errMsg);
  887               } catch (ParserConfigurationException e) {
  888                   String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
  889                   Debug.logError(e, errMsg, module);
  890                   throw new RuntimeException(errMsg);
  891               }
  892   
  893               // try finding the treeStringRenderer by name in the context in case one was prepared and put there
  894               TreeStringRenderer treeStringRenderer = (TreeStringRenderer) context.get("treeStringRenderer");
  895               // if there was no treeStringRenderer put in place, now try finding the request/response in the context and creating a new one
  896               if (treeStringRenderer == null) {
  897                   treeStringRenderer = new HtmlTreeRenderer();
  898                   /*
  899                   String renderClassStyle = modelTree.getRenderStyle();
  900                   if (UtilValidate.isNotEmpty(renderClassStyle) && renderClassStyle.equals("simple"))
  901                       treeStringRenderer = new HtmlTreeRenderer();
  902                   else
  903                       treeStringRenderer = new HtmlTreeExpandCollapseRenderer();
  904                   */
  905               }
  906               // still null, throw an error
  907               if (treeStringRenderer == null) {
  908                   throw new IllegalArgumentException("Could not find a treeStringRenderer in the context, and could not find HTTP request/response objects need to create one.");
  909               }
  910   
  911               StringBuffer renderBuffer = new StringBuffer();
  912               modelTree.renderTreeString(renderBuffer, context, treeStringRenderer);
  913               try {
  914                   writer.append(renderBuffer.toString());
  915               } catch (IOException e) {
  916                   String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
  917                   Debug.logError(e, errMsg, module);
  918                   throw new RuntimeException(errMsg);
  919               }
  920   
  921               if (protectScope) {
  922                   ((MapStack) context).pop();
  923               }
  924           }
  925   
  926           public String getName(Map<String, Object> context) {
  927               return this.nameExdr.expandString(context);
  928           }
  929   
  930           public String getLocation(Map<String, Object> context) {
  931               return this.locationExdr.expandString(context);
  932           }
  933   
  934           public boolean shareScope(Map<String, Object> context) {
  935               String shareScopeString = this.shareScopeExdr.expandString(context);
  936               // defaults to false, so anything but true is false
  937               return "true".equals(shareScopeString);
  938           }
  939   
  940           public String rawString() {
  941               return "<include-tree name=\"" + this.nameExdr.getOriginal() + "\" location=\"" + this.locationExdr.getOriginal() + "\" share-scope=\"" + this.shareScopeExdr.getOriginal() + "\"/>";
  942           }
  943       }
  944   
  945       public static class PlatformSpecific extends ModelScreenWidget {
  946           protected Map<String, ModelScreenWidget> subWidgets;
  947   
  948           public PlatformSpecific(ModelScreen modelScreen, Element platformSpecificElement) {
  949               super(modelScreen, platformSpecificElement);
  950               subWidgets = new HashMap<String, ModelScreenWidget>();
  951               List<? extends Element> childElements = UtilXml.childElementList(platformSpecificElement);
  952               if (childElements != null) {
  953                   for (Element childElement: childElements) {
  954                       if ("html".equals(childElement.getNodeName())) {
  955                           subWidgets.put("html", new HtmlWidget(modelScreen, childElement));
  956                       } else if ("xsl-fo".equals(childElement.getNodeName())) {
  957                           subWidgets.put("xsl-fo", new HtmlWidget(modelScreen, childElement));
  958                       } else if ("xml".equals(childElement.getNodeName())) {
  959                           subWidgets.put("xml", new HtmlWidget(modelScreen, childElement));
  960                       } else {
  961                           throw new IllegalArgumentException("Tag not supported under the platform-specific tag with name: " + childElement.getNodeName());
  962                       }
  963                   }
  964               }
  965           }
  966   
  967           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
  968               ModelScreenWidget subWidget = null;
  969               subWidget = (ModelScreenWidget)subWidgets.get(screenStringRenderer.getRendererName());
  970               if (subWidget == null) {
  971                   // This is here for backward compatibility
  972                   Debug.logWarning("In platform-dependent could not find template for " + screenStringRenderer.getRendererName() + ", using the one for html.", module);
  973                   subWidget = (ModelScreenWidget)subWidgets.get("html");
  974               }
  975               if (subWidget != null) {
  976                   subWidget.renderWidgetString(writer, context, screenStringRenderer);
  977               }
  978           }
  979   
  980           public String rawString() {
  981               Collection<ModelScreenWidget> subWidgetList = this.subWidgets.values();
  982               StringBuilder subWidgetsRawString = new StringBuilder("<platform-specific>");
  983               for (ModelScreenWidget subWidget: subWidgetList) {
  984                   subWidgetsRawString.append(subWidget.rawString());
  985               }
  986               return subWidgetsRawString.append("</platform-specific>").toString();
  987           }
  988       }
  989   
  990       public static class Content extends ModelScreenWidget {
  991   
  992           protected FlexibleStringExpander contentId;
  993           protected FlexibleStringExpander editRequest;
  994           protected FlexibleStringExpander editContainerStyle;
  995           protected FlexibleStringExpander enableEditName;
  996           protected boolean xmlEscape = false;
  997           protected FlexibleStringExpander dataResourceId;
  998           protected String width;
  999           protected String height;
 1000           protected String border;
 1001   
 1002           public Content(ModelScreen modelScreen, Element subContentElement) {
 1003               super(modelScreen, subContentElement);
 1004   
 1005               // put the text attribute first, then the pcdata under the element, if both are there of course
 1006               this.contentId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("content-id"));
 1007               this.dataResourceId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("dataresource-id"));
 1008               this.editRequest = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-request"));
 1009               this.editContainerStyle = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-container-style"));
 1010               this.enableEditName = FlexibleStringExpander.getInstance(subContentElement.getAttribute("enable-edit-name"));
 1011               this.xmlEscape = "true".equals(subContentElement.getAttribute("xml-escape"));
 1012               this.width = subContentElement.getAttribute("width");
 1013               if (UtilValidate.isEmpty(this.width)) this.width="60%";
 1014               this.height = subContentElement.getAttribute("height");
 1015               if (UtilValidate.isEmpty(this.height)) this.width="400px";
 1016               this.border = subContentElement.getAttribute("border");
 1017           }
 1018   
 1019           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
 1020               try {
 1021                   // pushing the contentId on the context as "contentId" is done
 1022                   // because many times there will be embedded "subcontent" elements
 1023                   // that use the syntax: <subcontent content-id="${contentId}"...
 1024                   // and this is a step to make sure that it is there.
 1025                   GenericDelegator delegator = (GenericDelegator) context.get("delegator");
 1026                   GenericValue content = null;
 1027                   String expandedDataResourceId = getDataResourceId(context);
 1028                   String expandedContentId = getContentId(context);
 1029                   if (!(context instanceof MapStack)) {
 1030                       context = MapStack.create(context);
 1031                   }
 1032   
 1033                   // This is an important step to make sure that the current contentId is in the context
 1034                   // as templates that contain "subcontent" elements will expect to find the master
 1035                   // contentId in the context as "contentId".
 1036                   ((MapStack) context).push();
 1037                   context.put("contentId", expandedContentId);
 1038   
 1039                   if (UtilValidate.isEmpty(expandedDataResourceId)) {
 1040                       if (UtilValidate.isNotEmpty(expandedContentId)) {
 1041                           content = delegator.findByPrimaryKeyCache("Content", UtilMisc.toMap("contentId", expandedContentId));
 1042                       } else {
 1043                           String errMsg = "contentId is empty.";
 1044                           Debug.logError(errMsg, module);
 1045                           return;
 1046                       }
 1047                       if (content != null) {
 1048                           expandedDataResourceId = content.getString("dataResourceId");
 1049                       } else {
 1050                           String errMsg = "Could not find content with contentId [" + expandedContentId + "] ";
 1051                           Debug.logError(errMsg, module);
 1052                           throw new RuntimeException(errMsg);
 1053                       }
 1054                   }
 1055   
 1056                   GenericValue dataResource = null;
 1057                   if (UtilValidate.isNotEmpty(expandedDataResourceId)) {
 1058                       dataResource = delegator.findByPrimaryKeyCache("DataResource", UtilMisc.toMap("dataResourceId", expandedDataResourceId));
 1059                       this.dataResourceId = FlexibleStringExpander.getInstance(expandedDataResourceId);
 1060                   }
 1061   
 1062                   String mimeTypeId = null;
 1063                   if (dataResource != null) {
 1064                       mimeTypeId = dataResource.getString("mimeTypeId");
 1065                   }
 1066   
 1067                   if (UtilValidate.isNotEmpty(mimeTypeId)
 1068                           && ((mimeTypeId.indexOf("application") >= 0) || (mimeTypeId.indexOf("image")) >= 0) ) {
 1069                       screenStringRenderer.renderContentFrame(writer, context, this);
 1070                   } else {
 1071                       screenStringRenderer.renderContentBegin(writer, context, this);
 1072                       screenStringRenderer.renderContentBody(writer, context, this);
 1073                       screenStringRenderer.renderContentEnd(writer, context, this);
 1074                   }
 1075                   ((MapStack) context).pop();
 1076               } catch (IOException e) {
 1077                   String errMsg = "Error rendering content with contentId [" + getContentId(context) + "]: " + e.toString();
 1078                   Debug.logError(e, errMsg, module);
 1079                   throw new RuntimeException(errMsg);
 1080               } catch (GenericEntityException e) {
 1081                   String errMsg = "Error obtaining content with contentId [" + getContentId(context) + "]: " + e.toString();
 1082                   Debug.logError(e, errMsg, module);
 1083                   throw new RuntimeException(errMsg);
 1084               }
 1085   
 1086           }
 1087   
 1088           public String getContentId(Map<String, Object> context) {
 1089               return this.contentId.expandString(context);
 1090           }
 1091   
 1092           public String getDataResourceId(Map<String, Object> context) {
 1093               return this.dataResourceId.expandString(context);
 1094           }
 1095   
 1096           public String getEditRequest(Map<String, Object> context) {
 1097               return this.editRequest.expandString(context);
 1098           }
 1099   
 1100           public String getEditContainerStyle(Map<String, Object> context) {
 1101               return this.editContainerStyle.expandString(context);
 1102           }
 1103   
 1104           public String getEnableEditName(Map<String, Object> context) {
 1105               return this.enableEditName.expandString(context);
 1106           }
 1107   
 1108           public boolean xmlEscape() {
 1109               return this.xmlEscape;
 1110           }
 1111   
 1112           public String rawString() {
 1113               // may want to expand this a bit more
 1114               return "<content content-id=\"" + this.contentId.getOriginal() + "\" xml-escape=\"" + this.xmlEscape + "\"/>";
 1115           }
 1116   
 1117           public String getWidth() {
 1118               return this.width;
 1119           }
 1120   
 1121           public String getHeight() {
 1122               return this.height;
 1123           }
 1124   
 1125           public String getBorder() {
 1126               return this.border;
 1127           }
 1128       }
 1129   
 1130       public static class SubContent extends ModelScreenWidget {
 1131           protected FlexibleStringExpander contentId;
 1132           protected FlexibleStringExpander mapKey;
 1133           protected FlexibleStringExpander editRequest;
 1134           protected FlexibleStringExpander editContainerStyle;
 1135           protected FlexibleStringExpander enableEditName;
 1136           protected boolean xmlEscape = false;
 1137   
 1138           public SubContent(ModelScreen modelScreen, Element subContentElement) {
 1139               super(modelScreen, subContentElement);
 1140   
 1141               // put the text attribute first, then the pcdata under the element, if both are there of course
 1142               this.contentId = FlexibleStringExpander.getInstance(UtilFormatOut.checkNull(subContentElement.getAttribute("content-id")));
 1143               this.mapKey = FlexibleStringExpander.getInstance(UtilFormatOut.checkNull(subContentElement.getAttribute("map-key")));
 1144               if (this.mapKey.isEmpty()) {
 1145                   this.mapKey = FlexibleStringExpander.getInstance(UtilFormatOut.checkNull(subContentElement.getAttribute("assoc-name")));
 1146               }
 1147               this.editRequest = FlexibleStringExpander.getInstance(UtilFormatOut.checkNull(subContentElement.getAttribute("edit-request")));
 1148               this.editContainerStyle = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-container-style"));
 1149               this.enableEditName = FlexibleStringExpander.getInstance(subContentElement.getAttribute("enable-edit-name"));
 1150               this.xmlEscape = "true".equals(subContentElement.getAttribute("xml-escape"));
 1151           }
 1152   
 1153           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
 1154               try {
 1155                   screenStringRenderer.renderSubContentBegin(writer, context, this);
 1156                   screenStringRenderer.renderSubContentBody(writer, context, this);
 1157                   screenStringRenderer.renderSubContentEnd(writer, context, this);
 1158               } catch (IOException e) {
 1159                   String errMsg = "Error rendering subContent with contentId [" + getContentId(context) + "]: " + e.toString();
 1160                   Debug.logError(e, errMsg, module);
 1161                   throw new RuntimeException(errMsg);
 1162               }
 1163           }
 1164   
 1165           public String getContentId(Map<String, Object> context) {
 1166               return this.contentId.expandString(context);
 1167           }
 1168   
 1169           public String getMapKey(Map<String, Object> context) {
 1170               return this.mapKey.expandString(context);
 1171           }
 1172   
 1173           public String getEditRequest(Map<String, Object> context) {
 1174               return this.editRequest.expandString(context);
 1175           }
 1176   
 1177           public String getEditContainerStyle(Map<String, Object> context) {
 1178               return this.editContainerStyle.expandString(context);
 1179           }
 1180   
 1181           public String getEnableEditName(Map<String, Object> context) {
 1182               return this.enableEditName.expandString(context);
 1183           }
 1184   
 1185           public boolean xmlEscape() {
 1186               return this.xmlEscape;
 1187           }
 1188   
 1189           public String rawString() {
 1190               // may want to expand this a bit more
 1191               return "<sub-content content-id=\"" + this.contentId.getOriginal() + "\" map-key=\"" + this.mapKey.getOriginal() + "\" xml-escape=\"" + this.xmlEscape + "\"/>";
 1192           }
 1193       }
 1194   
 1195       public static class Menu extends ModelScreenWidget {
 1196           protected FlexibleStringExpander nameExdr;
 1197           protected FlexibleStringExpander locationExdr;
 1198   
 1199           public Menu(ModelScreen modelScreen, Element menuElement) {
 1200               super(modelScreen, menuElement);
 1201   
 1202               this.nameExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("name"));
 1203               this.locationExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("location"));
 1204           }
 1205   
 1206           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws IOException {
 1207               // try finding the menuStringRenderer by name in the context in case one was prepared and put there
 1208               MenuStringRenderer menuStringRenderer = (MenuStringRenderer) context.get("menuStringRenderer");
 1209               // if there was no menuStringRenderer put in place, now try finding the request/response in the context and creating a new one
 1210               if (menuStringRenderer == null) {
 1211                   // try finding the menuStringRenderer by name in the context in
 1212                   // case one was prepared and put there
 1213                   menuStringRenderer = (MenuStringRenderer) context.get("menuStringRenderer");
 1214                   // if there was no menuStringRenderer put in place, now try
 1215                   // finding the request/response in the context and creating a
 1216                   // new one
 1217                   if (menuStringRenderer == null) {
 1218                       HttpServletRequest request = (HttpServletRequest) context.get("request");
 1219                       HttpServletResponse response = (HttpServletResponse) context.get("response");
 1220                       if (request != null && response != null) {
 1221                           menuStringRenderer = new HtmlMenuRenderer(request, response);
 1222                       }
 1223                   }
 1224                   // still null, throw an error
 1225                   if (menuStringRenderer == null) {
 1226                       throw new IllegalArgumentException("Could not find a menuStringRenderer in the context, and could not find HTTP request/response objects need to create one.");
 1227                   }
 1228               }
 1229   
 1230               ModelMenu modelMenu = getModelMenu(context);
 1231               modelMenu.renderMenuString(writer, context, menuStringRenderer);
 1232           }
 1233   
 1234           public ModelMenu getModelMenu(Map<String, Object> context) {
 1235               String name = this.getName(context);
 1236               String location = this.getLocation(context);
 1237               ModelMenu modelMenu = null;
 1238               try {
 1239                   modelMenu = MenuFactory.getMenuFromLocation(location, name, this.modelScreen.getDelegator(context), this.modelScreen.getDispatcher(context));
 1240               } catch (Exception e) {
 1241                   String errMsg = "Error rendering included menu named [" + name + "] at location [" + location + "]: ";
 1242                   Debug.logError(e, errMsg, module);
 1243                   throw new RuntimeException(errMsg + e);
 1244               }
 1245               return modelMenu;
 1246           }
 1247   
 1248           public String getName(Map<String, Object> context) {
 1249               return this.nameExdr.expandString(context);
 1250           }
 1251   
 1252           public String getLocation(Map<String, Object> context) {
 1253               return this.locationExdr.expandString(context);
 1254           }
 1255   
 1256           public String rawString() {
 1257               return "<include-menu name=\"" + this.nameExdr.getOriginal() + "\" location=\"" + this.locationExdr.getOriginal() + "\"/>";
 1258           }
 1259       }
 1260   
 1261       public static class Link extends ModelScreenWidget {
 1262           protected FlexibleStringExpander textExdr;
 1263           protected FlexibleStringExpander idExdr;
 1264           protected FlexibleStringExpander styleExdr;
 1265           protected FlexibleStringExpander targetExdr;
 1266           protected FlexibleStringExpander targetWindowExdr;
 1267           protected FlexibleStringExpander prefixExdr;
 1268           protected FlexibleStringExpander nameExdr;
 1269           protected Image image;
 1270           protected String urlMode = "intra-app";
 1271           protected boolean fullPath = false;
 1272           protected boolean secure = false;
 1273           protected boolean encode = false;
 1274           protected String linkType;
 1275           protected List<WidgetWorker.Parameter> parameterList = FastList.newInstance();
 1276   
 1277   
 1278           public Link(ModelScreen modelScreen, Element linkElement) {
 1279               super(modelScreen, linkElement);
 1280   
 1281               setText(linkElement.getAttribute("text"));
 1282               setId(linkElement.getAttribute("id"));
 1283               setStyle(linkElement.getAttribute("style"));
 1284               setName(linkElement.getAttribute("name"));
 1285               setTarget(linkElement.getAttribute("target"));
 1286               setTargetWindow(linkElement.getAttribute("target-window"));
 1287               setPrefix(linkElement.getAttribute("prefix"));
 1288               setUrlMode(linkElement.getAttribute("url-mode"));
 1289               setFullPath(linkElement.getAttribute("full-path"));
 1290               setSecure(linkElement.getAttribute("secure"));
 1291               setEncode(linkElement.getAttribute("encode"));
 1292               Element imageElement = UtilXml.firstChildElement(linkElement, "image");
 1293               if (imageElement != null) {
 1294                   this.image = new Image(modelScreen, imageElement);
 1295               }
 1296   
 1297               this.linkType = linkElement.getAttribute("link-type");
 1298               List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
 1299               for (Element parameterElement: parameterElementList) {
 1300                   this.parameterList.add(new WidgetWorker.Parameter(parameterElement));
 1301               }
 1302           }
 1303   
 1304           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
 1305               try {
 1306                   screenStringRenderer.renderLink(writer, context, this);
 1307               } catch (IOException e) {
 1308                   String errMsg = "Error rendering link with id [" + getId(context) + "]: " + e.toString();
 1309                   Debug.logError(e, errMsg, module);
 1310                   throw new RuntimeException(errMsg);
 1311               }
 1312           }
 1313   
 1314           public String getText(Map<String, Object> context) {
 1315               String text = this.textExdr.expandString(context);
 1316               StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
 1317               if (simpleEncoder != null) {
 1318                   text = simpleEncoder.encode(text);
 1319               }
 1320               return text;
 1321           }
 1322   
 1323           public String getId(Map<String, Object> context) {
 1324               return this.idExdr.expandString(context);
 1325           }
 1326   
 1327           public String getStyle(Map<String, Object> context) {
 1328               return this.styleExdr.expandString(context);
 1329           }
 1330   
 1331           public String getTarget(Map<String, Object> context) {
 1332               Map<String, Object> expanderContext = context;
 1333               StringUtil.SimpleEncoder simpleEncoder = context == null ? null : (StringUtil.SimpleEncoder) context.get("simpleEncoder");
 1334               if (simpleEncoder != null) {
 1335                   expanderContext = StringUtil.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
 1336               }
 1337               return this.targetExdr.expandString(expanderContext);
 1338           }
 1339   
 1340           public String getName(Map<String, Object> context) {
 1341               return this.nameExdr.expandString(context);
 1342           }
 1343   
 1344           public String getTargetWindow(Map<String, Object> context) {
 1345               return this.targetWindowExdr.expandString(context);
 1346           }
 1347   
 1348           public String getUrlMode() {
 1349               return this.urlMode;
 1350           }
 1351   
 1352           public String getPrefix(Map<String, Object> context) {
 1353               return this.prefixExdr.expandString(context);
 1354           }
 1355   
 1356           public boolean getFullPath() {
 1357               return this.fullPath;
 1358           }
 1359   
 1360           public boolean getSecure() {
 1361               return this.secure;
 1362           }
 1363   
 1364           public boolean getEncode() {
 1365               return this.encode;
 1366           }
 1367   
 1368           public Image getImage() {
 1369               return this.image;
 1370           }
 1371   
 1372           public String getLinkType() {
 1373               return this.linkType;
 1374           }
 1375   
 1376           public List<WidgetWorker.Parameter> getParameterList() {
 1377               return this.parameterList;
 1378           }
 1379   
 1380           public void setText(String val) {
 1381               String textAttr = UtilFormatOut.checkNull(val);
 1382               this.textExdr = FlexibleStringExpander.getInstance(textAttr);
 1383           }
 1384           public void setId(String val) {
 1385               this.idExdr = FlexibleStringExpander.getInstance(val);
 1386           }
 1387           public void setStyle(String val) {
 1388               this.styleExdr = FlexibleStringExpander.getInstance(val);
 1389           }
 1390           public void setTarget(String val) {
 1391               this.targetExdr = FlexibleStringExpander.getInstance(val);
 1392           }
 1393           public void setName(String val) {
 1394               this.nameExdr = FlexibleStringExpander.getInstance(val);
 1395           }
 1396           public void setTargetWindow(String val) {
 1397               this.targetWindowExdr = FlexibleStringExpander.getInstance(val);
 1398           }
 1399           public void setPrefix(String val) {
 1400               this.prefixExdr = FlexibleStringExpander.getInstance(val);
 1401           }
 1402           public void setUrlMode(String val) {
 1403               if (UtilValidate.isNotEmpty(val))
 1404                   this.urlMode = val;
 1405           }
 1406           public void setFullPath(String val) {
 1407               String sFullPath = val;
 1408               if (sFullPath != null && sFullPath.equalsIgnoreCase("true"))
 1409                   this.fullPath = true;
 1410               else
 1411                   this.fullPath = false;
 1412           }
 1413   
 1414           public void setSecure(String val) {
 1415               String sSecure = val;
 1416               if (sSecure != null && sSecure.equalsIgnoreCase("true"))
 1417                   this.secure = true;
 1418               else
 1419                   this.secure = false;
 1420           }
 1421   
 1422           public void setEncode(String val) {
 1423               String sEncode = val;
 1424               if (sEncode != null && sEncode.equalsIgnoreCase("true"))
 1425                   this.encode = true;
 1426               else
 1427                   this.encode = false;
 1428           }
 1429           public void setImage(Image img) {
 1430               this.image = img;
 1431           }
 1432   
 1433           public String rawString() {
 1434               // may want to add more to this
 1435               return "<link id=\"" + this.idExdr.getOriginal() + "\" style=\"" + this.styleExdr.getOriginal() + "\" text=\"" + this.textExdr.getOriginal() + "\" target=\"" + this.targetExdr.getOriginal() + "\" name=\"" + this.nameExdr.getOriginal() + "\" url-mode=\"" + this.urlMode + "\"/>";
 1436           }
 1437       }
 1438   
 1439       public static class Image extends ModelScreenWidget {
 1440           protected FlexibleStringExpander srcExdr;
 1441           protected FlexibleStringExpander idExdr;
 1442           protected FlexibleStringExpander styleExdr;
 1443           protected FlexibleStringExpander widthExdr;
 1444           protected FlexibleStringExpander heightExdr;
 1445           protected FlexibleStringExpander borderExdr;
 1446           protected FlexibleStringExpander alt;
 1447           protected String urlMode = "content";
 1448   
 1449           public Image(ModelScreen modelScreen, Element imageElement) {
 1450               super(modelScreen, imageElement);
 1451   
 1452               setSrc(imageElement.getAttribute("src"));
 1453               setId(imageElement.getAttribute("id"));
 1454               setStyle(imageElement.getAttribute("style"));
 1455               setWidth(imageElement.getAttribute("width"));
 1456               setHeight(imageElement.getAttribute("height"));
 1457               setBorder(imageElement.getAttribute("border"));
 1458               setAlt(imageElement.getAttribute("alt"));
 1459               setUrlMode(UtilFormatOut.checkEmpty(imageElement.getAttribute("url-mode"), "content"));
 1460           }
 1461   
 1462           public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
 1463               try {
 1464                   screenStringRenderer.renderImage(writer, context, this);
 1465               } catch (IOException e) {
 1466                   String errMsg = "Error rendering image with id [" + getId(context) + "]: " + e.toString();
 1467                   Debug.logError(e, errMsg, module);
 1468                   throw new RuntimeException(errMsg);
 1469               }
 1470           }
 1471   
 1472           public String getSrc(Map<String, Object> context) {
 1473               return this.srcExdr.expandString(context);
 1474           }
 1475   
 1476           public String getId(Map<String, Object> context) {
 1477               return this.idExdr.expandString(context);
 1478           }
 1479   
 1480           public String getStyle(Map<String, Object> context) {
 1481               return this.styleExdr.expandString(context);
 1482           }
 1483   
 1484           public String getWidth(Map<String, Object> context) {
 1485               return this.widthExdr.expandString(context);
 1486           }
 1487   
 1488           public String getHeight(Map<String, Object> context) {
 1489               return this.heightExdr.expandString(context);
 1490           }
 1491   
 1492           public String getBorder(Map<String, Object> context) {
 1493               return this.borderExdr.expandString(context);
 1494           }
 1495   
 1496           public String getAlt(Map<String, Object> context) {
 1497               return this.alt.expandString(context);
 1498           }
 1499   
 1500           public String getUrlMode() {
 1501               return this.urlMode;
 1502           }
 1503   
 1504           public void setSrc(String val) {
 1505               String textAttr = UtilFormatOut.checkNull(val);
 1506               this.srcExdr = FlexibleStringExpander.getInstance(textAttr);
 1507           }
 1508           public void setId(String val) {
 1509               this.idExdr = FlexibleStringExpander.getInstance(val);
 1510           }
 1511           public void setStyle(String val) {
 1512               this.styleExdr = FlexibleStringExpander.getInstance(val);
 1513           }
 1514           public void setWidth(String val) {
 1515               this.widthExdr = FlexibleStringExpander.getInstance(val);
 1516           }
 1517           public void setHeight(String val) {
 1518               this.heightExdr = FlexibleStringExpander.getInstance(val);
 1519           }
 1520           public void setBorder(String val) {
 1521               this.borderExdr = FlexibleStringExpander.getInstance(val);
 1522           }
 1523           public void setAlt(String val) {
 1524               String altAttr = UtilFormatOut.checkNull(val);
 1525               this.alt = FlexibleStringExpander.getInstance(altAttr);
 1526           }
 1527   
 1528           public void setUrlMode(String val) {
 1529               if (UtilValidate.isEmpty(val)) {
 1530                   this.urlMode = "content";
 1531               } else {
 1532                   this.urlMode = val;
 1533               }
 1534           }
 1535   
 1536           public String rawString() {
 1537               // may want to add more to this
 1538               return "<image id=\"" + this.idExdr.getOriginal() + "\" style=\"" + this.styleExdr.getOriginal() + "\" src=\"" + this.srcExdr.getOriginal() + "\" url-mode=\"" + this.urlMode + "\"/>";
 1539           }
 1540       }
 1541   }
 1542   
 1543   
 1544   
 1545   
 1546   
 1547   
 1548   
 1549   
 1550   
 1551   
 1552   
 1553   
 1554   
 1555   

Save This Page
Home » apache-ofbiz-09.04 » org.ofbiz.widget.screen » [javadoc | source]