All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.ebean.OrderBy Maven / Gradle / Ivy

There is a newer version: 15.8.0
Show newest version
package io.ebean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Represents an Order By for a Query.
 * 

* Is an ordered list of OrderBy.Property objects each specifying a property and * whether it is ascending or descending order. *

* Typically, you will not construct an OrderBy yourself but use one that exists * on the Query object. */ public class OrderBy implements Serializable { private static final long serialVersionUID = 9157089257745730539L; private transient Query query; private final List list; /** * Create an OrderBy parsing the given order by clause. *

* The order by clause follows SQL order by clause with comma's between each * property and optionally "asc" or "desc" to represent ascending or * descending order respectively. */ public static

OrderBy

of(String orderByClause) { return new OrderBy<>(orderByClause); } /** * @deprecated This method will be removed from public API. *

* Create an empty OrderBy with no associated query. */ @Deprecated(forRemoval = true) public OrderBy() { this.list = new ArrayList<>(3); } private OrderBy(List list) { this.list = list; } /** * @deprecated migrate to {@link OrderBy#of(String)}. */ @Deprecated(forRemoval = true) public OrderBy(String orderByClause) { this(null, orderByClause); } /** * @deprecated This method will be removed from public API. */ @Deprecated(forRemoval = true) public OrderBy(Query query, String orderByClause) { this.query = query; this.list = new ArrayList<>(3); parse(orderByClause); } /** * Reverse the ascending/descending order on all the properties. */ public void reverse() { for (Property aList : list) { aList.reverse(); } } /** * Add a property with ascending order to this OrderBy. */ public Query asc(String propertyName) { list.add(new Property(propertyName, true)); return query; } /** * Add a property with ascending order to this OrderBy. */ public Query asc(String propertyName, String collation) { list.add(new Property(propertyName, true, collation)); return query; } /** * Add a property with descending order to this OrderBy. */ public Query desc(String propertyName) { list.add(new Property(propertyName, false)); return query; } /** * Add a property with descending order to this OrderBy. */ public Query desc(String propertyName, String collation) { list.add(new Property(propertyName, false, collation)); return query; } /** * Return true if the property is known to be contained in the order by clause. */ public boolean containsProperty(String propertyName) { for (Property aList : list) { if (propertyName.equals(aList.getProperty())) { return true; } } return false; } /** * @deprecated This method will become internal only API. *

* Return a copy of this OrderBy with the path trimmed. */ @Deprecated(forRemoval = true) public OrderBy copyWithTrim(String path) { List newList = new ArrayList<>(list.size()); for (Property aList : list) { newList.add(aList.copyWithTrim(path)); } return new OrderBy<>(newList); } /** * Return the properties for this OrderBy. */ public List getProperties() { // not returning an Immutable list at this point return list; } /** * Return true if this OrderBy does not have any properties. */ public boolean isEmpty() { return list.isEmpty(); } /** * Return the associated query if there is one. */ public Query getQuery() { return query; } /** * Associate this OrderBy with a query. */ public void setQuery(Query query) { this.query = query; } /** * Return a copy of the OrderBy. */ public OrderBy copy() { OrderBy copy = new OrderBy<>(); for (Property property : list) { copy.add(property.copy()); } return copy; } /** * Add to the order by by parsing a raw expression. */ public void add(String rawExpression) { parse(rawExpression); } /** * Add a property to the order by. */ public void add(Property p) { list.add(p); } @Override public String toString() { return list.toString(); } /** * Returns the OrderBy in string format. */ public String toStringFormat() { if (list.isEmpty()) { return null; } var append = new StringAppend(); for (int i = 0; i < list.size(); i++) { Property property = list.get(i); if (i > 0) { append.append(", "); } property.toStringFormat(append); } return append.toString(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof OrderBy)) { return false; } OrderBy e = (OrderBy) obj; return e.list.equals(list); } /** * Return a hash value for this OrderBy. This can be to determine logical * equality for OrderBy clauses. */ @Override public int hashCode() { return list.hashCode(); } /** * Clear the orderBy removing any current order by properties. *

* This is intended to be used when some code creates a query with a * 'default' order by clause and some other code may clear the 'default' * order by clause and replace. *

*/ public OrderBy clear() { list.clear(); return this; } /** * Append the order by clause. */ public interface Append { /** * Append a property expression. */ Append property(String property); /** * Append a literal. */ Append append(String literal); /** * Parse and append an expression. */ Append parse(String expression); } private static final class StringAppend implements Append { private final StringBuilder builder = new StringBuilder(); @Override public String toString() { return builder.toString(); } @Override public Append property(String property) { builder.append(property); return this; } @Override public Append append(String literal) { builder.append(literal); return this; } @Override public Append parse(String raw) { builder.append(raw); return this; } } /** * A property and its ascending descending order. */ public static class Property implements Serializable { private static final long serialVersionUID = 1546009780322478077L; private String property; private boolean ascending; private String collation; private String nulls; private String highLow; public Property(String property, boolean ascending) { this.property = property; this.ascending = ascending; } public Property(String property, boolean ascending, String nulls, String highLow) { this.property = property; this.ascending = ascending; this.nulls = nulls; this.highLow = highLow; } public Property(String property, boolean ascending, String collation) { this.property = property; this.ascending = ascending; this.collation = collation; } public Property(String property, boolean ascending, String collation, String nulls, String highLow) { this.property = property; this.ascending = ascending; this.collation = collation; this.nulls = nulls; this.highLow = highLow; } /** * Return a copy of this Property with the path trimmed. */ public Property copyWithTrim(String path) { return new Property(property.substring(path.length() + 1), ascending, collation, nulls, highLow); } @Override public int hashCode() { int hc = property.hashCode(); hc = hc * 92821 + (ascending ? 0 : 1); hc = hc * 92821 + (collation == null ? 0 : collation.hashCode()); hc = hc * 92821 + (nulls == null ? 0 : nulls.hashCode()); hc = hc * 92821 + (highLow == null ? 0 : highLow.hashCode()); return hc; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof Property)) { return false; } Property e = (Property) obj; if (ascending != e.ascending) return false; if (!property.equals(e.property)) return false; if (!Objects.equals(collation, e.collation)) return false; if (!Objects.equals(nulls, e.nulls)) return false; return Objects.equals(highLow, e.highLow); } @Override public String toString() { return property; } public void toStringFormat(Append append) { if (collation != null) { if (collation.contains("${}")) { // this is a complex collation, e.g. DB2 - we must replace the property append.parse(collation.replace("${}", property)); } else { append.property(property).append(" collate ").append(collation); } } else { append.property(property); } if (!ascending) { append.append(" desc"); } if (nulls != null) { append.append(" ").append(nulls).append(" ").append(highLow); } } /** * Reverse the ascending/descending order for this property. */ public void reverse() { this.ascending = !ascending; } /** * Trim off the pathPrefix. */ public void trim(String pathPrefix) { property = property.substring(pathPrefix.length() + 1); } /** * Return a copy of this property. */ public Property copy() { return new Property(property, ascending, collation, nulls, highLow); } /** * Return the property name. */ public String getProperty() { return property; } /** * Set the property name. */ public void setProperty(String property) { this.property = property; } /** * Return true if the order is ascending. */ public boolean isAscending() { return ascending; } /** * Set to true if the order is ascending. */ public void setAscending(boolean ascending) { this.ascending = ascending; } } private void parse(String orderByClause) { if (orderByClause == null) { return; } for (String chunk : orderByClause.split(",")) { Property p = parseProperty(chunk); if (p != null) { list.add(p); } } } private Property parseProperty(String chunk) { String[] pairs = chunk.split(" "); if (pairs.length == 0) { return null; } ArrayList wordList = new ArrayList<>(pairs.length); for (String pair : pairs) { if (!isEmptyString(pair)) { wordList.add(pair); } } if (wordList.isEmpty()) { return null; } if (wordList.size() == 1) { return new Property(wordList.get(0), true); } if (wordList.size() == 2) { boolean asc = isAscending(wordList.get(1)); return new Property(wordList.get(0), asc); } if (wordList.size() == 4) { // nulls high or nulls low as 3rd and 4th boolean asc = isAscending(wordList.get(1)); return new Property(wordList.get(0), asc, wordList.get(2), wordList.get(3)); } return new Property(chunk.trim(), true); } private boolean isAscending(String s) { s = s.toLowerCase(); if (s.startsWith("asc")) { return true; } if (s.startsWith("desc")) { return false; } throw new RuntimeException("Expecting [" + s + "] to be asc or desc?"); } private boolean isEmptyString(String s) { return s == null || s.isEmpty(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy