TNodeRepeatIter extends TNode { @SuppressWarnings("unchecked") @Override public void render(TRenderContext context) throws IOException { final Object modelValue = context.getModelValue(this.key); if (modelValue == null) { String options = Joiner.on(", ").join(context.getAllModelKeys()); throw new TemplateException("There is no model item with the key: " + this.key + ". Options include: " + options); } Iterable<Object> iter; int size; if (modelValue instanceof Collection) { final Collection collection = (Collection) modelValue; iter = collection; size = collection.size(); } else if (modelValue instanceof GPathResult) { GPathResult value = (GPathResult) modelValue; iter = value; size = value.size(); } else if (modelValue instanceof Map) { Map map = (Map) modelValue; iter = map.entrySet(); size = map.size(); } else if (modelValue.getClass().isArray()) { Object[] value = (Object[]) modelValue; iter = Arrays.asList(value); size = value.length; } else { iter = Collections.singletonList(modelValue); size = 1; } int i = 0; for (Object row : iter) { Map<String, Object> newModelMap = Maps.newHashMap(); newModelMap.put(this.rowContextKey, row); addIndexInfo(newModelMap, i, size); TRenderContext childContext = context.childContext(newModelMap); if (!this.onlyChildren) { context.append("<").append(qName); attributes.render(childContext); context.append(">"); } for (TNode node : getChildren()) { node.render(childContext); } if (!this.onlyChildren) { end.render(childContext); } i++; } if (i == 0 && this.info.isDevMode()) { context.append("<!-- fmt-repeat: ").append(rowContextKey).append(" in ").append(this.key).append(" is empty -->"); } } TNodeRepeatIter(SystemInfo info, TextContentParser parser, boolean onlyChildren, String qName, Attributes attributes, String key, String rowContextKey); @SuppressWarnings("unchecked") @Override void render(TRenderContext context);  }
@Test public void testEmptyRender() throws Exception { final TNodeRepeatIter repeat = new TNodeRepeatIter(info, TextContentParserTest.createTestTextContentParser(), false, null, TNode.EMPTY_ATTRIBUTES, "iter", "key"); Map<String, Object> model = Collections.<String, Object>singletonMap("iter", Collections.emptyList()); final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); repeat.render(new TRenderContext(outputStream, model)); assertEquals("<!-- fmt-repeat: key in iter is empty -->", outputStream.toString()); }