Пример #1
0
 public static Closure createOutputCapturingClosure(
     Object wrappedInstance,
     final Object body1,
     final GrailsWebRequest webRequest,
     boolean preferSubChunkWhenWritingToOtherBuffer) {
   if (body1 == null) {
     return EMPTY_BODY_CLOSURE;
   } else if (body1 instanceof GroovyPageTagBody) {
     GroovyPageTagBody gptb = (GroovyPageTagBody) body1;
     gptb.setPreferSubChunkWhenWritingToOtherBuffer(preferSubChunkWhenWritingToOtherBuffer);
     return gptb;
   } else if (body1 instanceof ConstantClosure) {
     return (Closure) body1;
   } else if (body1 instanceof Closure) {
     return new GroovyPageTagBody(
         wrappedInstance, webRequest, (Closure) body1, preferSubChunkWhenWritingToOtherBuffer);
   } else {
     return new ConstantClosure(body1);
   }
 }
Пример #2
0
  public void invokeTag(
      String tagName, String tagNamespace, int lineNumber, Map attrs, Closure body) {
    // TODO custom namespace stuff needs to be generalized and pluggable
    if (tagNamespace.equals(TEMPLATE_NAMESPACE)) {
      final String tmpTagName = tagName;
      final Map tmpAttrs = attrs;
      tagName = "render";
      tagNamespace = DEFAULT_NAMESPACE;
      attrs =
          new HashMap() {
            {
              put("model", tmpAttrs);
              put("template", tmpTagName);
            }
          };
    } else if (tagNamespace.equals(LINK_NAMESPACE)) {
      final String tmpTagName = tagName;
      final Map tmpAttrs = attrs;
      tagName = "link";
      tagNamespace = DEFAULT_NAMESPACE;
      attrs =
          new HashMap() {
            {
              if (tmpAttrs.size() > 0) {
                put("params", tmpAttrs);
              }
              put("mapping", tmpTagName);
            }
          };
    }

    try {
      GroovyObject tagLib = getTagLib(tagNamespace, tagName);
      if (tagLib != null || gspTagLibraryLookup.hasNamespace(tagNamespace)) {
        if (tagLib != null) {
          boolean returnsObject = gspTagLibraryLookup.doesTagReturnObject(tagNamespace, tagName);
          Object tagLibProp = tagLib.getProperty(tagName);
          if (tagLibProp instanceof Closure) {
            Closure tag = (Closure) ((Closure) tagLibProp).clone();
            Object tagresult = null;

            // GSP<->Sitemesh integration requires that the body or head subchunk isn't written to
            // output
            boolean preferSubChunkWhenWritingToOtherBuffer =
                resolvePreferSubChunk(tagNamespace, tagName);
            if (body instanceof GroovyPageTagBody && preferSubChunkWhenWritingToOtherBuffer) {
              ((GroovyPageTagBody) body).setPreferSubChunkWhenWritingToOtherBuffer(true);
            }

            switch (tag.getParameterTypes().length) {
              case 1:
                tagresult = tag.call(new Object[] {attrs});
                if (returnsObject && tagresult != null && !(tagresult instanceof Writer)) {
                  out.print(tagresult);
                }
                if (body != null && body != EMPTY_BODY_CLOSURE) {
                  body.call();
                }

                break;

              case 2:
                if (tag.getParameterTypes().length == 2) {
                  tagresult =
                      tag.call(new Object[] {attrs, (body != null) ? body : EMPTY_BODY_CLOSURE});
                  if (returnsObject && tagresult != null && !(tagresult instanceof Writer)) {
                    out.print(tagresult);
                  }
                }
                break;
            }

          } else {
            throw new GrailsTagException(
                "Tag ["
                    + tagName
                    + "] does not exist in tag library ["
                    + tagLib.getClass().getName()
                    + "]",
                getGroovyPageFileName(),
                lineNumber);
          }
        } else {
          throw new GrailsTagException(
              "Tag ["
                  + tagName
                  + "] does not exist. No tag library found for namespace: "
                  + tagNamespace,
              getGroovyPageFileName(),
              lineNumber);
        }
      } else {
        out.append('<').append(tagNamespace).append(':').append(tagName);
        for (Object o : attrs.entrySet()) {
          Map.Entry entry = (Map.Entry) o;
          out.append(' ');
          out.append(entry.getKey()).append('=');
          String value = String.valueOf(entry.getValue());
          // handle attribute value quotes & possible escaping " -> &quot;
          boolean containsQuotes = (value.indexOf('"') > -1);
          boolean containsSingleQuote = (value.indexOf('\'') > -1);
          if (containsQuotes && !containsSingleQuote) {
            out.append('\'').append(value).append('\'');
          } else if (containsQuotes & containsSingleQuote) {
            out.append('\"').append(value.replaceAll("\"", "&quot;")).append('\"');
          } else {
            out.append('\"').append(value).append('\"');
          }
        }
        out.append('>');
        if (body != null) {
          Object bodyOutput = body.call();
          if (bodyOutput != null) out.print(bodyOutput);
        }
        out.append("</").append(tagNamespace).append(':').append(tagName).append('>');
      }
    } catch (Throwable e) {
      if (LOG.isTraceEnabled()) {
        LOG.trace("Full exception for problem at " + getGroovyPageFileName() + ":" + lineNumber, e);
      }

      // The capture* tags are internal tags and not to be displayed to the user
      // hence we don't wrap the exception and simple rethrow it
      if (tagName.matches("capture(Body|Head|Meta|Title|Component)")) {
        RuntimeException rte = GrailsExceptionResolver.getFirstRuntimeException(e);
        if (rte == null) {
          throwRootCause(tagName, tagNamespace, lineNumber, e);
        } else {
          throw rte;
        }
      } else {
        throwRootCause(tagName, tagNamespace, lineNumber, e);
      }
    }
  }