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.rest.converter; 018 019import org.apache.juneau.*; 020import org.apache.juneau.objecttools.*; 021import org.apache.juneau.rest.*; 022import org.apache.juneau.rest.httppart.*; 023 024/** 025 * Converter for enabling of search/view/sort/page support on response objects returned by a <c>@RestOp</c>-annotated method. 026 * 027 * <p> 028 * When enabled, objects in a POJO tree can be filtered using the functionality described in the {@link ObjectSearcher}, 029 * {@link ObjectViewer}, {@link ObjectSorter}, and {@link ObjectPaginator} classes. 030 * 031 * <p> 032 * The following HTTP request parameters are available for tabular data (e.g. {@code Collections} of {@code Maps}, 033 * arrays of beans, etc...): 034 * <ul class='spaced-list'> 035 * <li> 036 * <c>&s=</c> Search arguments. 037 * <br>Comma-delimited list of key/value pairs representing column names and search tokens. 038 * <br>Example: 039 * <p class='burlenc'> 040 * &s=name=Bill*,birthDate>2000 041 * </p> 042 * <li> 043 * <c>&v=</c> Visible columns. 044 * <br>Comma-delimited list of column names to display. 045 * <br>Example: 046 * <p class='burlenc'> 047 * &v=name,birthDate 048 * </p> 049 * <li> 050 * <c>&o=</c> Sort commands. 051 * <br>Comma-delimited list of columns to sort by. 052 * <br>Column names can be suffixed with <js>'+'</js> or <js>'-'</js> to indicate ascending or descending order. 053 * <br>The default is ascending order. 054 * <br>Example: 055 * <p class='burlenc'> 056 * &o=name,birthDate- 057 * </p> 058 * <li> 059 * <c>&i=</c> Case-insensitive parameter. 060 * <br>Boolean flag for case-insensitive matching on the search parameters. 061 * <li> 062 * <c>&p=</c> - Position parameter. 063 * <br>Only return rows starting at the specified index position (zero-indexed). 064 * <br>Default is {@code 0}. 065 * <li> 066 * <c>&l=</c> Limit parameter. 067 * <br>Only return the specified number of rows. 068 * <br>Default is {@code 0} (meaning return all rows). 069 * </ul> 070 * 071 * <h5 class='section'>See Also:</h5><ul> 072 * <li class='jc'>{@link ObjectSearcher} - Additional information on searching POJO models. 073 * <li class='jc'>{@link ObjectViewer} - Additional information on filtering POJO models. 074 * <li class='jc'>{@link ObjectSorter} - Additional information on sorting POJO models. 075 * <li class='jc'>{@link ObjectPaginator} - Additional information on paginating POJO models. 076 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#converters()} - Registering converters with REST resources. 077 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Converters">Converters</a> 078 * </ul> 079 */ 080public class Queryable implements RestConverter { 081 082 /** 083 * Swagger parameters for this converter. 084 */ 085 public static final String SWAGGER_PARAMS="" 086 + "{" 087 + "in:'query'," 088 + "name:'s'," 089 + "description:'" 090 + "Search.\n" 091 + "Key/value pairs representing column names and search tokens.\n" 092 + "\\'*\\' and \\'?\\' can be used as meta-characters in string fields.\n" 093 + "\\'>\\', \\'>=\\', \\'<\\', and \\'<=\\' can be used as limits on numeric and date fields.\n" 094 + "Date fields can be matched with partial dates (e.g. \\'2018\\' to match any date in the year 2018)." 095 + "'," 096 + "type:'array'," 097 + "collectionFormat:'csv'," 098 + "examples:{example:'?s=Bill*,birthDate>2000'}" 099 + "}," 100 + "{" 101 + "in:'query'," 102 + "name:'v'," 103 + "description:'" 104 + "View.\n" 105 + "Column names to display." 106 + "'," 107 + "type:'array'," 108 + "collectionFormat:'csv'," 109 + "examples:{example:'?v=name,birthDate'}" 110 + "}," 111 + "{" 112 + "in:'query'," 113 + "name:'o'," 114 + "description:'" 115 + "Order by.\n" 116 + "Columns to sort by.\n" 117 + "Column names can be suffixed with \\'+\\' or \\'-\\' to indicate ascending or descending order.\n" 118 + "The default is ascending order." 119 + "'," 120 + "type:'array'," 121 + "collectionFormat:'csv'," 122 + "examples:{example:'?o=name,birthDate-'}" 123 + "}," 124 + "{" 125 + "in:'query'," 126 + "name:'p'," 127 + "description:'" 128 + "Position.\n" 129 + "Only return rows starting at the specified index position (zero-indexed).\n" 130 + "Default is 0" 131 + "'," 132 + "type:'integer'," 133 + "examples:{example:'?p=100'}" 134 + "}," 135 + "{" 136 + "in:'query'," 137 + "name:'l'," 138 + "description:'" 139 + "Limit.\n" 140 + "Only return the specified number of rows.\n" 141 + "Default is 0 (meaning return all rows)." 142 + "'," 143 + "type:'integer'," 144 + "examples:{example:'?l=100'}" 145 + "}" 146 ; 147 148 @Override /* RestConverter */ 149 public Object convert(RestRequest req, Object o) { 150 if (o == null) 151 return null; 152 153 Value<Object> v = Value.of(o); 154 RequestQueryParams params = req.getQueryParams(); 155 BeanSession bs = req.getBeanSession(); 156 157 params.getSearchArgs().ifPresent(x -> v.set(ObjectSearcher.create().run(bs, v.get(), x))); 158 params.getSortArgs().ifPresent(x -> v.set(ObjectSorter.create().run(bs, v.get(), x))); 159 params.getViewArgs().ifPresent(x -> v.set(ObjectViewer.create().run(bs, v.get(), x))); 160 params.getPageArgs().ifPresent(x -> v.set(ObjectPaginator.create().run(bs, v.get(), x))); 161 return v.get(); 162 } 163}