예제 #1
0
 NodeListModel filterByName(String name) throws TemplateModelException {
   NodeListModel result = new NodeListModel(contextNode);
   int size = size();
   if (size == 0) {
     return result;
   }
   Environment env = Environment.getCurrentEnvironment();
   for (int i = 0; i < size; i++) {
     NodeModel nm = (NodeModel) get(i);
     if (nm instanceof ElementModel) {
       if (((ElementModel) nm).matchesName(name, env)) {
         result.add(nm);
       }
     }
   }
   return result;
 }
  @SuppressWarnings("unchecked")
  public Writer getWriter(final Writer out, Map args) {
    final StringBuilder buf = new StringBuilder();
    final Environment env = Environment.getCurrentEnvironment();
    final Map<String, Object> templateCtx = FreeMarkerWorker.getWrappedObject("context", env);
    // FreeMarkerWorker.convertContext(templateCtx);
    final Map<String, Object> savedValues = FreeMarkerWorker.saveValues(templateCtx, saveKeyNames);
    FreeMarkerWorker.overrideWithArgs(templateCtx, args);
    final Delegator delegator = FreeMarkerWorker.getWrappedObject("delegator", env);
    /*
            final String editTemplate = FreeMarkerWorker.getArg(args, "editTemplate", ctx);
            final String wrapTemplateId = FreeMarkerWorker.getArg(args, "wrapTemplateId", ctx);
            //final String mapKey = FreeMarkerWorker.getArg(args, "mapKey", ctx);
            final String templateContentId = FreeMarkerWorker.getArg(args, "templateContentId", ctx);
            final String subDataResourceTypeId = FreeMarkerWorker.getArg(args, "subDataResourceTypeId", ctx);
            final String contentId = FreeMarkerWorker.getArg(args, "contentId", ctx);
            final String subContentId = FreeMarkerWorker.getArg(args, "subContentId", ctx);
            final String rootDir = FreeMarkerWorker.getArg(args, "rootDir", ctx);
            final String webSiteId = FreeMarkerWorker.getArg(args, "webSiteId", ctx);
            final String https = FreeMarkerWorker.getArg(args, "https", ctx);
            final String viewSize = FreeMarkerWorker.getArg(args, "viewSize", ctx);
            final String viewIndex = FreeMarkerWorker.getArg(args, "viewIndex", ctx);
            final String listSize = FreeMarkerWorker.getArg(args, "listSize", ctx);
            final String highIndex = FreeMarkerWorker.getArg(args, "highIndex", ctx);
            final String lowIndex = FreeMarkerWorker.getArg(args, "lowIndex", ctx);
            final String queryString = FreeMarkerWorker.getArg(args, "queryString", ctx);
            final Locale locale = FreeMarkerWorker.getWrappedObject("locale", env);
            final String mimeTypeId = FreeMarkerWorker.getArg(args, "mimeTypeId", ctx);
    */
    final LocalDispatcher dispatcher = FreeMarkerWorker.getWrappedObject("dispatcher", env);
    // final GenericValue userLogin = FreeMarkerWorker.getWrappedObject("userLogin", env);
    GenericValue view = FreeMarkerWorker.getWrappedObject("subContentDataResourceView", env);
    final Integer indent =
        (templateCtx.get("indent") == null)
            ? Integer.valueOf(0)
            : (Integer) templateCtx.get("indent");

    String contentId = (String) templateCtx.get("contentId");
    String subContentId = (String) templateCtx.get("subContentId");
    if (view == null) {
      String thisContentId = subContentId;
      if (UtilValidate.isEmpty(thisContentId)) {
        thisContentId = contentId;
      }
      if (UtilValidate.isNotEmpty(thisContentId)) {
        try {
          view = delegator.findByPrimaryKey("Content", UtilMisc.toMap("contentId", thisContentId));
        } catch (GenericEntityException e) {
          Debug.logError(e, "Error getting sub-content", module);
          throw new RuntimeException(e.getMessage());
        }
      }
    }

    final GenericValue subContentDataResourceView = view;
    final Map<String, Object> traverseContext = FastMap.newInstance();
    traverseContext.put("delegator", delegator);
    Map<String, Object> whenMap = FastMap.newInstance();
    whenMap.put("followWhen", templateCtx.get("followWhen"));
    whenMap.put("pickWhen", templateCtx.get("pickWhen"));
    whenMap.put("returnBeforePickWhen", templateCtx.get("returnBeforePickWhen"));
    whenMap.put("returnAfterPickWhen", templateCtx.get("returnAfterPickWhen"));
    traverseContext.put("whenMap", whenMap);
    String fromDateStr = (String) templateCtx.get("fromDateStr");
    String thruDateStr = (String) templateCtx.get("thruDateStr");
    Timestamp fromDate = null;
    if (UtilValidate.isNotEmpty(fromDateStr)) {
      fromDate = UtilDateTime.toTimestamp(fromDateStr);
    }
    traverseContext.put("fromDate", fromDate);
    Timestamp thruDate = null;
    if (UtilValidate.isNotEmpty(thruDateStr)) {
      thruDate = UtilDateTime.toTimestamp(thruDateStr);
    }
    traverseContext.put("thruDate", thruDate);
    String startContentAssocTypeId = (String) templateCtx.get("contentAssocTypeId");
    if (startContentAssocTypeId != null) startContentAssocTypeId = "SUB_CONTENT";
    traverseContext.put("contentAssocTypeId", startContentAssocTypeId);
    String direction = (String) templateCtx.get("direction");
    if (UtilValidate.isEmpty(direction)) direction = "From";
    traverseContext.put("direction", direction);

    return new LoopWriter(out) {

      @Override
      public void write(char cbuf[], int off, int len) {
        // StringBuilder ctxBuf = (StringBuilder) templateContext.get("buf");
        // ctxBuf.append(cbuf, off, len);
        buf.append(cbuf, off, len);
      }

      @Override
      public void flush() throws IOException {
        out.flush();
      }

      @Override
      public int onStart() throws TemplateModelException, IOException {
        // templateContext.put("buf", new StringBuilder());
        List<Map<String, Object>> nodeTrail = FastList.newInstance();
        traverseContext.put("nodeTrail", nodeTrail);
        // GenericValue content = null;
        /*
                        if (UtilValidate.isNotEmpty(contentId)) {
                            try {
                                content = delegator.findByPrimaryKey("Content", UtilMisc.toMap("contentId", contentId));
                            } catch (GenericEntityException e) {
                                // TODO: Not sure what to put here.
                                throw new RuntimeException(e.getMessage());
                            }
                        }
        */
        Map<String, Object> rootNode = ContentWorker.makeNode(subContentDataResourceView);
        ContentWorker.traceNodeTrail("1", nodeTrail);
        ContentWorker.selectKids(rootNode, traverseContext);
        ContentWorker.traceNodeTrail("2", nodeTrail);
        nodeTrail.add(rootNode);
        boolean isPick =
            checkWhen(
                subContentDataResourceView, (String) traverseContext.get("contentAssocTypeId"));
        rootNode.put("isPick", Boolean.valueOf(isPick));
        if (!isPick) {
          ContentWorker.traceNodeTrail("3", nodeTrail);
          isPick = ContentWorker.traverseSubContent(traverseContext);
          ContentWorker.traceNodeTrail("4", nodeTrail);
        }
        if (isPick) {
          populateContext(traverseContext, templateCtx);
          ContentWorker.traceNodeTrail("5", nodeTrail);
          return TransformControl.EVALUATE_BODY;
        } else {
          return TransformControl.SKIP_BODY;
        }
      }

      @Override
      public int afterBody() throws TemplateModelException, IOException {
        // out.write(buf.toString());
        // buf.setLength(0);
        // templateContext.put("buf", new StringBuilder());
        List<Map<String, Object>> nodeTrail =
            UtilGenerics.checkList(traverseContext.get("nodeTrail"));
        ContentWorker.traceNodeTrail("6", nodeTrail);
        boolean inProgress = ContentWorker.traverseSubContent(traverseContext);
        ContentWorker.traceNodeTrail("7", nodeTrail);
        if (inProgress) {
          populateContext(traverseContext, templateCtx);
          ContentWorker.traceNodeTrail("8", nodeTrail);
          return TransformControl.REPEAT_EVALUATION;
        } else return TransformControl.END_EVALUATION;
      }

      @Override
      public void close() throws IOException {
        String wrappedFTL = buf.toString();
        String encloseWrappedText = (String) templateCtx.get("encloseWrappedText");
        if (UtilValidate.isEmpty(encloseWrappedText)
            || encloseWrappedText.equalsIgnoreCase("false")) {
          out.write(wrappedFTL);
          wrappedFTL = null; // So it won't get written again below.
        }
        String wrapTemplateId = (String) templateCtx.get("wrapTemplateId");
        if (UtilValidate.isNotEmpty(wrapTemplateId)) {
          templateCtx.put("wrappedFTL", wrappedFTL);
          Map<String, Object> templateRoot = FreeMarkerWorker.createEnvironmentMap(env);
          /*
                              templateRoot.put("viewSize", viewSize);
                              templateRoot.put("viewIndex", viewIndex);
                              templateRoot.put("listSize", listSize);
                              templateRoot.put("highIndex", highIndex);
                              templateRoot.put("lowIndex", lowIndex);
                              templateRoot.put("queryString", queryString);
                              templateRoot.put("wrapDataResourceTypeId", subDataResourceTypeId);
                              templateRoot.put("wrapContentIdTo", contentId);
                              templateRoot.put("wrapMimeTypeId", mimeTypeId);
                              //templateRoot.put("wrapMapKey", mapKey);

          */
          templateRoot.put("context", templateCtx);
          String mimeTypeId = (String) templateCtx.get("mimeTypeId");
          Locale locale = (Locale) templateCtx.get("locale");
          if (locale == null) locale = Locale.getDefault();
          try {
            ContentWorker.renderContentAsText(
                dispatcher,
                delegator,
                wrapTemplateId,
                out,
                templateRoot,
                locale,
                mimeTypeId,
                null,
                null,
                true);
          } catch (GeneralException e) {
            Debug.logError(e, "Error rendering content", module);
            throw new IOException("Error rendering content" + e.toString());
          }
          /*
                              Map resultsCtx = FreeMarkerWorker.getWrappedObject("context", env);
                              templateContext.put("contentId", contentId);
                              templateContext.put("locale", locale);
                              templateContext.put("mapKey", null);
                              templateContext.put("subContentId", null);
                              templateContext.put("templateContentId", null);
                              templateContext.put("subDataResourceTypeId", null);
                              templateContext.put("mimeTypeId", null);
          */
        } else {
          if (UtilValidate.isNotEmpty(wrappedFTL)) out.write(wrappedFTL);
        }
        FreeMarkerWorker.removeValues(templateCtx, removeKeyNames);
        FreeMarkerWorker.reloadValues(templateCtx, savedValues, env);
      }

      private boolean checkWhen(GenericValue thisContent, String contentAssocTypeId) {
        boolean isPick = false;
        Map<String, Object> assocContext = FastMap.newInstance();
        if (UtilValidate.isEmpty(contentAssocTypeId)) {
          contentAssocTypeId = "";
        }
        assocContext.put("contentAssocTypeId", contentAssocTypeId);
        // assocContext.put("contentTypeId", assocValue.get("contentTypeId"));
        // String assocRelation = null;
        String thisDirection = (String) templateCtx.get("direction");
        String thisContentId = (String) templateCtx.get("thisContentId");
        // String relatedDirection = null;
        if (thisDirection != null && thisDirection.equalsIgnoreCase("From")) {
          assocContext.put("contentIdFrom", thisContentId);
          // assocRelation = "FromContent";
          // relatedDirection = "From";
        } else {
          assocContext.put("contentIdTo", thisContentId);
          // assocRelation = "ToContent";
          // relatedDirection = "To";
        }
        assocContext.put("content", thisContent);
        List<Object> purposes = ContentWorker.getPurposes(thisContent);
        assocContext.put("purposes", purposes);
        List<String> contentTypeAncestry = FastList.newInstance();
        String contentTypeId = (String) thisContent.get("contentTypeId");
        try {
          ContentWorker.getContentTypeAncestry(delegator, contentTypeId, contentTypeAncestry);
        } catch (GenericEntityException e) {
          return false;
        }
        assocContext.put("typeAncestry", contentTypeAncestry);
        Map<String, Object> whenMap = UtilGenerics.checkMap(traverseContext.get("whenMap"));
        // String pickWhen = (String)whenMap.get("pickWhen");
        List<Map<String, ? extends Object>> nodeTrail =
            UtilGenerics.checkList(traverseContext.get("nodeTrail"));
        int indentSz = indent.intValue() + nodeTrail.size();
        assocContext.put("indentObj", Integer.valueOf(indentSz));
        isPick = ContentWorker.checkWhen(assocContext, (String) whenMap.get("pickWhen"));
        return isPick;
      }

      public void populateContext(
          Map<String, Object> traverseContext, Map<String, Object> templateContext) {
        List<Map<String, Object>> nodeTrail =
            UtilGenerics.checkList(traverseContext.get("nodeTrail"));
        int sz = nodeTrail.size();
        Map<String, Object> node = nodeTrail.get(sz - 1);
        // GenericValue content = (GenericValue)node.get("value");
        String contentId = (String) node.get("contentId");
        // String subContentId = (String)node.get("subContentId");
        templateContext.put("subContentId", contentId);
        templateContext.put("subContentDataResourceView", null);
        int indentSz = indent.intValue() + nodeTrail.size();
        templateContext.put("indent", Integer.valueOf(indentSz));
        if (sz >= 2) {
          Map<String, Object> parentNode = nodeTrail.get(sz - 2);
          GenericValue parentContent = (GenericValue) parentNode.get("value");
          String parentContentId = (String) parentNode.get("contentId");
          templateContext.put("parentContentId", parentContentId);
          templateContext.put("parentContent", parentContent);
          templateContext.put("nodeTrail", nodeTrail);
        }
      }
    };
  }
 public String getNamespaceForPrefix(String prefix) {
   if (prefix.equals(Template.DEFAULT_NAMESPACE_PREFIX)) {
     return Environment.getCurrentEnvironment().getDefaultNS();
   }
   return Environment.getCurrentEnvironment().getNamespaceForPrefix(prefix);
 }
 public Environment getEnvironment() {
   if (env == null) {
     env = Environment.getCurrentEnvironment();
   }
   return env;
 }
예제 #5
0
  @SuppressWarnings("unchecked")
  public Writer getWriter(final Writer out, Map args) {
    final Environment env = Environment.getCurrentEnvironment();
    // final Map templateCtx = FreeMarkerWorker.getWrappedObject("context", env);
    // final Map templateCtx = new HashMap<String, Object>();
    final LocalDispatcher dispatcher = FreeMarkerWorker.getWrappedObject("dispatcher", env);
    final Delegator delegator = FreeMarkerWorker.getWrappedObject("delegator", env);
    final HttpServletRequest request = FreeMarkerWorker.getWrappedObject("request", env);
    final HttpServletResponse response = FreeMarkerWorker.getWrappedObject("response", env);
    final Map<String, Object> templateRoot = FreeMarkerWorker.createEnvironmentMap(env);
    if (Debug.verboseOn()) {
      Debug.logVerbose(
          "in RenderSubContent, contentId(0):" + templateRoot.get("contentId"), module);
    }
    FreeMarkerWorker.getSiteParameters(request, templateRoot);
    final Map<String, Object> savedValuesUp = new HashMap<String, Object>();
    FreeMarkerWorker.saveContextValues(templateRoot, upSaveKeyNames, savedValuesUp);
    FreeMarkerWorker.overrideWithArgs(templateRoot, args);
    if (Debug.verboseOn()) {
      Debug.logVerbose(
          "in RenderSubContent, contentId(2):" + templateRoot.get("contentId"), module);
    }
    // not used yet: final GenericValue userLogin = FreeMarkerWorker.getWrappedObject("userLogin",
    // env);
    // not used yet: List trail = (List)templateRoot.get("globalNodeTrail");
    // if (Debug.infoOn()) Debug.logInfo("in Render(0), globalNodeTrail ." + trail , module);
    // not used yet: String contentAssocPredicateId =
    // (String)templateRoot.get("contentAssocPredicateId");
    // not used yet: String strNullThruDatesOnly = (String)templateRoot.get("nullThruDatesOnly");
    // not used yet: Boolean nullThruDatesOnly = (strNullThruDatesOnly != null &&
    // strNullThruDatesOnly.equalsIgnoreCase("true")) ? Boolean.TRUE :Boolean.FALSE;
    final String thisContentId = (String) templateRoot.get("contentId");
    final String xmlEscape = (String) templateRoot.get("xmlEscape");
    final boolean directAssocMode = UtilValidate.isNotEmpty(thisContentId) ? true : false;
    if (Debug.verboseOn()) {
      Debug.logVerbose("in Render(0), directAssocMode ." + directAssocMode, module);
    }
    /*
    if (Debug.infoOn()) Debug.logInfo("in Render(0), thisSubContentId ." + thisSubContentId , module);
    String thisSubContentId =  (String)templateRoot.get("subContentId");
    GenericValue val = null;
    try {
        val = FreeMarkerWorker.getCurrentContent(delegator, trail, userLogin, templateRoot, nullThruDatesOnly, contentAssocPredicateId);
    } catch (GeneralException e) {
        throw new RuntimeException("Error getting current content. " + e.toString());
    }
    final GenericValue view = val;

    String dataResourceId = null;
    String subContentIdSub = null;
    if (view != null) {
        try {
            dataResourceId = (String) view.get("drDataResourceId");
        } catch (Exception e) {
            dataResourceId = (String) view.get("dataResourceId");
        }
        subContentIdSub = (String) view.get("contentId");
    }
    // This order is taken so that the dataResourceType can be overridden in the transform arguments.
    String subDataResourceTypeId = (String)templateRoot.get("subDataResourceTypeId");
    if (UtilValidate.isEmpty(subDataResourceTypeId)) {
        try {
            subDataResourceTypeId = (String) view.get("drDataResourceTypeId");
        } catch (Exception e) {
            // view may be "Content"
        }
        // TODO: If this value is still empty then it is probably necessary to get a value from
        // the parent context. But it will already have one and it is the same context that is
        // being passed.
    }
    String mimeTypeId = FreeMarkerWorker.getMimeTypeId(delegator, view, templateRoot);
    templateRoot.put("drDataResourceId", dataResourceId);
    templateRoot.put("mimeTypeId", mimeTypeId);
    templateRoot.put("dataResourceId", dataResourceId);
    templateRoot.put("subContentId", subContentIdSub);
    templateRoot.put("subDataResourceTypeId", subDataResourceTypeId);
    */

    final Map<String, Object> savedValues = new HashMap<String, Object>();

    return new Writer(out) {

      @Override
      public void write(char cbuf[], int off, int len) {}

      @Override
      public void flush() throws IOException {
        out.flush();
      }

      @Override
      public void close() throws IOException {
        List<Map<String, ? extends Object>> globalNodeTrail =
            UtilGenerics.checkList(templateRoot.get("globalNodeTrail"));
        if (Debug.verboseOn()) {
          Debug.logVerbose(
              "Render close, globalNodeTrail(2a):" + ContentWorker.nodeTrailToCsv(globalNodeTrail),
              "");
        }
        renderSubContent();
        // if (Debug.verboseOn()) Debug.logVerbose("in Render(2), globalNodeTrail ." +
        // getWrapped(env, "globalNodeTrail") , module);
      }

      public void renderSubContent() throws IOException {
        String mimeTypeId = (String) templateRoot.get("mimeTypeId");
        Object localeObject = templateRoot.get("locale");
        Locale locale = null;
        if (localeObject == null) {
          locale = UtilHttp.getLocale(request);
        } else {
          locale = UtilMisc.ensureLocale(localeObject);
        }

        // TemplateHashModel dataRoot = env.getDataModel();
        // Timestamp fromDate = UtilDateTime.nowTimestamp();
        // List passedGlobalNodeTrail = (List)templateRoot.get("globalNodeTrail");
        String editRequestName = (String) templateRoot.get("editRequestName");
        if (Debug.verboseOn()) {
          Debug.logVerbose("in Render(3), editRequestName ." + editRequestName, module);
        }
        /*
        GenericValue thisView = null;
        if (view != null) {
            thisView = view;
        } else if (passedGlobalNodeTrail.size() > 0) {
            Map map = (Map)passedGlobalNodeTrail.get(passedGlobalNodeTrail.size() - 1);
            if (Debug.infoOn()) Debug.logInfo("in Render(3), map ." + map , module);
            if (map != null)
                thisView = (GenericValue)map.get("value");
        }
        if (Debug.verboseOn()) Debug.logVerbose("in RenderSubContent, subContentId:" + templateRoot.get("subContentId"), module);
        if (Debug.verboseOn()) Debug.logVerbose("in RenderSubContent, contentId:" + templateRoot.get("contentId"), module);
        */

        if (UtilValidate.isNotEmpty(editRequestName)) {
          String editStyle = getEditStyle();
          openEditWrap(out, editStyle);
        }

        if (Debug.verboseOn()) {
          Debug.logVerbose(
              "in RenderSubContent, contentId(2):" + templateRoot.get("contentId"), module);
          Debug.logVerbose(
              "in RenderSubContent, subContentId(2):" + templateRoot.get("subContentId"), module);
        }
        FreeMarkerWorker.saveContextValues(templateRoot, saveKeyNames, savedValues);
        // if (thisView != null) {
        try {
          String txt =
              ContentWorker.renderContentAsText(
                  dispatcher, delegator, thisContentId, templateRoot, locale, mimeTypeId, true);
          if ("true".equals(xmlEscape)) {
            txt = UtilFormatOut.encodeXmlValue(txt);
          }

          out.write(txt);

          // if (Debug.infoOn()) Debug.logInfo("in RenderSubContent, after
          // renderContentAsTextCache:", module);
        } catch (GeneralException e) {
          String errMsg = "Error rendering thisContentId:" + thisContentId + " msg:" + e.toString();
          Debug.logError(e, errMsg, module);
          // just log a message and don't return anything: throw new IOException();
        }
        // }
        FreeMarkerWorker.reloadValues(templateRoot, savedValuesUp, env);
        FreeMarkerWorker.reloadValues(templateRoot, savedValues, env);
        if (UtilValidate.isNotEmpty(editRequestName)) {
          closeEditWrap(out, editRequestName);
        }

        // if (Debug.infoOn()) Debug.logInfo("in Render(4), globalNodeTrail ." + getWrapped(env,
        // "globalNodeTrail") , module);
      }

      public void openEditWrap(Writer out, String editStyle) throws IOException {
        String divStr = "<div class=\"" + editStyle + "\">";
        out.write(divStr);
      }

      public void closeEditWrap(Writer out, String editRequestName) throws IOException {
        if (Debug.infoOn()) {
          Debug.logInfo(
              "in RenderSubContent, contentId(3):" + templateRoot.get("contentId"), module);
          Debug.logInfo(
              "in RenderSubContent, subContentId(3):" + templateRoot.get("subContentId"), module);
        }
        String fullRequest = editRequestName;
        String contentId = null;
        contentId = (String) templateRoot.get("subContentId");
        String delim = "?";
        if (UtilValidate.isNotEmpty(contentId)) {
          fullRequest += delim + "contentId=" + contentId;
          delim = "&";
        }

        out.write("<a href=\"");
        ServletContext servletContext = request.getSession().getServletContext();
        RequestHandler rh = (RequestHandler) servletContext.getAttribute("_REQUEST_HANDLER_");
        out.append(rh.makeLink(request, response, "/" + fullRequest, false, false, true));
        out.write("\">Edit</a>");
        out.write("</div>");
      }

      public String getEditStyle() {
        String editStyle = (String) templateRoot.get("editStyle");
        if (UtilValidate.isEmpty(editStyle)) {
          editStyle = UtilProperties.getPropertyValue("content", "defaultEditStyle");
        }
        if (UtilValidate.isEmpty(editStyle)) {
          editStyle = "buttontext";
        }
        return editStyle;
      }
    };
  }
  @SuppressWarnings("unchecked")
  public Writer getWriter(final Writer out, Map args) {
    final StringBuilder buf = new StringBuilder();
    final Environment env = Environment.getCurrentEnvironment();
    final Map<String, Object> templateCtx = FreeMarkerWorker.createEnvironmentMap(env);
    // FreeMarkerWorker.convertContext(templateCtx);
    final Delegator delegator = FreeMarkerWorker.getWrappedObject("delegator", env);
    final HttpServletRequest request = FreeMarkerWorker.getWrappedObject("request", env);
    final GenericValue userLogin = FreeMarkerWorker.getWrappedObject("userLogin", env);
    FreeMarkerWorker.getSiteParameters(request, templateCtx);
    FreeMarkerWorker.overrideWithArgs(templateCtx, args);
    final String mode = (String) templateCtx.get("mode");
    final String quickCheckContentId = (String) templateCtx.get("quickCheckContentId");
    final Map<String, Object> savedValues = FastMap.newInstance();
    // Debug.logInfo("in CheckPermission, contentId(1):" + templateCtx.get("contentId"),"");
    // Debug.logInfo("in CheckPermission, subContentId(1):" + templateCtx.get("subContentId"),"");

    return new LoopWriter(out) {

      @Override
      public void write(char cbuf[], int off, int len) {
        buf.append(cbuf, off, len);
      }

      @Override
      public void flush() throws IOException {
        out.flush();
      }

      @Override
      public int onStart() throws TemplateModelException, IOException {
        List<Map<String, ? extends Object>> trail =
            UtilGenerics.checkList(templateCtx.get("globalNodeTrail"));
        // String trailCsv = ContentWorker.nodeTrailToCsv(trail);
        // Debug.logInfo("in CheckPermission, trailCsv(2):" + trailCsv,"");
        // Debug.logInfo("in CheckPermission, contentId(2):" + templateCtx.get("contentId"),"");
        // Debug.logInfo("in CheckPermission, subContentId(2):" +
        // templateCtx.get("subContentId"),"");

        GenericValue currentContent = null;
        String contentAssocPredicateId = (String) templateCtx.get("contentAssocPredicateId");
        String strNullThruDatesOnly = (String) templateCtx.get("nullThruDatesOnly");
        Boolean nullThruDatesOnly =
            (strNullThruDatesOnly != null && strNullThruDatesOnly.equalsIgnoreCase("true"))
                ? Boolean.TRUE
                : Boolean.FALSE;
        GenericValue val = null;
        try {
          val =
              ContentWorker.getCurrentContent(
                  delegator,
                  trail,
                  userLogin,
                  templateCtx,
                  nullThruDatesOnly,
                  contentAssocPredicateId);
        } catch (GeneralException e) {
          throw new RuntimeException("Error getting current content. " + e.toString());
        }
        // final GenericValue view = val;
        currentContent = val;
        if (currentContent != null) {
          // Debug.logInfo("in CheckPermission, currentContent(0):" +
          // currentContent.get("contentId"),"");
        }

        if (currentContent == null) {
          currentContent = delegator.makeValue("Content");
          currentContent.put("ownerContentId", templateCtx.get("ownerContentId"));
        }
        // Debug.logInfo("in CheckPermission, currentContent(1):" +
        // currentContent.get("contentId"),"");

        Security security = null;
        if (request != null) {
          security = (Security) request.getAttribute("security");
        }

        String statusId = (String) currentContent.get("statusId");
        String passedStatusId = (String) templateCtx.get("statusId");
        List<String> statusList = StringUtil.split(passedStatusId, "|");
        if (statusList == null) {
          statusList = FastList.newInstance();
        }
        if (UtilValidate.isNotEmpty(statusId) && !statusList.contains(statusId)) {
          statusList.add(statusId);
        }
        String targetPurpose = (String) templateCtx.get("contentPurposeList");
        List<String> purposeList = StringUtil.split(targetPurpose, "|");
        String entityOperation = (String) templateCtx.get("entityOperation");
        String targetOperation = (String) templateCtx.get("targetOperation");
        if (UtilValidate.isEmpty(targetOperation)) {
          if (UtilValidate.isNotEmpty(entityOperation)) {
            targetOperation = "CONTENT" + entityOperation;
          }
        }
        List<String> targetOperationList = StringUtil.split(targetOperation, "|");
        if (targetOperationList.size() == 0) {
          // Debug.logInfo("in CheckPermission, entityOperation:" + entityOperation,"");
          // Debug.logInfo("in CheckPermission, templateCtx:" + templateCtx,"");
          throw new IOException("targetOperationList has zero size.");
        }
        List<String> roleList = FastList.newInstance();

        String privilegeEnumId = (String) currentContent.get("privilegeEnumId");
        Map<String, Object> results =
            EntityPermissionChecker.checkPermission(
                currentContent,
                statusList,
                userLogin,
                purposeList,
                targetOperationList,
                roleList,
                delegator,
                security,
                entityOperation,
                privilegeEnumId,
                quickCheckContentId);

        boolean isError =
            ModelService.RESPOND_ERROR.equals(results.get(ModelService.RESPONSE_MESSAGE));
        if (isError) {
          throw new IOException(ModelService.RESPONSE_MESSAGE);
        }

        String permissionStatus = (String) results.get("permissionStatus");

        if (UtilValidate.isEmpty(permissionStatus) || !permissionStatus.equals("granted")) {
          String errorMessage = "Permission to add response is denied (2)";
          PermissionRecorder recorder = (PermissionRecorder) results.get("permissionRecorder");
          // Debug.logInfo("recorder(0):" + recorder, "");
          if (recorder != null) {
            String permissionMessage = recorder.toHtml();
            // Debug.logInfo("permissionMessage(0):" + permissionMessage, "");
            errorMessage += " \n " + permissionMessage;
          }
          templateCtx.put("permissionErrorMsg", errorMessage);
        }

        if (permissionStatus != null && permissionStatus.equalsIgnoreCase("granted")) {
          FreeMarkerWorker.saveContextValues(templateCtx, saveKeyNames, savedValues);
          if (mode == null || !mode.equalsIgnoreCase("not-equals"))
            return TransformControl.EVALUATE_BODY;
          else return TransformControl.SKIP_BODY;
        } else {
          if (mode == null || !mode.equalsIgnoreCase("not-equals"))
            return TransformControl.SKIP_BODY;
          else return TransformControl.EVALUATE_BODY;
        }
      }

      @Override
      public void close() throws IOException {
        FreeMarkerWorker.reloadValues(templateCtx, savedValues, env);
        String wrappedContent = buf.toString();
        out.write(wrappedContent);
      }
    };
  }