SortKey.java
/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions Copyrighted [year] [name of copyright owner]".
*
* Copyright 2012-2015 ForgeRock AS. All rights reserved.
*/
package org.forgerock.json.resource;
import static org.forgerock.util.Reject.checkNotNull;
import java.util.Arrays;
import org.forgerock.json.JsonException;
import org.forgerock.json.JsonPointer;
/**
* A sort key which can be used to specify the order in which JSON resources
* should be included in the results of a query request.
*/
public final class SortKey {
/**
* Creates a new ascending-order sort key for the provided JSON field.
*
* @param field
* The sort key field.
* @return A new ascending-order sort key.
*/
public static SortKey ascendingOrder(final JsonPointer field) {
return new SortKey(field, true);
}
/**
* Creates a new ascending-order sort key for the provided JSON field.
*
* @param field
* The sort key field.
* @return A new ascending-order sort key.
* @throws IllegalArgumentException
* If {@code field} is not a valid JSON pointer.
*/
public static SortKey ascendingOrder(final String field) {
try {
return ascendingOrder(new JsonPointer(field));
} catch (JsonException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
/**
* Creates a new descending-order sort key for the provided JSON field.
*
* @param field
* The sort key field.
* @return A new descending-order sort key.
*/
public static SortKey descendingOrder(final JsonPointer field) {
return new SortKey(field, false);
}
/**
* Creates a new descending-order sort key for the provided JSON field.
*
* @param field
* The sort key field.
* @return A new descending-order sort key.
* @throws IllegalArgumentException
* If {@code field} is not a valid JSON pointer.
*/
public static SortKey descendingOrder(final String field) {
try {
return descendingOrder(new JsonPointer(field));
} catch (JsonException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
/**
* Creates a new sort key having the same field as the provided key, but in
* reverse sort order.
*
* @param key
* The sort key to be reversed.
* @return The reversed sort key.
*/
public static SortKey reverseOrder(final SortKey key) {
return new SortKey(key.field, !key.isAscendingOrder);
}
private final JsonPointer field;
private final boolean isAscendingOrder;
private SortKey(final JsonPointer field, final boolean isAscendingOrder) {
this.field = checkNotNull(field, "SortKey field cannot be null");
this.isAscendingOrder = isAscendingOrder;
}
/**
* Returns the sort key field.
*
* @return The sort key field.
*/
public JsonPointer getField() {
return field;
}
/**
* Returns {@code true} if this sort key is in ascending order, or
* {@code false} if it is in descending order.
*
* @return {@code true} if this sort key is in ascending order, or
* {@code false} if it is in descending ord)er.
*/
public boolean isAscendingOrder() {
return isAscendingOrder;
}
/**
* Parses the provided string as a sort key. If the string does not begin
* with a plus or minus symbol, then the sort key will default to ascending
* order.
*
* @param s
* The string representation of a sort key as specified in
* {@link #toString()}.
* @return The parsed sort key.
* @throws IllegalArgumentException
* If {@code s} is not a valid sort key.
*/
public static SortKey valueOf(String s) {
if (s.length() == 0) {
throw new IllegalArgumentException("Empty sort key");
}
switch (s.charAt(0)) {
case '-':
return descendingOrder(s.substring(1));
case '+':
return ascendingOrder(s.substring(1));
default:
return ascendingOrder(s);
}
}
/**
* Returns the string representation of this sort key. It will be composed
* of a plus symbol, if the key is ascending, or a minus symbol, if the key
* is descending, followed by the field name.
*
* @return The string representation of this sort key.
*/
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append(isAscendingOrder ? '+' : '-');
builder.append(field);
return builder.toString();
}
@Override
public boolean equals(Object obj) {
return obj instanceof SortKey
&& ((SortKey) obj).isAscendingOrder() == isAscendingOrder()
&& ((SortKey) obj).getField().equals(getField());
}
@Override
public int hashCode() {
return Arrays.hashCode(new Object[] { isAscendingOrder, field });
}
}