001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyrighted [year] [name of copyright owner]". 013 * 014 * Copyright 2012-2015 ForgeRock AS. All rights reserved. 015 */ 016 017package org.forgerock.json.resource; 018 019import org.forgerock.json.JsonException; 020import org.forgerock.json.JsonPointer; 021 022/** 023 * A sort key which can be used to specify the order in which JSON resources 024 * should be included in the results of a query request. 025 */ 026public final class SortKey { 027 028 /** 029 * Creates a new ascending-order sort key for the provided JSON field. 030 * 031 * @param field 032 * The sort key field. 033 * @return A new ascending-order sort key. 034 */ 035 public static SortKey ascendingOrder(final JsonPointer field) { 036 return new SortKey(field, true); 037 } 038 039 /** 040 * Creates a new ascending-order sort key for the provided JSON field. 041 * 042 * @param field 043 * The sort key field. 044 * @return A new ascending-order sort key. 045 * @throws IllegalArgumentException 046 * If {@code field} is not a valid JSON pointer. 047 */ 048 public static SortKey ascendingOrder(final String field) { 049 try { 050 return ascendingOrder(new JsonPointer(field)); 051 } catch (JsonException e) { 052 throw new IllegalArgumentException(e.getMessage()); 053 } 054 } 055 056 /** 057 * Creates a new descending-order sort key for the provided JSON field. 058 * 059 * @param field 060 * The sort key field. 061 * @return A new descending-order sort key. 062 */ 063 public static SortKey descendingOrder(final JsonPointer field) { 064 return new SortKey(field, false); 065 } 066 067 /** 068 * Creates a new descending-order sort key for the provided JSON field. 069 * 070 * @param field 071 * The sort key field. 072 * @return A new descending-order sort key. 073 * @throws IllegalArgumentException 074 * If {@code field} is not a valid JSON pointer. 075 */ 076 public static SortKey descendingOrder(final String field) { 077 try { 078 return descendingOrder(new JsonPointer(field)); 079 } catch (JsonException e) { 080 throw new IllegalArgumentException(e.getMessage()); 081 } 082 } 083 084 /** 085 * Creates a new sort key having the same field as the provided key, but in 086 * reverse sort order. 087 * 088 * @param key 089 * The sort key to be reversed. 090 * @return The reversed sort key. 091 */ 092 public static SortKey reverseOrder(final SortKey key) { 093 return new SortKey(key.field, !key.isAscendingOrder); 094 } 095 096 private final JsonPointer field; 097 098 private final boolean isAscendingOrder; 099 100 private SortKey(final JsonPointer field, final boolean isAscendingOrder) { 101 this.field = field; 102 this.isAscendingOrder = isAscendingOrder; 103 } 104 105 /** 106 * Returns the sort key field. 107 * 108 * @return The sort key field. 109 */ 110 public JsonPointer getField() { 111 return field; 112 } 113 114 /** 115 * Returns {@code true} if this sort key is in ascending order, or 116 * {@code false} if it is in descending order. 117 * 118 * @return {@code true} if this sort key is in ascending order, or 119 * {@code false} if it is in descending ord)er. 120 */ 121 public boolean isAscendingOrder() { 122 return isAscendingOrder; 123 } 124 125 /** 126 * Parses the provided string as a sort key. If the string does not begin 127 * with a plus or minus symbol, then the sort key will default to ascending 128 * order. 129 * 130 * @param s 131 * The string representation of a sort key as specified in 132 * {@link #toString()}. 133 * @return The parsed sort key. 134 * @throws IllegalArgumentException 135 * If {@code s} is not a valid sort key. 136 */ 137 public static SortKey valueOf(String s) { 138 if (s.length() == 0) { 139 throw new IllegalArgumentException("Empty sort key"); 140 } 141 142 switch (s.charAt(0)) { 143 case '-': 144 return descendingOrder(s.substring(1)); 145 case '+': 146 return ascendingOrder(s.substring(1)); 147 default: 148 return ascendingOrder(s); 149 } 150 } 151 152 /** 153 * Returns the string representation of this sort key. It will be composed 154 * of a plus symbol, if the key is ascending, or a minus symbol, if the key 155 * is descending, followed by the field name. 156 * 157 * @return The string representation of this sort key. 158 */ 159 public String toString() { 160 final StringBuilder builder = new StringBuilder(); 161 builder.append(isAscendingOrder ? '+' : '-'); 162 builder.append(field); 163 return builder.toString(); 164 } 165}