001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.console.datatables; 018 019import java.util.*; 020 021/** 022 * The DataTables server-side-processing response envelope. 023 * 024 * <p> 025 * Serializes (via the normal negotiated serializer) to the JSON shape DataTables expects from a server-side source: 026 * <p class='bjson'> 027 * { 028 * <jf>draw</jf>: 1, 029 * <jf>recordsTotal</jf>: 57, 030 * <jf>recordsFiltered</jf>: 12, 031 * <jf>data</jf>: [ ... ] 032 * } 033 * </p> 034 * 035 * <ul class='spaced-list'> 036 * <li>{@link #getDraw() draw} — the draw counter echoed back from the request (cast to a number by DataTables). 037 * <li>{@link #getRecordsTotal() recordsTotal} — total records before filtering. 038 * <li>{@link #getRecordsFiltered() recordsFiltered} — records after filtering (before paging). 039 * <li>{@link #getData() data} — the page of rows. 040 * <li>{@link #getError() error} — optional error message (omitted from the response when <jk>null</jk>). 041 * </ul> 042 * 043 * <h5 class='section'>Example:</h5> 044 * <p class='bjava'> 045 * <jc>// A normal page of results.</jc> 046 * DataTablesResults<Person> <jv>results</jv> = DataTablesResults.<Person><jsm>create</jsm>() 047 * .setDraw(<jv>request</jv>.getDraw()) 048 * .setRecordsTotal(<jv>page</jv>.total().orElse(0)) 049 * .setRecordsFiltered(<jv>page</jv>.matched().orElse(0)) 050 * .setData(<jv>page</jv>.rows()); 051 * 052 * <jc>// An explicit application-level error envelope (HTTP 200; DataTablesQuery itself no longer builds one).</jc> 053 * DataTablesResults<Person> <jv>errorResults</jv> = DataTablesResults.<jsm>error</jsm>(<jv>request</jv>.getDraw(), <js>"Unknown column 'x'."</js>); 054 * </p> 055 * 056 * @param <T> The row type. 057 * 058 * @since 10.0.0 059 */ 060public class DataTablesResults<T> { 061 062 private int draw; 063 private long recordsTotal; 064 private long recordsFiltered; 065 private List<T> data; 066 private String error; 067 068 /** 069 * Constructor. 070 */ 071 public DataTablesResults() { /* All fields are populated via the fluent setters below. */ } 072 073 /** 074 * Static creator. 075 * 076 * @param <T> The row type. 077 * @return A new empty {@link DataTablesResults}. 078 */ 079 public static <T> DataTablesResults<T> create() { 080 return new DataTablesResults<>(); 081 } 082 083 /** 084 * Builds an error envelope: the draw counter echoed back, no rows, and no counts, with the caller's error message. 085 * 086 * <p> 087 * For an application-level failure an endpoint wants to report with HTTP 200 so DataTables surfaces {@link #getError() 088 * error} through its {@code errMode}. Note that {@code DataTablesQuery} no longer uses this for a 089 * {@code BeanQuerySyntaxException} (unknown column, too many search clauses, ...): since 2026-10-05 that propagates 090 * and is mapped centrally to HTTP 400 with an {@code X-BeanQuery-Error} header. 091 * 092 * <h5 class='section'>Example:</h5> 093 * <p class='bjava'> 094 * <jk>return</jk> DataTablesResults.<jsm>error</jsm>(<jv>request</jv>.getDraw(), <js>"Unknown column 'x'."</js>); 095 * </p> 096 * 097 * @param <T> The row type. 098 * @param draw The draw counter to echo back. 099 * @param message The error message to show. 100 * @return A new {@link DataTablesResults} with only {@code draw} and {@code error} set. 101 */ 102 public static <T> DataTablesResults<T> error(int draw, String message) { 103 return DataTablesResults.<T>create().setDraw(draw).setError(message); 104 } 105 106 /** 107 * Returns the draw counter. 108 * 109 * @return The draw counter. 110 */ 111 public int getDraw() { 112 return draw; 113 } 114 115 /** 116 * Sets the draw counter. 117 * 118 * @param value The value. 119 * @return This object. 120 */ 121 public DataTablesResults<T> setDraw(int value) { 122 this.draw = value; 123 return this; 124 } 125 126 /** 127 * Returns the total record count before filtering. 128 * 129 * @return The total record count. 130 */ 131 public long getRecordsTotal() { 132 return recordsTotal; 133 } 134 135 /** 136 * Sets the total record count before filtering. 137 * 138 * @param value The value. 139 * @return This object. 140 */ 141 public DataTablesResults<T> setRecordsTotal(long value) { 142 this.recordsTotal = value; 143 return this; 144 } 145 146 /** 147 * Returns the record count after filtering (before paging). 148 * 149 * @return The filtered record count. 150 */ 151 public long getRecordsFiltered() { 152 return recordsFiltered; 153 } 154 155 /** 156 * Sets the record count after filtering (before paging). 157 * 158 * @param value The value. 159 * @return This object. 160 */ 161 public DataTablesResults<T> setRecordsFiltered(long value) { 162 this.recordsFiltered = value; 163 return this; 164 } 165 166 /** 167 * Returns the page of rows. 168 * 169 * @return The page of rows. Can be <jk>null</jk>. 170 */ 171 public List<T> getData() { 172 return data; 173 } 174 175 /** 176 * Sets the page of rows. 177 * 178 * @param value The value. 179 * @return This object. 180 */ 181 public DataTablesResults<T> setData(List<T> value) { 182 this.data = value; 183 return this; 184 } 185 186 /** 187 * Returns the optional error message. 188 * 189 * @return The error message, or <jk>null</jk> if none. 190 */ 191 public String getError() { 192 return error; 193 } 194 195 /** 196 * Sets the optional error message. 197 * 198 * @param value The value. 199 * @return This object. 200 */ 201 public DataTablesResults<T> setError(String value) { 202 this.error = value; 203 return this; 204 } 205}