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

com.avaje.ebean.OrderBy Maven / Gradle / Ivy

package com.avaje.ebean;

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

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

* Is a 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 final class OrderBy implements Serializable { private static final long serialVersionUID = 9157089257745730539L; private transient Query query; private final List list; /** * Create an empty OrderBy with no associated query. */ public OrderBy() { this.list = new ArrayList(3); } private OrderBy(List list) { this.list = list; } /** * Create an orderBy parsing the 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 OrderBy(String orderByClause) { this(null, orderByClause); } /** * Construct with a given query and order by clause. */ 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 (int i = 0; i < list.size(); i++) { list.get(i).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 descending order to this OrderBy. */ public Query desc(String propertyName) { list.add(new Property(propertyName, false)); return query; } /** * Return true if the property is known to be contained in the order by clause. */ public boolean containsProperty(String propertyName) { for (int i = 0; i < list.size(); i++) { if (propertyName.equals(list.get(i).getProperty())) { return true; } } return false; } /** * Return a copy of this OrderBy with the path trimmed. */ public OrderBy copyWithTrim(String path) { List newList = new ArrayList(list.size()); for (int i = 0; i < list.size(); i++) { newList.add(list.get(i).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 (int i = 0; i < list.size(); i++) { copy.add(list.get(i).copy()); } return copy; } /** * Add a property to the order by. */ public void add(Property p) { list.add(p); } public String toString() { return list.toString(); } /** * Returns the OrderBy in string format. */ public String toStringFormat() { if (list.isEmpty()) { return null; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.size(); i++) { Property property = list.get(i); if (i > 0) { sb.append(", "); } sb.append(property.toStringFormat()); } return sb.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. */ 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 void clear() { list.clear(); } /** * A property and its ascending descending order. */ public static final class Property implements Serializable { private static final long serialVersionUID = 1546009780322478077L; private String property; private boolean ascending; 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; } /** * Return a copy of this Property with the path trimmed. */ public Property copyWithTrim(String path) { return new Property(property.substring(path.length() + 1), ascending, nulls, highLow); } @Override public int hashCode() { int hc = property.hashCode(); hc = hc * 31 + (ascending ? 0 : 1); hc = hc * 31 + (nulls == null ? 0 : nulls.hashCode()); hc = hc * 31 + (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 (nulls != null ? !nulls.equals(e.nulls) : e.nulls != null) return false; return highLow != null ? highLow.equals(e.highLow) : e.highLow == null; } public String toString() { return toStringFormat(); } public String toStringFormat() { if (nulls == null) { if (ascending) { return property; } else { return property + " desc"; } } else { StringBuilder sb = new StringBuilder(); sb.append(property); if (!ascending) { sb.append(" ").append("desc"); } sb.append(" ").append(nulls).append(" ").append(highLow); return sb.toString(); } } /** * 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, 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; } String[] chunks = orderByClause.split(","); for (int i = 0; i < chunks.length; i++) { String[] pairs = chunks[i].split(" "); Property p = parseProperty(pairs); if (p != null) { list.add(p); } } } private Property parseProperty(String[] pairs) { if (pairs.length == 0) { return null; } ArrayList wordList = new ArrayList(pairs.length); for (int i = 0; i < pairs.length; i++) { if (!isEmptyString(pairs[i])) { wordList.add(pairs[i]); } } 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)); } String m = "Expecting a 1, 2 or 4 words in [" + Arrays.toString(pairs) + "] but got " + wordList; throw new RuntimeException(m); } private boolean isAscending(String s) { s = s.toLowerCase(); if (s.startsWith("asc")) { return true; } if (s.startsWith("desc")) { return false; } String m = "Expecting [" + s + "] to be asc or desc?"; throw new RuntimeException(m); } private boolean isEmptyString(String s) { return s == null || s.length() == 0; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy