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.StringWriter;
   23   import java.io.Writer;
   24   import java.util.List;
   25   import java.util.Locale;
   26   import java.util.Map;
   27   import java.util.Set;
   28   
   29   import javax.servlet.ServletContext;
   30   import javax.servlet.http.HttpServletRequest;
   31   import javax.servlet.http.HttpServletResponse;
   32   import javax.servlet.http.HttpSession;
   33   import javax.xml.parsers.ParserConfigurationException;
   34   
   35   import javolution.util.FastList;
   36   import javolution.util.FastMap;
   37   
   38   import org.ofbiz.base.util.GeneralException;
   39   import org.ofbiz.base.util.UtilDateTime;
   40   import org.ofbiz.base.util.UtilFormatOut;
   41   import org.ofbiz.base.util.UtilGenerics;
   42   import org.ofbiz.base.util.UtilHttp;
   43   import org.ofbiz.base.util.UtilMisc;
   44   import org.ofbiz.base.util.UtilValidate;
   45   import org.ofbiz.base.util.collections.MapStack;
   46   import org.ofbiz.entity.GenericDelegator;
   47   import org.ofbiz.entity.GenericEntity;
   48   import org.ofbiz.entity.GenericValue;
   49   import org.ofbiz.security.Security;
   50   import org.ofbiz.service.DispatchContext;
   51   import org.ofbiz.service.LocalDispatcher;
   52   import org.ofbiz.webapp.control.LoginWorker;
   53   import org.ofbiz.widget.cache.GenericWidgetOutput;
   54   import org.ofbiz.widget.cache.ScreenCache;
   55   import org.ofbiz.widget.cache.WidgetContextCacheKey;
   56   import org.xml.sax.SAXException;
   57   
   58   import freemarker.ext.beans.BeansWrapper;
   59   import freemarker.ext.jsp.TaglibFactory;
   60   import freemarker.ext.servlet.HttpRequestHashModel;
   61   import freemarker.ext.servlet.HttpSessionHashModel;
   62   
   63   /**
   64    * Widget Library - Screen model class
   65    */
   66   public class ScreenRenderer {
   67   
   68       public static final String module = ScreenRenderer.class.getName();
   69   
   70       protected Appendable writer;
   71       protected MapStack<String> context;
   72       protected ScreenStringRenderer screenStringRenderer;
   73   
   74       public ScreenRenderer(Appendable writer, MapStack<String> context, ScreenStringRenderer screenStringRenderer) {
   75           this.writer = writer;
   76           this.context = context;
   77           if (this.context == null) this.context = MapStack.create();
   78           this.screenStringRenderer = screenStringRenderer;
   79       }
   80   
   81       /**
   82        * Renders the named screen using the render environment configured when this ScreenRenderer was created.
   83        *
   84        * @param combinedName A combination of the resource name/location for the screen XML file and the name of the screen within that file, separated by a pound sign ("#"). This is the same format that is used in the view-map elements on the controller.xml file.
   85        * @throws IOException
   86        * @throws SAXException
   87        * @throws ParserConfigurationException
   88        */
   89       public String render(String combinedName) throws GeneralException, IOException, SAXException, ParserConfigurationException {
   90           String resourceName = ScreenFactory.getResourceNameFromCombined(combinedName);
   91           String screenName = ScreenFactory.getScreenNameFromCombined(combinedName);
   92           this.render(resourceName, screenName);
   93           return "";
   94       }
   95   
   96       /**
   97        * Renders the named screen using the render environment configured when this ScreenRenderer was created.
   98        *
   99        * @param resourceName The name/location of the resource to use, can use "component://[component-name]/" and "ofbiz://" and other special OFBiz style URLs
  100        * @param screenName The name of the screen within the XML file specified by the resourceName.
  101        * @throws IOException
  102        * @throws SAXException
  103        * @throws ParserConfigurationException
  104        */
  105       public String render(String resourceName, String screenName) throws GeneralException, IOException, SAXException, ParserConfigurationException {
  106           ModelScreen modelScreen = ScreenFactory.getScreenFromLocation(resourceName, screenName);
  107           if (modelScreen.useCache) {
  108               // if in the screen definition use-cache is set to true
  109               // then try to get an already built screen output from the cache:
  110               // 1) if we find it then we get it and attach it to the passed in writer
  111               // 2) if we can't find one, we create a new StringWriter,
  112               //    and pass it to the renderScreenString;
  113               //    then we wrap its content and put it in the cache;
  114               //    and we attach it to the passed in writer
  115               WidgetContextCacheKey wcck = new WidgetContextCacheKey(context);
  116               String screenCombinedName = resourceName + ":" + screenName;
  117               ScreenCache screenCache = new ScreenCache();
  118               GenericWidgetOutput gwo = screenCache.get(screenCombinedName, wcck);
  119               if (gwo == null) {
  120                   Writer sw = new StringWriter();
  121                   screenStringRenderer.renderScreenBegin(writer, context);
  122                   modelScreen.renderScreenString(sw, context, screenStringRenderer);
  123                   screenStringRenderer.renderScreenEnd(writer, context);
  124                   gwo = new GenericWidgetOutput(sw.toString());
  125                   screenCache.put(screenCombinedName, wcck, gwo);
  126                   writer.append(gwo.toString());
  127               } else {
  128                   writer.append(gwo.toString());
  129               }
  130           } else {
  131               screenStringRenderer.renderScreenBegin(writer, context);
  132               modelScreen.renderScreenString(writer, context, screenStringRenderer);
  133               screenStringRenderer.renderScreenEnd(writer, context);
  134           }
  135           return "";
  136       }
  137   
  138       public ScreenStringRenderer getScreenStringRenderer() {
  139           return this.screenStringRenderer;
  140       }
  141   
  142       public void populateBasicContext(Map<String, Object> parameters, GenericDelegator delegator, LocalDispatcher dispatcher, Security security, Locale locale, GenericValue userLogin) {
  143           populateBasicContext(context, this, parameters, delegator, dispatcher, security, locale, userLogin);
  144       }
  145   
  146       public static void populateBasicContext(MapStack<String> context, ScreenRenderer screens, Map<String, Object> parameters, GenericDelegator delegator, LocalDispatcher dispatcher, Security security, Locale locale, GenericValue userLogin) {
  147           // ========== setup values that should always be in a screen context
  148           // include an object to more easily render screens
  149           context.put("screens", screens);
  150   
  151           // make a reference for high level variables, a global context
  152           context.put("globalContext", context.standAloneStack());
  153   
  154           // make sure the "nullField" object is in there for entity ops; note this is nullField and not null because as null causes problems in FreeMarker and such...
  155           context.put("nullField", GenericEntity.NULL_FIELD);
  156   
  157           context.put("parameters", parameters);
  158           context.put("delegator", delegator);
  159           context.put("dispatcher", dispatcher);
  160           context.put("security", security);
  161           context.put("locale", locale);
  162           context.put("userLogin", userLogin);
  163           context.put("nowTimestamp", UtilDateTime.nowTimestamp());
  164       }
  165   
  166       /**
  167        * This method populates the context for this ScreenRenderer based on the HTTP Request and Response objects and the ServletContext.
  168        * It leverages various conventions used in other places, namely the ControlServlet and so on, of OFBiz to get the different resources needed.
  169        *
  170        * @param request
  171        * @param response
  172        * @param servletContext
  173        */
  174       public void populateContextForRequest(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
  175           populateContextForRequest(context, this, request, response, servletContext);
  176       }
  177   
  178       public static void populateContextForRequest(MapStack<String> context, ScreenRenderer screens, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
  179           HttpSession session = request.getSession();
  180   
  181           // attribute names to skip for session and application attributes; these are all handled as special cases, duplicating results and causing undesired messages
  182           Set<String> attrNamesToSkip = UtilMisc.toSet("delegator", "dispatcher", "security", "webSiteId");
  183           Map<String, Object> parameterMap = UtilHttp.getCombinedMap(request, attrNamesToSkip);
  184   
  185           GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
  186   
  187           populateBasicContext(context, screens, parameterMap, (GenericDelegator) request.getAttribute("delegator"),
  188                   (LocalDispatcher) request.getAttribute("dispatcher"), (Security) request.getAttribute("security"),
  189                   UtilHttp.getLocale(request), userLogin);
  190   
  191           context.put("autoUserLogin", session.getAttribute("autoUserLogin"));
  192           context.put("person", session.getAttribute("person"));
  193           context.put("partyGroup", session.getAttribute("partyGroup"));
  194   
  195           // some things also seem to require this, so here it is:
  196           request.setAttribute("userLogin", userLogin);
  197   
  198           // set up the user's time zone
  199           context.put("timeZone", UtilHttp.getTimeZone(request));
  200   
  201           // ========== setup values that are specific to OFBiz webapps
  202   
  203           context.put("request", request);
  204           context.put("response", response);
  205           context.put("session", session);
  206           context.put("application", servletContext);
  207           if (servletContext != null) {
  208               String rootDir = (String) context.get("rootDir");
  209               String webSiteId = (String) context.get("webSiteId");
  210               String https = (String) context.get("https");
  211               if (UtilValidate.isEmpty(rootDir)) {
  212                   rootDir = servletContext.getRealPath("/");
  213                   context.put("rootDir", rootDir);
  214               }
  215               if (UtilValidate.isEmpty(webSiteId)) {
  216                   webSiteId = (String) servletContext.getAttribute("webSiteId");
  217                   context.put("webSiteId", webSiteId);
  218               }
  219               if (UtilValidate.isEmpty(https)) {
  220                   https = (String) servletContext.getAttribute("https");
  221                   context.put("https", https);
  222               }
  223           }
  224           context.put("javaScriptEnabled", Boolean.valueOf(UtilHttp.isJavaScriptEnabled(request)));
  225   
  226           // these ones are FreeMarker specific and will only work in FTL templates, mainly here for backward compatibility
  227           BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
  228           context.put("sessionAttributes", new HttpSessionHashModel(session, wrapper));
  229           context.put("requestAttributes", new HttpRequestHashModel(request, wrapper));
  230           TaglibFactory JspTaglibs = new TaglibFactory(servletContext);
  231           context.put("JspTaglibs", JspTaglibs);
  232           context.put("requestParameters",  UtilHttp.getParameterMap(request));
  233   
  234           // this is a dummy object to stand-in for the JPublish page object for backward compatibility
  235           context.put("page", FastMap.newInstance());
  236   
  237           // some information from/about the ControlServlet environment
  238           context.put("controlPath", request.getAttribute("_CONTROL_PATH_"));
  239           context.put("contextRoot", request.getAttribute("_CONTEXT_ROOT_"));
  240           context.put("serverRoot", request.getAttribute("_SERVER_ROOT_URL_"));
  241           context.put("checkLoginUrl", LoginWorker.makeLoginUrl(request));
  242           String externalLoginKey = LoginWorker.getExternalLoginKey(request);
  243           String externalKeyParam = externalLoginKey == null ? "" : "&amp;externalLoginKey=" + externalLoginKey;
  244           context.put("externalLoginKey", externalLoginKey);
  245           context.put("externalKeyParam", externalKeyParam);
  246   
  247           // setup message lists
  248           List<String> eventMessageList = UtilGenerics.toList(request.getAttribute("eventMessageList"));
  249           if (eventMessageList == null) eventMessageList = FastList.newInstance();
  250           List<String> errorMessageList = UtilGenerics.toList(request.getAttribute("errorMessageList"));
  251           if (errorMessageList == null) errorMessageList = FastList.newInstance();
  252   
  253           if (request.getAttribute("_EVENT_MESSAGE_") != null) {
  254               eventMessageList.add(UtilFormatOut.replaceString((String) request.getAttribute("_EVENT_MESSAGE_"), "\n", "<br/>"));
  255               request.removeAttribute("_EVENT_MESSAGE_");
  256           }
  257           List<String> msgList = UtilGenerics.toList(request.getAttribute("_EVENT_MESSAGE_LIST_"));
  258           if (msgList != null) {
  259               eventMessageList.addAll(msgList);
  260               request.removeAttribute("_EVENT_MESSAGE_LIST_");
  261           }
  262           if (request.getAttribute("_ERROR_MESSAGE_") != null) {
  263               errorMessageList.add(UtilFormatOut.replaceString((String) request.getAttribute("_ERROR_MESSAGE_"), "\n", "<br/>"));
  264               request.removeAttribute("_ERROR_MESSAGE_");
  265           }
  266           if (session.getAttribute("_ERROR_MESSAGE_") != null) {
  267               errorMessageList.add(UtilFormatOut.replaceString((String) session.getAttribute("_ERROR_MESSAGE_"), "\n", "<br/>"));
  268               session.removeAttribute("_ERROR_MESSAGE_");
  269           }
  270           msgList = UtilGenerics.toList(request.getAttribute("_ERROR_MESSAGE_LIST_"));
  271           if (msgList != null) {
  272               errorMessageList.addAll(msgList);
  273               request.removeAttribute("_ERROR_MESSAGE_LIST_");
  274           }
  275           context.put("eventMessageList", eventMessageList);
  276           context.put("errorMessageList", errorMessageList);
  277   
  278           if (request.getAttribute("serviceValidationException") != null) {
  279               context.put("serviceValidationException", request.getAttribute("serviceValidationException"));
  280               request.removeAttribute("serviceValidationException");
  281           }
  282   
  283           // if there was an error message, this is an error
  284           context.put("isError", errorMessageList.size() > 0 ? Boolean.TRUE : Boolean.FALSE);
  285           // if a parameter was passed saying this is an error, it is an error
  286           if ("true".equals(parameterMap.get("isError"))) {
  287               context.put("isError", Boolean.TRUE);
  288           }
  289   
  290           // to preserve these values, push the MapStack
  291           context.push();
  292       }
  293   
  294       public Map<String, Object> getContext() {
  295           return context;
  296       }
  297   
  298       public void populateContextForService(DispatchContext dctx, Map<String, Object> serviceContext) {
  299           this.populateBasicContext(serviceContext, dctx.getDelegator(), dctx.getDispatcher(), dctx.getSecurity(),
  300                   (Locale) serviceContext.get("locale"), (GenericValue) serviceContext.get("userLogin"));
  301       }
  302   }

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