private void writeDataCell(State itemState, String fieldName) throws IOException { page.writeStart("td"); for (Iterator<Object> i = CollectionUtils.recursiveIterable(itemState.getByPath(fieldName)).iterator(); i.hasNext(); ) { Object value = i.next(); page.writeObject(value); if (i.hasNext()) { page.writeHtml(", "); } } page.writeEnd(); }
protected void writeTableHtml(Iterable<?> items) throws IOException { HttpServletRequest request = page.getRequest(); page.putOverride( Recordable.class, (HtmlWriter writer, Recordable object) -> { ToolPageContext page = (ToolPageContext) writer; page.writeObjectLabel(object); }); page.putOverride( Metric.class, (HtmlWriter writer, Metric object) -> { writer.write(Double.toString(object.getSum())); }); page.putOverride( Content.class, (HtmlWriter writer, Content content) -> { ToolPageContext page = (ToolPageContext) writer; page.writeStart( "a", "href", page.objectUrl("/content/edit.jsp", content), "target", "_top"); page.writeObjectLabel(content); page.writeEnd(); }); page.putOverride( StorageItem.class, (HtmlWriter writer, StorageItem item) -> { ToolPageContext page = (ToolPageContext) writer; page.writeElement( "img", "height", 100, "src", ImageEditor.Static.getDefault() != null ? new ImageTag.Builder(item).setHeight(100).toUrl() : item.getPublicUrl()); }); page.writeStart("table", "class", "searchResultTable links table-striped pageThumbnails"); page.writeStart("thead"); page.writeStart("tr"); page.writeStart("th"); page.writeElement("input", "type", "checkbox", "class", "searchResult-checkAll"); page.writeEnd(); if (sortField != null && ObjectField.DATE_TYPE.equals(sortField.getInternalType())) { page.writeStart("th", "colspan", 2); page.writeHtml(sortField.getDisplayName()); page.writeEnd(); } if (showSiteLabel) { page.writeStart("th"); page.writeHtml(page.localize(ListSearchResultView.class, "label.site")); page.writeEnd(); } if (showTypeLabel) { page.writeStart("th"); page.writeHtml(page.localize(ListSearchResultView.class, "label.type")); page.writeEnd(); } page.writeStart("th"); page.writeHtml(page.localize(ListSearchResultView.class, "label.label")); page.writeEnd(); if (sortField != null && !ObjectField.DATE_TYPE.equals(sortField.getInternalType())) { page.writeStart("th"); page.writeHtml(sortField.getDisplayName()); page.writeEnd(); } ToolUser user = page.getUser(); if (user != null) { ObjectType selectedType = search.getSelectedType(); List<String> fieldNames = user.getSearchResultFieldsByTypeId() .get(selectedType != null ? selectedType.getId().toString() : ""); if (fieldNames == null) { for (Class<? extends SearchResultField> c : ClassFinder.Static.findClasses(SearchResultField.class)) { if (!c.isInterface() && !Modifier.isAbstract(c.getModifiers())) { SearchResultField field = TypeDefinition.getInstance(c).newInstance(); if (field.isDefault(selectedType) && !ObjectUtils.equals(sortField, field)) { field.writeTableHeaderCellHtml(page); } } } if (selectedType != null) { for (ObjectField field : selectedType.getFields()) { if (Boolean.TRUE.equals(field.as(ToolUi.class).getDefaultSearchResult())) { writeHeaderCell(field); } } } } else { for (String fieldName : fieldNames) { Class<?> fieldNameClass = ObjectUtils.getClassByName(fieldName); if (fieldNameClass != null && SearchResultField.class.isAssignableFrom(fieldNameClass)) { @SuppressWarnings("unchecked") SearchResultField field = TypeDefinition.getInstance((Class<? extends SearchResultField>) fieldNameClass) .newInstance(); if (field.isSupported(selectedType) && !ObjectUtils.equals(sortField, field)) { field.writeTableHeaderCellHtml(page); } } else { ObjectField field = null; if (selectedType != null) { field = selectedType.getField(fieldName); } if (field == null) { field = Database.Static.getDefault().getEnvironment().getField(fieldName); } if (field != null && !ObjectUtils.equals(sortField, field)) { writeHeaderCell(field); } } } } } page.writeEnd(); page.writeEnd(); page.writeStart("tbody"); for (Object item : items) { State itemState = State.getInstance(item); String permalink = itemState.as(Directory.ObjectModification.class).getPermalink(); Integer embedWidth = null; if (ObjectUtils.isBlank(permalink)) { ObjectType type = itemState.getType(); if (type != null) { Renderer.TypeModification rendererData = type.as(Renderer.TypeModification.class); int previewWidth = rendererData.getEmbedPreviewWidth(); if (previewWidth > 0 && !ObjectUtils.isBlank(rendererData.getEmbedPath())) { permalink = "/_preview?_embed=true&_cms.db.previewId=" + itemState.getId(); embedWidth = 320; } } } page.writeStart( "tr", "data-preview-url", permalink, "data-preview-embed-width", embedWidth, "class", State.getInstance(item).getId().equals(page.param(UUID.class, "id")) ? "selected" : null); page.writeStart("td"); itemWriter.writeCheckboxHtml(page, search, item); page.writeEnd(); if (sortField != null && ObjectField.DATE_TYPE.equals(sortField.getInternalType())) { DateTime dateTime = page.toUserDateTime(itemState.getByPath(sortField.getInternalName())); if (dateTime == null) { page.writeStart("td", "colspan", 2); page.writeHtml("N/A"); page.writeEnd(); } else { String date = page.formatUserDate(dateTime); page.writeStart("td", "class", "date"); if (!ObjectUtils.equals(date, request.getAttribute(PREVIOUS_DATE_ATTRIBUTE))) { request.setAttribute(PREVIOUS_DATE_ATTRIBUTE, date); page.writeHtml(date); } page.writeEnd(); page.writeStart("td", "class", "time"); page.writeHtml(page.formatUserTime(dateTime)); page.writeEnd(); } } if (showSiteLabel) { page.writeStart("td"); page.writeObjectLabel(itemState.as(Site.ObjectModification.class).getOwner()); page.writeEnd(); } if (showTypeLabel) { page.writeStart("td"); page.writeTypeLabel(item); page.writeEnd(); } page.writeStart("td", "data-preview-anchor", ""); itemWriter.writeBeforeHtml(page, search, item); page.writeObjectLabel(item); itemWriter.writeAfterHtml(page, search, item); page.writeEnd(); if (sortField != null && !ObjectField.DATE_TYPE.equals(sortField.getInternalType())) { String sortFieldName = sortField.getInternalName(); Object value = itemState.getByPath(sortFieldName); page.writeStart("td"); if (value instanceof Metric) { page.writeStart("span", "style", page.cssString("white-space", "nowrap")); Double maxSum = (Double) request.getAttribute(MAX_SUM_ATTRIBUTE); if (maxSum == null) { Object maxObject = search.toQuery(page.getSite()).sortDescending(sortFieldName).first(); maxSum = maxObject != null ? ((Metric) State.getInstance(maxObject).get(sortFieldName)).getSum() : 1.0; request.setAttribute(MAX_SUM_ATTRIBUTE, maxSum); } Metric valueMetric = (Metric) value; Map<DateTime, Double> sumEntries = valueMetric.groupSumByDate( new MetricInterval.Daily(), new DateTime().dayOfMonth().roundFloorCopy().minusDays(7), null); double sum = valueMetric.getSum(); long sumLong = (long) sum; if (sumLong == sum) { page.writeHtml(String.format("%,2d ", sumLong)); } else { page.writeHtml(String.format("%,2.2f ", sum)); } if (!sumEntries.isEmpty()) { long minMillis = Long.MAX_VALUE; long maxMillis = Long.MIN_VALUE; for (Map.Entry<DateTime, Double> sumEntry : sumEntries.entrySet()) { long sumMillis = sumEntry.getKey().getMillis(); if (sumMillis < minMillis) { minMillis = sumMillis; } if (sumMillis > maxMillis) { maxMillis = sumMillis; } } double cumulativeSum = 0.0; StringBuilder path = new StringBuilder(); double xRange = maxMillis - minMillis; int width = 35; int height = 18; for (Map.Entry<DateTime, Double> sumEntry : sumEntries.entrySet()) { cumulativeSum += sumEntry.getValue(); path.append('L'); path.append((sumEntry.getKey().getMillis() - minMillis) / xRange * width); path.append(','); path.append(height - cumulativeSum / maxSum * height); } path.setCharAt(0, 'M'); page.writeStart( "svg", "xmlns", "http://www.w3.org/2000/svg", "width", width, "height", height, "style", page.cssString( "display", "inline-block", "vertical-align", "middle")); page.writeStart("path", "fill", "none", "stroke", "#444444", "d", path.toString()); page.writeEnd(); page.writeEnd(); } page.writeEnd(); } else if (value instanceof Recordable) { page.writeHtml(((Recordable) value).getState().getLabel()); } else { for (Iterator<Object> i = CollectionUtils.recursiveIterable(value).iterator(); i.hasNext(); ) { Object collectionValue = i.next(); page.writeObject(collectionValue); if (i.hasNext()) { page.writeHtml(", "); } } } page.writeEnd(); } if (user != null) { ObjectType selectedType = search.getSelectedType(); List<String> fieldNames = user.getSearchResultFieldsByTypeId() .get(selectedType != null ? selectedType.getId().toString() : ""); ObjectType itemType = itemState.getType(); if (fieldNames == null) { for (Class<? extends SearchResultField> c : ClassFinder.Static.findClasses(SearchResultField.class)) { if (!c.isInterface() && !Modifier.isAbstract(c.getModifiers())) { SearchResultField field = TypeDefinition.getInstance(c).newInstance(); if (field.isDefault(itemType) && !ObjectUtils.equals(sortField, field)) { field.writeTableDataCellHtml(page, item); } } } if (selectedType != null) { for (ObjectField field : selectedType.getFields()) { if (Boolean.TRUE.equals(field.as(ToolUi.class).getDefaultSearchResult())) { writeDataCell(itemState, field.getInternalName()); } } } } else { for (String fieldName : fieldNames) { Class<?> fieldNameClass = ObjectUtils.getClassByName(fieldName); if (fieldNameClass != null && SearchResultField.class.isAssignableFrom(fieldNameClass)) { @SuppressWarnings("unchecked") SearchResultField field = TypeDefinition.getInstance((Class<? extends SearchResultField>) fieldNameClass) .newInstance(); if (field.isSupported(itemState.getType()) && !ObjectUtils.equals(sortField, field)) { field.writeTableDataCellHtml(page, item); } } else { ObjectField field = itemState.getField(fieldName); if (field == null) { field = Database.Static.getDefault().getEnvironment().getField(fieldName); } if (field != null && !ObjectUtils.equals(sortField, field)) { writeDataCell(itemState, fieldName); } } } } } page.writeEnd(); } page.writeEnd(); page.writeEnd(); page.writeStart("div", "id", page.createId()); page.writeEnd(); page.writeStart("script", "type", "text/javascript"); page.writeRaw( "$('#" + page.getId() + "').siblings('.searchResultTable').find('tr').each(function() {"); page.writeRaw(" if ($(this).find('td > a').size() > 1) {"); page.writeRaw( " $(this).closest('.searchResultTable').addClass('multipleLinkedColumns');"); page.writeRaw(" return false;"); page.writeRaw(" }"); page.writeRaw(" });"); page.writeEnd(); }
// Reads: key operator value private Predicate readComparison(Queue<String> tokens, ParameterList parameters) { String key = tokens.poll(); if (key == null) { return null; } String realKey = Query.Static.getCanonicalKey(key); if (realKey != null) { key = realKey; } String operator = tokens.poll(); boolean isIgnoreCase = false; if (operator == null) { throw new IllegalArgumentException(String.format("No operator after [%s] key!", key)); } else { operator = operator.toLowerCase(Locale.ENGLISH); if (operator.endsWith("[c]")) { operator = operator.substring(0, operator.length() - 3); isIgnoreCase = true; } } Object value = readValue(tokens); if (value == null) { throw new IllegalArgumentException( String.format("No value after [%s] key and [%s] operator!", key, operator)); } else if (value instanceof String) { String valueString = (String) value; if (valueString.startsWith("?")) { if (valueString.length() == 1) { value = parameters.poll(); } else { String path = valueString.substring(1); int slashAt = path.indexOf('/'); String splitIndex; String splitPath; if (slashAt > -1) { splitIndex = path.substring(0, slashAt); splitPath = path.substring(slashAt + 1); } else { splitIndex = path; splitPath = ""; } Integer index = ObjectUtils.to(Integer.class, splitIndex); if (index == null) { index = 0; } else { path = splitPath; } value = index < parameters.size() ? parameters.get(index) : null; if (value != null && path.length() > 0) { if (value instanceof Recordable) { value = ((Recordable) value).getState().getByPath(path); } else { value = CollectionUtils.getByPath(value, path); } } } } else if ("true".equalsIgnoreCase(valueString)) { value = Boolean.TRUE; } else if ("false".equalsIgnoreCase(valueString)) { value = Boolean.FALSE; } else if ("null".equalsIgnoreCase(valueString)) { value = null; } else if ("missing".equalsIgnoreCase(valueString)) { value = Query.MISSING_VALUE; } } String comparisonOperator = getComparisonOperators().get(operator); if (comparisonOperator != null) { return new ComparisonPredicate( comparisonOperator, isIgnoreCase, key, ObjectUtils.to(Iterable.class, value)); } else { throw new IllegalArgumentException( String.format("[%s] isn't a valid comparison operator!", operator)); } }