From 176197513dfd1d3dce51cfabf80cd51c86eb4d54 Mon Sep 17 00:00:00 2001
From: rbygrave
Date: Wed, 9 Jul 2014 23:51:19 +1200
Subject: [PATCH] No effective change - format only
---
.../server/querydefn/DefaultOrmQuery.java | 1972 ++++++++---------
.../server/querydefn/DefaultOrmUpdate.java | 3 +-
.../querydefn/DefaultRelationalQuery.java | 4 +-
.../server/querydefn/NaturalKeyBindParam.java | 30 +-
.../server/querydefn/OrmQueryDetail.java | 801 ++++---
.../querydefn/OrmQueryDetailParser.java | 320 ++-
.../querydefn/OrmQueryLimitRequest.java | 44 +-
.../server/querydefn/OrmQueryProperties.java | 1096 +++++----
.../server/querydefn/SimpleTextParser.java | 288 +--
9 files changed, 2270 insertions(+), 2288 deletions(-)
diff --git a/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java
index 41b497550..a9d08db0d 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java
@@ -54,79 +54,79 @@ import com.avaje.ebeaninternal.util.DefaultExpressionList;
*/
public class DefaultOrmQuery implements SpiQuery {
- private static final long serialVersionUID = 6838006264714672460L;
+ private static final long serialVersionUID = 6838006264714672460L;
- private final Class beanType;
-
- private transient final EbeanServer server;
-
- private transient BeanCollectionTouched beanCollectionTouched;
-
- private transient final ExpressionFactory expressionFactory;
-
- /**
- * Used to add beans to the PersistanceContext prior to query.
- */
- private transient ArrayList contextAdditions;
-
- /**
- * For lazy loading of ManyToMany we need to add a join to the intersection
- * table. This is that join to the intersection table.
- */
- private transient TableJoin includeTableJoin;
+ private final Class beanType;
- private transient AutoFetchManager autoFetchManager;
+ private transient final EbeanServer server;
- private transient BeanDescriptor> beanDescriptor;
-
- private boolean cancelled;
-
- private transient CancelableQuery cancelableQuery;
-
- /**
- * The name of the query.
- */
- private String name;
-
- private Type type;
-
- private Mode mode = Mode.NORMAL;
-
- /**
- * Holds query in structured form.
- */
- private OrmQueryDetail detail;
+ private transient BeanCollectionTouched beanCollectionTouched;
- private int maxRows;
+ private transient final ExpressionFactory expressionFactory;
- private int firstRow;
+ /**
+ * Used to add beans to the PersistanceContext prior to query.
+ */
+ private transient ArrayList contextAdditions;
- private int totalHits;
-
- /**
- * The where clause from a parsed query string.
- */
- private String rawWhereClause;
-
- private OrderBy orderBy;
+ /**
+ * For lazy loading of ManyToMany we need to add a join to the intersection table. This is that
+ * join to the intersection table.
+ */
+ private transient TableJoin includeTableJoin;
- private String loadMode;
-
- private String loadDescription;
-
- private String generatedSql;
+ private transient AutoFetchManager autoFetchManager;
- /**
- * Query language version of the query.
- */
- private String query;
+ private transient BeanDescriptor> beanDescriptor;
- private String additionalWhere;
+ private boolean cancelled;
- private String additionalHaving;
+ private transient CancelableQuery cancelableQuery;
+
+ /**
+ * The name of the query.
+ */
+ private String name;
+
+ private Type type;
+
+ private Mode mode = Mode.NORMAL;
+
+ /**
+ * Holds query in structured form.
+ */
+ private OrmQueryDetail detail;
+
+ private int maxRows;
+
+ private int firstRow;
+
+ private int totalHits;
+
+ /**
+ * The where clause from a parsed query string.
+ */
+ private String rawWhereClause;
+
+ private OrderBy orderBy;
+
+ private String loadMode;
+
+ private String loadDescription;
+
+ private String generatedSql;
+
+ /**
+ * Query language version of the query.
+ */
+ private String query;
+
+ private String additionalWhere;
+
+ private String additionalHaving;
+
+ private String lazyLoadProperty;
- private String lazyLoadProperty;
-
private String lazyLoadManyPath;
/**
@@ -134,397 +134,398 @@ public class DefaultOrmQuery implements SpiQuery {
*/
private boolean distinct;
- /**
- * Set to true internally by Ebean when it needs the DISTINCT keyword added to the query (id property still expected).
- */
- private boolean sqlDistinct;
-
- /**
- * Set to true if this is a future fetch using background threads.
- */
- private boolean futureFetch;
-
- private List
*
- * It is worth noting that for autoFetch a "tuned fetch info" builds an instance
- * of OrmQueryDetail. Tuning a query is a matter of replacing an instance of
- * this class with one that has been tuned with select() and join() set.
+ * It is worth noting that for autoFetch a "tuned fetch info" builds an instance of OrmQueryDetail.
+ * Tuning a query is a matter of replacing an instance of this class with one that has been tuned
+ * with select() and join() set.
*
*/
public class OrmQueryDetail implements Serializable {
- private static final long serialVersionUID = -2510486880141461807L;
+ private static final long serialVersionUID = -2510486880141461807L;
- /**
- * Root level properties.
- */
- private OrmQueryProperties baseProps = new OrmQueryProperties();
+ /**
+ * Root level properties.
+ */
+ private OrmQueryProperties baseProps = new OrmQueryProperties();
- /**
- * Contains the fetch/lazy/query joins and their properties.
- */
- private LinkedHashMap fetchPaths = new LinkedHashMap(8);
+ /**
+ * Contains the fetch/lazy/query joins and their properties.
+ */
+ private LinkedHashMap fetchPaths = new LinkedHashMap(8);
- private LinkedHashSet includes = new LinkedHashSet(8);
+ private LinkedHashSet includes = new LinkedHashSet(8);
- /**
- * Return a deep copy of the OrmQueryDetail.
- */
- public OrmQueryDetail copy() {
- OrmQueryDetail copy = new OrmQueryDetail();
- copy.baseProps = baseProps.copy();
- for (Map.Entry entry : fetchPaths.entrySet()) {
- copy.fetchPaths.put(entry.getKey(), entry.getValue().copy());
- }
- copy.includes = new LinkedHashSet(includes);
- return copy;
+ /**
+ * Return a deep copy of the OrmQueryDetail.
+ */
+ public OrmQueryDetail copy() {
+ OrmQueryDetail copy = new OrmQueryDetail();
+ copy.baseProps = baseProps.copy();
+ for (Map.Entry entry : fetchPaths.entrySet()) {
+ copy.fetchPaths.put(entry.getKey(), entry.getValue().copy());
+ }
+ copy.includes = new LinkedHashSet(includes);
+ return copy;
+ }
+
+ /**
+ * Calculate the hash for the query plan.
+ */
+ public void queryPlanHash(BeanQueryRequest> request, HashQueryPlanBuilder builder) {
+ if (baseProps == null) {
+ builder.add(false);
+ } else {
+ builder.add(true);
+ baseProps.queryPlanHash(request, builder);
}
- /**
- * Calculate the hash for the query plan.
- */
- public void queryPlanHash(BeanQueryRequest> request, HashQueryPlanBuilder builder) {
- if (baseProps == null) {
- builder.add(false);
+ if (fetchPaths != null) {
+ for (OrmQueryProperties p : fetchPaths.values()) {
+ p.queryPlanHash(request, builder);
+ }
+ }
+ }
+
+ /**
+ * Return true if equal in terms of autofetch (select and joins).
+ */
+ public boolean isAutoFetchEqual(OrmQueryDetail otherDetail) {
+ return autofetchPlanHash() == otherDetail.autofetchPlanHash();
+ }
+
+ /**
+ * Calculate the hash for the query plan.
+ */
+ private int autofetchPlanHash() {
+
+ int hc = (baseProps == null ? 1 : baseProps.autofetchPlanHash());
+
+ if (fetchPaths != null) {
+ for (OrmQueryProperties p : fetchPaths.values()) {
+ hc = hc * 31 + p.autofetchPlanHash();
+ }
+ }
+
+ return hc;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (baseProps != null) {
+ sb.append("select ").append(baseProps);
+ }
+ if (fetchPaths != null) {
+ for (OrmQueryProperties join : fetchPaths.values()) {
+ sb.append(" fetch ").append(join);
+ }
+ }
+ return sb.toString();
+ }
+
+ public int hashCode() {
+ throw new RuntimeException("should not use");
+ }
+
+ /**
+ * set the properties to include on the base / root entity.
+ */
+ public void select(String columns) {
+ baseProps = new OrmQueryProperties(null, columns);
+ }
+
+ public boolean containsProperty(String property) {
+ if (baseProps == null) {
+ return true;
+ } else {
+ return baseProps.isIncluded(property);
+ }
+ }
+
+ /**
+ * Set the base / root query properties.
+ */
+ public void setBase(OrmQueryProperties baseProps) {
+ this.baseProps = baseProps;
+ }
+
+ public List removeSecondaryQueries() {
+ return removeSecondaryQueries(false);
+ }
+
+ public List removeSecondaryLazyQueries() {
+ return removeSecondaryQueries(true);
+ }
+
+ private List removeSecondaryQueries(boolean lazyQuery) {
+
+ ArrayList matchingPaths = new ArrayList(2);
+
+ for (OrmQueryProperties chunk : fetchPaths.values()) {
+ boolean match = lazyQuery ? chunk.isLazyFetch() : chunk.isQueryFetch();
+ if (match) {
+ matchingPaths.add(chunk.getPath());
+ }
+ }
+
+ if (matchingPaths.size() == 0) {
+ return null;
+ }
+
+ // sort into depth order to remove
+ Collections.sort(matchingPaths);
+
+ // the list of secondary queries
+ ArrayList props = new ArrayList(2);
+
+ for (int i = 0; i < matchingPaths.size(); i++) {
+ String path = matchingPaths.get(i);
+ includes.remove(path);
+ OrmQueryProperties secQuery = fetchPaths.remove(path);
+ if (secQuery == null) {
+ // the path has already been removed by another
+ // secondary query
+
} else {
- builder.add(true);
- baseProps.queryPlanHash(request, builder);
- }
-
- if (fetchPaths != null) {
- for (OrmQueryProperties p : fetchPaths.values()) {
- p.queryPlanHash(request, builder);
+ props.add(secQuery);
+
+ // remove any child properties for this path
+ Iterator pass2It = fetchPaths.values().iterator();
+ while (pass2It.hasNext()) {
+ OrmQueryProperties pass2Prop = pass2It.next();
+ if (secQuery.isChild(pass2Prop)) {
+ // remove join to secondary query from the main query
+ // and add to this secondary query
+ pass2It.remove();
+ includes.remove(pass2Prop.getPath());
+ secQuery.add(pass2Prop);
+ }
}
}
}
- /**
- * Return true if equal in terms of autofetch (select and joins).
- */
- public boolean isAutoFetchEqual(OrmQueryDetail otherDetail) {
- return autofetchPlanHash() == otherDetail.autofetchPlanHash();
+ // Add the secondary queries as select properties
+ // to the parent chunk to ensure the foreign keys
+ // are included in the query
+ for (int i = 0; i < props.size(); i++) {
+ String path = props.get(i).getPath();
+ // split into parent and property
+ String[] split = SplitName.split(path);
+ // add property to parent chunk
+ OrmQueryProperties chunk = getChunk(split[0], true);
+ chunk.addSecondaryQueryJoin(split[1]);
}
- /**
- * Calculate the hash for the query plan.
- */
- private int autofetchPlanHash() {
+ return props;
+ }
- int hc = (baseProps == null ? 1 : baseProps.autofetchPlanHash());
+ public boolean tuneFetchProperties(OrmQueryDetail tunedDetail) {
- if (fetchPaths != null) {
- for (OrmQueryProperties p : fetchPaths.values()) {
- hc = hc * 31 + p.autofetchPlanHash();
- }
- }
+ boolean tuned = false;
- return hc;
- }
+ OrmQueryProperties tunedRoot = tunedDetail.getChunk(null, false);
+ if (tunedRoot != null && tunedRoot.hasProperties()) {
+ tuned = true;
+ baseProps.setTunedProperties(tunedRoot);
- public String toString() {
- StringBuilder sb = new StringBuilder();
- if (baseProps != null) {
- sb.append("select ").append(baseProps);
- }
- if (fetchPaths != null) {
- for (OrmQueryProperties join : fetchPaths.values()) {
- sb.append(" fetch ").append(join);
- }
- }
- return sb.toString();
- }
-
- public int hashCode() {
- throw new RuntimeException("should not use");
- }
-
- /**
- * set the properties to include on the base / root entity.
- */
- public void select(String columns) {
- baseProps = new OrmQueryProperties(null, columns);
- }
-
- public boolean containsProperty(String property) {
- if (baseProps == null) {
- return true;
+ for (OrmQueryProperties tunedChunk : tunedDetail.fetchPaths.values()) {
+ OrmQueryProperties chunk = getChunk(tunedChunk.getPath(), false);
+ if (chunk != null) {
+ // set the properties to select
+ chunk.setTunedProperties(tunedChunk);
} else {
- return baseProps.isIncluded(property);
+ // add a missing join
+ putFetchPath(tunedChunk.copy());
}
+ }
+ }
+ return tuned;
+ }
+
+ /**
+ * Matches a join() method of the query.
+ */
+ public void putFetchPath(OrmQueryProperties chunk) {
+ String path = chunk.getPath();
+ fetchPaths.put(path, chunk);
+ includes.add(path);
+ }
+
+ /**
+ * Remove all joins and properties.
+ *
+ * Typically for the row count query.
+ *
+ */
+ public void clear() {
+ includes.clear();
+ fetchPaths.clear();
+ }
+
+ /**
+ * Set the fetch properties and configuration for a given path.
+ *
+ * @param path
+ * the property to join
+ * @param partialProps
+ * the properties on the join property to include
+ */
+ public OrmQueryProperties addFetch(String path, String partialProps, FetchConfig fetchConfig) {
+
+ OrmQueryProperties chunk = getChunk(path, true);
+ chunk.setProperties(partialProps);
+ chunk.setFetchConfig(fetchConfig);
+ return chunk;
+ }
+
+ public void sortFetchPaths(BeanDescriptor> d) {
+
+ LinkedHashMap sorted = new LinkedHashMap(fetchPaths.size());
+
+ for (OrmQueryProperties p : fetchPaths.values()) {
+ sortFetchPaths(d, p, sorted);
}
- /**
- * Set the base / root query properties.
- */
- public void setBase(OrmQueryProperties baseProps) {
- this.baseProps = baseProps;
- }
+ fetchPaths = sorted;
+ }
- public List removeSecondaryQueries() {
- return removeSecondaryQueries(false);
- }
+ private void sortFetchPaths(BeanDescriptor> d, OrmQueryProperties p,
+ LinkedHashMap sorted) {
- public List removeSecondaryLazyQueries() {
- return removeSecondaryQueries(true);
- }
-
- private List removeSecondaryQueries(boolean lazyQuery) {
-
- ArrayList matchingPaths = new ArrayList(2);
-
- for (OrmQueryProperties chunk : fetchPaths.values()) {
- boolean match = lazyQuery ? chunk.isLazyFetch() : chunk.isQueryFetch();
- if (match) {
- matchingPaths.add(chunk.getPath());
- }
+ String path = p.getPath();
+ if (!sorted.containsKey(path)) {
+ String parentPath = p.getParentPath();
+ if (parentPath == null || sorted.containsKey(parentPath)) {
+ // off root path or parent already ahead in fetch order
+ sorted.put(path, p);
+ } else {
+ OrmQueryProperties parentProp = fetchPaths.get(parentPath);
+ if (parentProp == null) {
+ ElPropertyValue el = d.getElGetValue(parentPath);
+ if (el == null) {
+ String msg = "Path [" + parentPath + "] not valid from " + d.getFullName();
+ throw new PersistenceException(msg);
+ }
+ // add a missing parent path just fetching the Id property
+ BeanPropertyAssoc> assocOne = (BeanPropertyAssoc>) el.getBeanProperty();
+ parentProp = new OrmQueryProperties(parentPath, assocOne.getTargetIdProperty());
}
-
- if (matchingPaths.size() == 0) {
- return null;
+ if (parentProp != null) {
+ sortFetchPaths(d, parentProp, sorted);
}
+ sorted.put(path, p);
+ }
+ }
+ }
- // sort into depth order to remove
- Collections.sort(matchingPaths);
+ /**
+ * Convert 'fetch joins' to 'many' properties over to 'query joins'.
+ */
+ public void convertManyFetchJoinsToQueryJoins(BeanDescriptor> beanDescriptor, String lazyLoadManyPath,
+ boolean allowOne, int queryBatch) {
- // the list of secondary queries
- ArrayList props = new ArrayList(2);
+ ArrayList manyChunks = new ArrayList(3);
- for (int i = 0; i < matchingPaths.size(); i++) {
- String path = matchingPaths.get(i);
- includes.remove(path);
- OrmQueryProperties secQuery = fetchPaths.remove(path);
- if (secQuery == null) {
- // the path has already been removed by another
- // secondary query
+ // the name of the many fetch property if there is one
+ String manyFetchProperty = null;
- } else {
- props.add(secQuery);
+ // flag that is set once the many fetch property is chosen
+ boolean fetchJoinFirstMany = allowOne;
- // remove any child properties for this path
- Iterator pass2It = fetchPaths.values().iterator();
- while (pass2It.hasNext()) {
- OrmQueryProperties pass2Prop = pass2It.next();
- if (secQuery.isChild(pass2Prop)) {
- // remove join to secondary query from the main query
- // and add to this secondary query
- pass2It.remove();
- includes.remove(pass2Prop.getPath());
- secQuery.add(pass2Prop);
- }
- }
- }
+ sortFetchPaths(beanDescriptor);
+
+ for (String fetchPath : fetchPaths.keySet()) {
+ ElPropertyDeploy elProp = beanDescriptor.getElPropertyDeploy(fetchPath);
+ if (elProp.containsManySince(manyFetchProperty)) {
+
+ // this is a join to a *ToMany
+ OrmQueryProperties chunk = fetchPaths.get(fetchPath);
+ if (chunk.isFetchJoin() && !isLazyLoadManyRoot(lazyLoadManyPath, chunk)
+ && !hasParentSecJoin(lazyLoadManyPath, chunk)) {
+ // this is a 'fetch join' (included in main query)
+ if (fetchJoinFirstMany) {
+ // letting the first one remain a 'fetch join'
+ fetchJoinFirstMany = false;
+ manyFetchProperty = fetchPath;
+ } else {
+ // convert this one over to a 'query join'
+ manyChunks.add(chunk);
+ }
}
-
- // Add the secondary queries as select properties
- // to the parent chunk to ensure the foreign keys
- // are included in the query
- for (int i = 0; i < props.size(); i++) {
- String path = props.get(i).getPath();
- // split into parent and property
- String[] split = SplitName.split(path);
- // add property to parent chunk
- OrmQueryProperties chunk = getChunk(split[0], true);
- chunk.addSecondaryQueryJoin(split[1]);
- }
-
- return props;
+ }
}
- public boolean tuneFetchProperties(OrmQueryDetail tunedDetail) {
-
- boolean tuned = false;
-
- OrmQueryProperties tunedRoot = tunedDetail.getChunk(null, false);
- if (tunedRoot != null && tunedRoot.hasProperties()) {
- tuned = true;
- baseProps.setTunedProperties(tunedRoot);
-
- for (OrmQueryProperties tunedChunk : tunedDetail.fetchPaths.values()) {
- OrmQueryProperties chunk = getChunk(tunedChunk.getPath(), false);
- if (chunk != null) {
- // set the properties to select
- chunk.setTunedProperties(tunedChunk);
- } else {
- // add a missing join
- putFetchPath(tunedChunk.copy());
- }
- }
- }
- return tuned;
+ for (int i = 0; i < manyChunks.size(); i++) {
+ // convert 'fetch joins' over to 'query joins'
+ manyChunks.get(i).setQueryFetch(queryBatch, true);
}
+ }
- /**
- * Matches a join() method of the query.
- */
- public void putFetchPath(OrmQueryProperties chunk) {
- String path = chunk.getPath();
- fetchPaths.put(path, chunk);
- includes.add(path);
+ /**
+ * Return true if this is actually the root level of a +query/+lazy loading query.
+ */
+ private boolean isLazyLoadManyRoot(String lazyLoadManyPath, OrmQueryProperties chunk) {
+ if (lazyLoadManyPath != null && lazyLoadManyPath.equals(chunk.getPath())) {
+ return true;
}
+ return false;
+ }
- /**
- * Remove all joins and properties.
- *
- * Typically for the row count query.
- *
- */
- public void clear() {
- includes.clear();
- fetchPaths.clear();
- }
-
- /**
- * Set the fetch properties and configuration for a given path.
- *
- * @param path
- * the property to join
- * @param partialProps
- * the properties on the join property to include
- */
- public OrmQueryProperties addFetch(String path, String partialProps, FetchConfig fetchConfig) {
-
- OrmQueryProperties chunk = getChunk(path, true);
- chunk.setProperties(partialProps);
- chunk.setFetchConfig(fetchConfig);
- return chunk;
- }
-
- public void sortFetchPaths(BeanDescriptor> d) {
-
- LinkedHashMap sorted = new LinkedHashMap(fetchPaths.size());
-
- for (OrmQueryProperties p : fetchPaths.values()) {
- sortFetchPaths(d, p, sorted);
- }
-
- fetchPaths = sorted;
- }
-
- private void sortFetchPaths(BeanDescriptor> d, OrmQueryProperties p,
- LinkedHashMap sorted) {
-
- String path = p.getPath();
- if (!sorted.containsKey(path)) {
- String parentPath = p.getParentPath();
- if (parentPath == null || sorted.containsKey(parentPath)) {
- // off root path or parent already ahead in fetch order
- sorted.put(path, p);
- } else {
- OrmQueryProperties parentProp = fetchPaths.get(parentPath);
- if (parentProp == null) {
- ElPropertyValue el = d.getElGetValue(parentPath);
- if (el == null) {
- String msg = "Path [" + parentPath + "] not valid from " + d.getFullName();
- throw new PersistenceException(msg);
- }
- // add a missing parent path just fetching the Id property
- BeanPropertyAssoc> assocOne = (BeanPropertyAssoc>) el.getBeanProperty();
- parentProp = new OrmQueryProperties(parentPath, assocOne.getTargetIdProperty());
- }
- if (parentProp != null) {
- sortFetchPaths(d, parentProp, sorted);
- }
- sorted.put(path, p);
- }
- }
- }
-
- /**
- * Convert 'fetch joins' to 'many' properties over to 'query joins'.
- */
- public void convertManyFetchJoinsToQueryJoins(BeanDescriptor> beanDescriptor, String lazyLoadManyPath,
- boolean allowOne, int queryBatch) {
-
- ArrayList manyChunks = new ArrayList(3);
-
- // the name of the many fetch property if there is one
- String manyFetchProperty = null;
-
- // flag that is set once the many fetch property is chosen
- boolean fetchJoinFirstMany = allowOne;
-
- sortFetchPaths(beanDescriptor);
-
- for (String fetchPath : fetchPaths.keySet()) {
- ElPropertyDeploy elProp = beanDescriptor.getElPropertyDeploy(fetchPath);
- if (elProp.containsManySince(manyFetchProperty)) {
-
- // this is a join to a *ToMany
- OrmQueryProperties chunk = fetchPaths.get(fetchPath);
- if (chunk.isFetchJoin()
- && !isLazyLoadManyRoot(lazyLoadManyPath, chunk)
- && !hasParentSecJoin(lazyLoadManyPath, chunk)) {
- // this is a 'fetch join' (included in main query)
- if (fetchJoinFirstMany) {
- // letting the first one remain a 'fetch join'
- fetchJoinFirstMany = false;
- manyFetchProperty = fetchPath;
- } else {
- // convert this one over to a 'query join'
- manyChunks.add(chunk);
- }
- }
- }
- }
-
- for (int i = 0; i < manyChunks.size(); i++) {
- // convert 'fetch joins' over to 'query joins'
- manyChunks.get(i).setQueryFetch(queryBatch, true);
- }
- }
-
- /**
- * Return true if this is actually the root level of a +query/+lazy loading
- * query.
- */
- private boolean isLazyLoadManyRoot(String lazyLoadManyPath, OrmQueryProperties chunk) {
- if (lazyLoadManyPath != null && lazyLoadManyPath.equals(chunk.getPath())) {
- return true;
- }
+ /**
+ * If the chunk has a parent that is a query or lazy join. In this case it does not need to be
+ * converted.
+ */
+ private boolean hasParentSecJoin(String lazyLoadManyPath, OrmQueryProperties chunk) {
+ OrmQueryProperties parent = getParent(chunk);
+ if (parent == null) {
+ return false;
+ } else {
+ if (lazyLoadManyPath != null && lazyLoadManyPath.equals(parent.getPath())) {
return false;
+ } else if (!parent.isFetchJoin()) {
+ return true;
+ } else {
+ return hasParentSecJoin(lazyLoadManyPath, parent);
+ }
+ }
+ }
+
+ /**
+ * Return the parent chunk.
+ */
+ private OrmQueryProperties getParent(OrmQueryProperties chunk) {
+ String parentPath = chunk.getParentPath();
+ return parentPath == null ? null : fetchPaths.get(parentPath);
+ }
+
+ /**
+ * Set any default select clauses for the main bean and any joins that have not explicitly defined
+ * a select clause.
+ *
+ * That is this will use FetchType.LAZY to exclude some properties by default.
+ *
+ */
+ public void setDefaultSelectClause(BeanDescriptor> desc) {
+
+ if (desc.hasDefaultSelectClause() && !hasSelectClause()) {
+ if (baseProps == null) {
+ baseProps = new OrmQueryProperties();
+ }
+ baseProps.setDefaultProperties(desc.getDefaultSelectClause(), desc.getDefaultSelectClauseSet());
}
- /**
- * If the chunk has a parent that is a query or lazy join. In this case it
- * does not need to be converted.
- */
- private boolean hasParentSecJoin(String lazyLoadManyPath, OrmQueryProperties chunk) {
- OrmQueryProperties parent = getParent(chunk);
- if (parent == null) {
- return false;
- } else {
- if (lazyLoadManyPath != null && lazyLoadManyPath.equals(parent.getPath())) {
- return false;
- } else if (!parent.isFetchJoin()) {
- return true;
- } else {
- return hasParentSecJoin(lazyLoadManyPath, parent);
- }
+ for (OrmQueryProperties joinProps : fetchPaths.values()) {
+ if (!joinProps.hasSelectClause()) {
+ BeanDescriptor> assocDesc = desc.getBeanDescriptor(joinProps.getPath());
+ if (assocDesc.hasDefaultSelectClause()) {
+ // use the default select clause
+ joinProps.setDefaultProperties(assocDesc.getDefaultSelectClause(), assocDesc.getDefaultSelectClauseSet());
}
+ }
}
+ }
- /**
- * Return the parent chunk.
- */
- private OrmQueryProperties getParent(OrmQueryProperties chunk) {
- String parentPath = chunk.getParentPath();
- return parentPath == null ? null : fetchPaths.get(parentPath);
+ public boolean hasSelectClause() {
+ return (baseProps != null && baseProps.hasSelectClause());
+ }
+
+ /**
+ * Return true if the query detail has neither select properties specified or any joins defined.
+ */
+ public boolean isEmpty() {
+ return fetchPaths.isEmpty() && (baseProps == null || !baseProps.hasProperties());
+ }
+
+ /**
+ * Return true if there are no joins.
+ */
+ public boolean isJoinsEmpty() {
+ return fetchPaths.isEmpty();
+ }
+
+ /**
+ * Add the explicit bean join.
+ *
+ * This is also used to Exclude the matching property from the parent select (aka remove the
+ * foreign key) because it is now included in it's on node in the SqlTree.
+ *
+ */
+ public void includeBeanJoin(String parentPath, String propertyName) {
+ OrmQueryProperties parentChunk = getChunk(parentPath, true);
+ parentChunk.includeBeanJoin(propertyName);
+ }
+
+ public OrmQueryProperties getChunk(String path, boolean create) {
+ if (path == null) {
+ return baseProps;
}
+ OrmQueryProperties props = fetchPaths.get(path);
+ if (create && props == null) {
+ props = new OrmQueryProperties(path);
+ putFetchPath(props);
+ return props;
- /**
- * Set any default select clauses for the main bean and any joins that have
- * not explicitly defined a select clause.
- *
- * That is this will use FetchType.LAZY to exclude some properties by
- * default.
- *
- */
- public void setDefaultSelectClause(BeanDescriptor> desc) {
-
- if (desc.hasDefaultSelectClause() && !hasSelectClause()) {
- if (baseProps == null) {
- baseProps = new OrmQueryProperties();
- }
- baseProps.setDefaultProperties(desc.getDefaultSelectClause(), desc.getDefaultSelectClauseSet());
- }
-
- for (OrmQueryProperties joinProps : fetchPaths.values()) {
- if (!joinProps.hasSelectClause()) {
- BeanDescriptor> assocDesc = desc.getBeanDescriptor(joinProps.getPath());
- if (assocDesc.hasDefaultSelectClause()) {
- // use the default select clause
- joinProps.setDefaultProperties(assocDesc.getDefaultSelectClause(), assocDesc.getDefaultSelectClauseSet());
- }
- }
- }
+ } else {
+ return props;
}
+ }
- public boolean hasSelectClause() {
- return (baseProps != null && baseProps.hasSelectClause());
- }
+ /**
+ * Return true if the property is included.
+ */
+ public boolean includes(String path) {
- /**
- * Return true if the query detail has neither select properties specified
- * or any joins defined.
- */
- public boolean isEmpty() {
- return fetchPaths.isEmpty() && (baseProps == null || !baseProps.hasProperties());
- }
+ OrmQueryProperties chunk = fetchPaths.get(path);
- /**
- * Return true if there are no joins.
- */
- public boolean isJoinsEmpty() {
- return fetchPaths.isEmpty();
- }
+ // may not have fetch properties if just +cache etc
+ return chunk != null && !chunk.isCache();
+ }
- /**
- * Add the explicit bean join.
- *
- * This is also used to Exclude the matching property from the parent select
- * (aka remove the foreign key) because it is now included in it's on node
- * in the SqlTree.
- *
- */
- public void includeBeanJoin(String parentPath, String propertyName) {
- OrmQueryProperties parentChunk = getChunk(parentPath, true);
- parentChunk.includeBeanJoin(propertyName);
- }
-
- public OrmQueryProperties getChunk(String path, boolean create) {
- if (path == null) {
- return baseProps;
- }
- OrmQueryProperties props = fetchPaths.get(path);
- if (create && props == null) {
- props = new OrmQueryProperties(path);
- putFetchPath(props);
- return props;
-
- } else {
- return props;
- }
- }
-
- /**
- * Return true if the property is included.
- */
- public boolean includes(String path) {
-
- OrmQueryProperties chunk = fetchPaths.get(path);
-
- // may not have fetch properties if just +cache etc
- return chunk != null && !chunk.isCache();
- }
-
- /**
- * Return the property includes for this detail.
- */
- public HashSet getIncludes() {
- return includes;
- }
+ /**
+ * Return the property includes for this detail.
+ */
+ public HashSet getIncludes() {
+ return includes;
+ }
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryDetailParser.java b/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryDetailParser.java
index fff9f9da6..b1dfbd5a8 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryDetailParser.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryDetailParser.java
@@ -3,198 +3,196 @@ package com.avaje.ebeaninternal.server.querydefn;
import javax.persistence.PersistenceException;
/**
- * Parses a Object relational query statement into a OrmQueryDetail and
- * OrmQueryAttributes.
+ * Parses a Object relational query statement into a OrmQueryDetail and OrmQueryAttributes.
*
- * The reason they are split into detail and attributes is that the autoFetch
- * feature is used to replace the OrmQueryDetail leaving the attributes
- * unchanged.
+ * The reason they are split into detail and attributes is that the autoFetch feature is used to
+ * replace the OrmQueryDetail leaving the attributes unchanged.
*
*/
public class OrmQueryDetailParser {
- private final OrmQueryDetail detail = new OrmQueryDetail();
+ private final OrmQueryDetail detail = new OrmQueryDetail();
- private int maxRows;
+ private int maxRows;
- private int firstRow;
+ private int firstRow;
- private String rawWhereClause;
+ private String rawWhereClause;
- private String rawOrderBy;
+ private String rawOrderBy;
- private final SimpleTextParser parser;
+ private final SimpleTextParser parser;
- public OrmQueryDetailParser(String oql) {
- this.parser = new SimpleTextParser(oql);
+ public OrmQueryDetailParser(String oql) {
+ this.parser = new SimpleTextParser(oql);
+ }
+
+ public void parse() throws PersistenceException {
+
+ parser.nextWord();
+ processInitial();
+ }
+
+ protected void assign(DefaultOrmQuery> query) {
+ query.setOrmQueryDetail(detail);
+ query.setFirstRow(firstRow);
+ query.setMaxRows(maxRows);
+ query.setRawWhereClause(rawWhereClause);
+ query.order(rawOrderBy);
+ }
+
+ private void processInitial() {
+ if (parser.isMatch("find")) {
+ OrmQueryProperties props = readFindFetch();
+ detail.setBase(props);
+ } else {
+ process();
}
+ while (!parser.isFinished()) {
+ process();
+ }
+ }
- public void parse() throws PersistenceException {
+ private boolean isFetch() {
+ return parser.isMatch("fetch") || parser.isMatch("join");
+ }
+ private void process() {
+ if (isFetch()) {
+ OrmQueryProperties props = readFindFetch();
+ detail.putFetchPath(props);
+
+ } else if (parser.isMatch("where")) {
+ readWhere();
+
+ } else if (parser.isMatch("order", "by")) {
+ readOrderBy();
+
+ } else if (parser.isMatch("limit")) {
+ readLimit();
+
+ } else {
+ throw new PersistenceException("Query expected 'fetch', 'where','order by' or 'limit' keyword but got ["
+ + parser.getWord() + "] \r " + parser.getOql());
+ }
+ }
+
+ private void readLimit() {
+ try {
+ String maxLimit = parser.nextWord();
+ maxRows = Integer.parseInt(maxLimit);
+
+ String offsetKeyword = parser.nextWord();
+ if (offsetKeyword != null) {
+ if (!parser.isMatch("offset")) {
+ throw new PersistenceException("expected offset keyword but got " + parser.getWord());
+ }
+ String firstRowLimit = parser.nextWord();
+ firstRow = Integer.parseInt(firstRowLimit);
parser.nextWord();
- processInitial();
+ }
+ } catch (NumberFormatException e) {
+ String msg = "Expected an integer for maxRows or firstRows in limit offset clause";
+ throw new PersistenceException(msg, e);
}
+ }
- protected void assign(DefaultOrmQuery> query) {
- query.setOrmQueryDetail(detail);
- query.setFirstRow(firstRow);
- query.setMaxRows(maxRows);
- query.setRawWhereClause(rawWhereClause);
- query.order(rawOrderBy);
- }
+ private void readOrderBy() {
+ // read the by
+ parser.nextWord();
- private void processInitial() {
- if (parser.isMatch("find")) {
- OrmQueryProperties props = readFindFetch();
- detail.setBase(props);
- } else {
- process();
- }
- while (!parser.isFinished()) {
- process();
+ StringBuilder sb = new StringBuilder();
+ while (parser.nextWord() != null) {
+ if (parser.isMatch("limit")) {
+ break;
+ } else {
+ String w = parser.getWord();
+ if (!w.startsWith("(")) {
+ sb.append(" ");
}
+ sb.append(w);
+ }
+ }
+ rawOrderBy = sb.toString().trim();
+
+ if (!parser.isFinished()) {
+ readLimit();
+ }
+ }
+
+ private void readWhere() {
+
+ int nextMode = 0;
+ StringBuilder sb = new StringBuilder();
+ while ((parser.nextWord()) != null) {
+ if (parser.isMatch("order", "by")) {
+ nextMode = 1;
+ break;
+
+ } else if (parser.isMatch("limit")) {
+ nextMode = 2;
+ break;
+
+ } else {
+ sb.append(" ").append(parser.getWord());
+ }
+ }
+ String whereClause = sb.toString().trim();
+ if (whereClause.length() > 0) {
+ rawWhereClause = whereClause;
}
- private boolean isFetch() {
- return parser.isMatch("fetch") || parser.isMatch("join");
+ if (nextMode == 1) {
+ readOrderBy();
+ } else if (nextMode == 2) {
+ readLimit();
}
+ }
- private void process() {
- if (isFetch()) {
- OrmQueryProperties props = readFindFetch();
- detail.putFetchPath(props);
+ private OrmQueryProperties readFindFetch() {
- } else if (parser.isMatch("where")) {
- readWhere();
+ boolean readAlias = false;
- } else if (parser.isMatch("order", "by")) {
- readOrderBy();
-
- } else if (parser.isMatch("limit")) {
- readLimit();
-
- } else {
- throw new PersistenceException("Query expected 'fetch', 'where','order by' or 'limit' keyword but got ["
- + parser.getWord() + "] \r " + parser.getOql());
- }
- }
-
- private void readLimit() {
- try {
- String maxLimit = parser.nextWord();
- maxRows = Integer.parseInt(maxLimit);
-
- String offsetKeyword = parser.nextWord();
- if (offsetKeyword != null) {
- if (!parser.isMatch("offset")) {
- throw new PersistenceException("expected offset keyword but got " + parser.getWord());
- }
- String firstRowLimit = parser.nextWord();
- firstRow = Integer.parseInt(firstRowLimit);
- parser.nextWord();
- }
- } catch (NumberFormatException e) {
- String msg = "Expected an integer for maxRows or firstRows in limit offset clause";
- throw new PersistenceException(msg, e);
- }
- }
-
- private void readOrderBy() {
- // read the by
+ String props = null;
+ String path = parser.nextWord();
+ String token = null;
+ while ((token = parser.nextWord()) != null) {
+ if (!readAlias && parser.isMatch("as")) {
+ // next token is alias
parser.nextWord();
+ readAlias = true;
- StringBuilder sb = new StringBuilder();
- while (parser.nextWord() != null) {
- if (parser.isMatch("limit")) {
- break;
- } else {
- String w = parser.getWord();
- if (!w.startsWith("(")) {
- sb.append(" ");
- }
- sb.append(w);
- }
- }
- rawOrderBy = sb.toString().trim();
+ } else if ('(' == token.charAt(0)) {
+ props = token;
+ parser.nextWord();
+ break;
- if (!parser.isFinished()) {
- readLimit();
- }
+ } else if (isFindFetchEnd()) {
+ break;
+
+ } else if (!readAlias) {
+ readAlias = true;
+
+ } else {
+ throw new PersistenceException("Expected (props) or new 'fetch' 'where' but got " + token);
+ }
}
-
- private void readWhere() {
-
- int nextMode = 0;
- StringBuilder sb = new StringBuilder();
- while ((parser.nextWord()) != null) {
- if (parser.isMatch("order", "by")) {
- nextMode = 1;
- break;
-
- } else if (parser.isMatch("limit")) {
- nextMode = 2;
- break;
-
- } else {
- sb.append(" ").append(parser.getWord());
- }
- }
- String whereClause = sb.toString().trim();
- if (whereClause.length() > 0) {
- rawWhereClause = whereClause;
- }
-
- if (nextMode == 1) {
- readOrderBy();
- } else if (nextMode == 2) {
- readLimit();
- }
+ if (props != null) {
+ props = props.substring(1, props.length() - 1);
}
+ return new OrmQueryProperties(path, props);
+ }
- private OrmQueryProperties readFindFetch() {
-
- boolean readAlias = false;
-
- String props = null;
- String path = parser.nextWord();
- String token = null;
- while ((token = parser.nextWord()) != null) {
- if (!readAlias && parser.isMatch("as")) {
- // next token is alias
- parser.nextWord();
- readAlias = true;
-
- } else if ('(' == token.charAt(0)) {
- props = token;
- parser.nextWord();
- break;
-
- } else if (isFindFetchEnd()) {
- break;
-
- } else if (!readAlias) {
- readAlias = true;
-
- } else {
- throw new PersistenceException("Expected (props) or new 'fetch' 'where' but got " + token);
- }
- }
- if (props != null) {
- props = props.substring(1, props.length() - 1);
- }
- return new OrmQueryProperties(path, props);
+ private boolean isFindFetchEnd() {
+ if (isFetch()) {
+ return true;
}
-
- private boolean isFindFetchEnd() {
- if (isFetch()) {
- return true;
- }
- if (parser.isMatch("where")) {
- return true;
- }
- if (parser.isMatch("order", "by")) {
- return true;
- }
- return false;
+ if (parser.isMatch("where")) {
+ return true;
}
+ if (parser.isMatch("order", "by")) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryLimitRequest.java b/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryLimitRequest.java
index e48817b3c..2f61869d1 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryLimitRequest.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryLimitRequest.java
@@ -6,40 +6,40 @@ import com.avaje.ebeaninternal.api.SpiQuery;
public class OrmQueryLimitRequest implements SqlLimitRequest {
- private final SpiQuery> ormQuery;
-
+ private final SpiQuery> ormQuery;
+
private final DatabasePlatform dbPlatform;
- private final String sql;
-
- private final String sqlOrderBy;
-
+ private final String sql;
+
+ private final String sqlOrderBy;
+
public OrmQueryLimitRequest(String sql, String sqlOrderBy, SpiQuery> ormQuery, DatabasePlatform dbPlatform) {
this.sql = sql;
this.sqlOrderBy = sqlOrderBy;
this.ormQuery = ormQuery;
this.dbPlatform = dbPlatform;
}
-
- public String getDbOrderBy() {
- return sqlOrderBy;
- }
- public String getDbSql() {
- return sql;
- }
+ public String getDbOrderBy() {
+ return sqlOrderBy;
+ }
- public int getFirstRow() {
- return ormQuery.getFirstRow();
- }
+ public String getDbSql() {
+ return sql;
+ }
- public int getMaxRows() {
- return ormQuery.getMaxRows();
- }
+ public int getFirstRow() {
+ return ormQuery.getFirstRow();
+ }
- public boolean isDistinct() {
- return ormQuery.isDistinctQuery();
- }
+ public int getMaxRows() {
+ return ormQuery.getMaxRows();
+ }
+
+ public boolean isDistinct() {
+ return ormQuery.isDistinctQuery();
+ }
public SpiQuery> getOrmQuery() {
return ormQuery;
diff --git a/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryProperties.java b/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryProperties.java
index 0bd24548a..cef728a61 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryProperties.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/querydefn/OrmQueryProperties.java
@@ -29,586 +29,582 @@ import com.avaje.ebeaninternal.util.FilterExpressionList;
*/
public class OrmQueryProperties implements Serializable {
- private static final long serialVersionUID = -8785582703966455658L;
+ private static final long serialVersionUID = -8785582703966455658L;
- private String parentPath;
- private String path;
+ private String parentPath;
+ private String path;
- private String properties;
+ private String properties;
- private String trimmedProperties;
+ private String trimmedProperties;
- /**
- * NB: -1 means no +query, 0 means use the default batch size.
- */
- private int queryFetchBatch = -1;
- private boolean queryFetchAll;
+ /**
+ * NB: -1 means no +query, 0 means use the default batch size.
+ */
+ private int queryFetchBatch = -1;
+ private boolean queryFetchAll;
- /**
- * NB: -1 means no +lazy, 0 means use the default batch size.
- */
- private int lazyFetchBatch = -1;
+ /**
+ * NB: -1 means no +lazy, 0 means use the default batch size.
+ */
+ private int lazyFetchBatch = -1;
- private FetchConfig fetchConfig;
-
- private boolean cache;
+ private FetchConfig fetchConfig;
- private boolean readOnly;
+ private boolean cache;
- /**
- * Note this SHOULD be a LinkedHashSet to preserve order of the properties.
- * This is to make using SqlSelect easier with predictable property/column
- * ordering.
- */
- private Set included;
+ private boolean readOnly;
- /**
- * Included bean joins.
- */
- private Set includedBeanJoin;
+ /**
+ * Note this SHOULD be a LinkedHashSet to preserve order of the properties. This is to make using
+ * SqlSelect easier with predictable property/column ordering.
+ */
+ private Set included;
- /**
- * Add these properties to the select so that the foreign key columns are
- * included in the query.
- */
- private Set secondaryQueryJoins;
+ /**
+ * Included bean joins.
+ */
+ private Set includedBeanJoin;
- private List secondaryChildren;
+ /**
+ * Add these properties to the select so that the foreign key columns are included in the query.
+ */
+ private Set secondaryQueryJoins;
- /**
- * OrderBy properties that where on the main query
- * but moved here as they relate to this (query join).
- */
- @SuppressWarnings("rawtypes")
- private OrderBy orderBy;
-
- /**
- * A filter that can be applied to the fetch of this path in the object graph.
- */
- @SuppressWarnings("rawtypes")
- private SpiExpressionList filterMany;
-
- /**
- * Construct with a given path (null == root path).
- */
- public OrmQueryProperties(String path) {
- this.path = path;
- this.parentPath = SplitName.parent(path);
+ private List secondaryChildren;
+
+ /**
+ * OrderBy properties that where on the main query but moved here as they relate to this (query
+ * join).
+ */
+ @SuppressWarnings("rawtypes")
+ private OrderBy orderBy;
+
+ /**
+ * A filter that can be applied to the fetch of this path in the object graph.
+ */
+ @SuppressWarnings("rawtypes")
+ private SpiExpressionList filterMany;
+
+ /**
+ * Construct with a given path (null == root path).
+ */
+ public OrmQueryProperties(String path) {
+ this.path = path;
+ this.parentPath = SplitName.parent(path);
+ }
+
+ public OrmQueryProperties() {
+ this(null);
+ }
+
+ /**
+ * Used by query language parser.
+ */
+ public OrmQueryProperties(String path, String properties) {
+ this(path);
+ setProperties(properties);
+ }
+
+ /**
+ * Move a OrderBy.Property from the main query to this query join.
+ */
+ @SuppressWarnings("rawtypes")
+ public void addSecJoinOrderProperty(OrderBy.Property orderProp) {
+ if (orderBy == null) {
+ orderBy = new OrderBy();
}
+ orderBy.add(orderProp);
+ }
- public OrmQueryProperties() {
- this(null);
+ /**
+ * Set the Fetch configuration options for this path.
+ */
+ public void setFetchConfig(FetchConfig fetchConfig) {
+ if (fetchConfig != null) {
+ this.fetchConfig = fetchConfig;
+ lazyFetchBatch = fetchConfig.getLazyBatchSize();
+ queryFetchBatch = fetchConfig.getQueryBatchSize();
+ queryFetchAll = fetchConfig.isQueryAll();
}
+ }
- /**
- * Used by query language parser.
- */
- public OrmQueryProperties(String path, String properties) {
- this(path);
- setProperties(properties);
- }
+ public FetchConfig getFetchConfig() {
+ return fetchConfig;
+ }
- /**
- * Move a OrderBy.Property from the main query to this query join.
- */
- @SuppressWarnings("rawtypes")
- public void addSecJoinOrderProperty(OrderBy.Property orderProp) {
- if (orderBy == null){
- orderBy = new OrderBy();
- }
- orderBy.add(orderProp);
- }
-
- /**
- * Set the Fetch configuration options for this path.
- */
- public void setFetchConfig(FetchConfig fetchConfig) {
- if (fetchConfig != null) {
- this.fetchConfig = fetchConfig;
- lazyFetchBatch = fetchConfig.getLazyBatchSize();
- queryFetchBatch = fetchConfig.getQueryBatchSize();
- queryFetchAll = fetchConfig.isQueryAll();
- }
- }
-
- public FetchConfig getFetchConfig() {
- return fetchConfig;
- }
-
- /**
- * Set the comma delimited properties to fetch for this path.
- *
- * This can include the +query and +lazy type hints.
- *
- */
- public void setProperties(String properties) {
- this.properties = properties;
- this.trimmedProperties = properties;
- parseProperties();
+ /**
+ * Set the comma delimited properties to fetch for this path.
+ *
+ * This can include the +query and +lazy type hints.
+ *
+ */
+ public void setProperties(String properties) {
+ this.properties = properties;
+ this.trimmedProperties = properties;
+ parseProperties();
- if (!isAllProperties()) {
- Set parsed = parseIncluded(trimmedProperties);
- if (parsed.contains("*")){
- this.included = null;
- } else {
- this.included = parsed;
- }
- } else {
- this.included = null;
- }
- }
-
- private boolean isAllProperties() {
- return (trimmedProperties == null) || (trimmedProperties.length() == 0) || "*".equals(trimmedProperties);
- }
-
- /**
- * Return the expressions used to filter on this path.
- * This should be a many path to use this method.
- */
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public SpiExpressionList filterMany(Query rootQuery) {
- if (filterMany == null){
- FilterExprPath exprPath = new FilterExprPath(path);
- SpiExpressionFactory queryEf = (SpiExpressionFactory)rootQuery.getExpressionFactory();
- ExpressionFactory filterEf = queryEf.createExpressionFactory();//exprPath);
- filterMany = new FilterExpressionList(exprPath, filterEf, rootQuery);
- // by default we need to make this a 'query join' now
- queryFetchAll = true;
- queryFetchBatch = 100;
- lazyFetchBatch = 100;
- }
- return filterMany;
- }
-
- /**
- * Return the filterMany expression list (can be null).
- */
- public SpiExpressionList> getFilterManyTrimPath(int trimPath) {
- if (filterMany == null){
- return null;
- }
- return filterMany.trimPath(trimPath);
- }
-
- /**
- * Return the filterMany expression list (can be null).
- */
- public SpiExpressionList> getFilterMany() {
- return filterMany;
- }
-
- /**
- * Set the filterMany expression list.
- */
- public void setFilterMany(SpiExpressionList> filterMany) {
- this.filterMany = filterMany;
- }
-
- /**
- * Set the properties from deployment default FetchTypes.
- */
- public void setDefaultProperties(String properties, Set included) {
- this.properties = properties;
- this.trimmedProperties = properties;
- this.included = included;
- }
-
- /**
- * Set the properties from a matching autofetch tuned properties.
- */
- public void setTunedProperties(OrmQueryProperties tunedProperties) {
- this.properties = tunedProperties.properties;
- this.trimmedProperties = tunedProperties.trimmedProperties;
- this.included = tunedProperties.included;
- }
-
- /**
- * Define the select and joins for this query.
- */
- @SuppressWarnings("unchecked")
- public void configureBeanQuery(SpiQuery> query) {
-
- if (trimmedProperties != null && trimmedProperties.length() > 0) {
- query.select(trimmedProperties);
- }
-
- if (filterMany != null){
- SpiExpressionList> trimPath = filterMany.trimPath(path.length()+1);
- List underlyingList = trimPath.getUnderlyingList();
- for (SpiExpression spiExpression : underlyingList) {
- query.where().add(spiExpression);
- }
- }
-
- if (secondaryChildren != null) {
- int trimPath = path.length() + 1;
- for (int i = 0; i < secondaryChildren.size(); i++) {
- OrmQueryProperties p = secondaryChildren.get(i);
- String path = p.getPath();
- path = path.substring(trimPath);
- query.fetch(path, p.getProperties(), p.getFetchConfig());
- query.setFilterMany(path, p.getFilterManyTrimPath(trimPath));
- }
- }
-
- if (orderBy != null){
- query.setOrder(orderBy.copyWithTrim(path));
- }
- }
-
- /**
- * Creates a copy of the OrmQueryProperties.
- */
- public OrmQueryProperties copy() {
- OrmQueryProperties copy = new OrmQueryProperties();
- copy.parentPath = parentPath;
- copy.path = path;
- copy.properties = properties;
- copy.cache = cache;
- copy.readOnly = readOnly;
- copy.queryFetchAll = queryFetchAll;
- copy.queryFetchBatch = queryFetchBatch;
- copy.lazyFetchBatch = lazyFetchBatch;
- copy.filterMany = filterMany;
- if (included != null) {
- copy.included = new HashSet(included);
- }
- if (includedBeanJoin != null) {
- copy.includedBeanJoin = new HashSet(includedBeanJoin);
- }
- return copy;
- }
-
- public boolean hasSelectClause() {
- if ("*".equals(trimmedProperties)) {
- // explicitly selected all properties
- return true;
- }
- // explicitly selected some properties
- return included != null;
- }
-
- public String toString() {
- String s = "";
- if (path != null) {
- s += path + " ";
- }
- if (properties != null) {
- s += "(" + properties + ") ";
- } else if (included != null) {
- s += "(" + included + ") ";
- }
- return s;
- }
-
- public boolean isChild(OrmQueryProperties possibleChild) {
- return possibleChild.getPath().startsWith(path + ".");
- }
-
- /**
- * For secondary queries add a child element.
- */
- public void add(OrmQueryProperties child) {
- if (secondaryChildren == null) {
- secondaryChildren = new ArrayList();
- }
- secondaryChildren.add(child);
- }
-
- public int autofetchPlanHash() {
-
- int hc = (path != null ? path.hashCode() : 1);
- if (properties != null){
- hc = hc * 31 + properties.hashCode();
- } else {
- hc = hc * 31 + (included != null ? included.hashCode() : 1);
- }
-
- return hc;
- }
-
- /**
- * Calculate the query plan hash.
- */
- @SuppressWarnings("unchecked")
- public void queryPlanHash(BeanQueryRequest> request, HashQueryPlanBuilder builder) {
-
- builder.add(path);
- if (properties != null) {
- builder.add(properties);
+ if (!isAllProperties()) {
+ Set parsed = parseIncluded(trimmedProperties);
+ if (parsed.contains("*")) {
+ this.included = null;
} else {
- builder.add(included);
+ this.included = parsed;
}
- builder.add(filterMany != null);
- if (filterMany != null) {
- filterMany.queryPlanHash(request, builder);
+ } else {
+ this.included = null;
+ }
+ }
+
+ private boolean isAllProperties() {
+ return (trimmedProperties == null) || (trimmedProperties.length() == 0) || "*".equals(trimmedProperties);
+ }
+
+ /**
+ * Return the expressions used to filter on this path. This should be a many path to use this
+ * method.
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public SpiExpressionList filterMany(Query rootQuery) {
+ if (filterMany == null) {
+ FilterExprPath exprPath = new FilterExprPath(path);
+ SpiExpressionFactory queryEf = (SpiExpressionFactory) rootQuery.getExpressionFactory();
+ ExpressionFactory filterEf = queryEf.createExpressionFactory();// exprPath);
+ filterMany = new FilterExpressionList(exprPath, filterEf, rootQuery);
+ // by default we need to make this a 'query join' now
+ queryFetchAll = true;
+ queryFetchBatch = 100;
+ lazyFetchBatch = 100;
+ }
+ return filterMany;
+ }
+
+ /**
+ * Return the filterMany expression list (can be null).
+ */
+ public SpiExpressionList> getFilterManyTrimPath(int trimPath) {
+ if (filterMany == null) {
+ return null;
+ }
+ return filterMany.trimPath(trimPath);
+ }
+
+ /**
+ * Return the filterMany expression list (can be null).
+ */
+ public SpiExpressionList> getFilterMany() {
+ return filterMany;
+ }
+
+ /**
+ * Set the filterMany expression list.
+ */
+ public void setFilterMany(SpiExpressionList> filterMany) {
+ this.filterMany = filterMany;
+ }
+
+ /**
+ * Set the properties from deployment default FetchTypes.
+ */
+ public void setDefaultProperties(String properties, Set included) {
+ this.properties = properties;
+ this.trimmedProperties = properties;
+ this.included = included;
+ }
+
+ /**
+ * Set the properties from a matching autofetch tuned properties.
+ */
+ public void setTunedProperties(OrmQueryProperties tunedProperties) {
+ this.properties = tunedProperties.properties;
+ this.trimmedProperties = tunedProperties.trimmedProperties;
+ this.included = tunedProperties.included;
+ }
+
+ /**
+ * Define the select and joins for this query.
+ */
+ @SuppressWarnings("unchecked")
+ public void configureBeanQuery(SpiQuery> query) {
+
+ if (trimmedProperties != null && trimmedProperties.length() > 0) {
+ query.select(trimmedProperties);
+ }
+
+ if (filterMany != null) {
+ SpiExpressionList> trimPath = filterMany.trimPath(path.length() + 1);
+ List underlyingList = trimPath.getUnderlyingList();
+ for (SpiExpression spiExpression : underlyingList) {
+ query.where().add(spiExpression);
}
}
- public String getProperties() {
- return properties;
+ if (secondaryChildren != null) {
+ int trimPath = path.length() + 1;
+ for (int i = 0; i < secondaryChildren.size(); i++) {
+ OrmQueryProperties p = secondaryChildren.get(i);
+ String path = p.getPath();
+ path = path.substring(trimPath);
+ query.fetch(path, p.getProperties(), p.getFetchConfig());
+ query.setFilterMany(path, p.getFilterManyTrimPath(trimPath));
+ }
}
- /**
- * Return true if this has properties.
- */
- public boolean hasProperties() {
- return properties != null || included != null;
+ if (orderBy != null) {
+ query.setOrder(orderBy.copyWithTrim(path));
+ }
+ }
+
+ /**
+ * Creates a copy of the OrmQueryProperties.
+ */
+ public OrmQueryProperties copy() {
+ OrmQueryProperties copy = new OrmQueryProperties();
+ copy.parentPath = parentPath;
+ copy.path = path;
+ copy.properties = properties;
+ copy.cache = cache;
+ copy.readOnly = readOnly;
+ copy.queryFetchAll = queryFetchAll;
+ copy.queryFetchBatch = queryFetchBatch;
+ copy.lazyFetchBatch = lazyFetchBatch;
+ copy.filterMany = filterMany;
+ if (included != null) {
+ copy.included = new HashSet(included);
+ }
+ if (includedBeanJoin != null) {
+ copy.includedBeanJoin = new HashSet(includedBeanJoin);
+ }
+ return copy;
+ }
+
+ public boolean hasSelectClause() {
+ if ("*".equals(trimmedProperties)) {
+ // explicitly selected all properties
+ return true;
+ }
+ // explicitly selected some properties
+ return included != null;
+ }
+
+ public String toString() {
+ String s = "";
+ if (path != null) {
+ s += path + " ";
+ }
+ if (properties != null) {
+ s += "(" + properties + ") ";
+ } else if (included != null) {
+ s += "(" + included + ") ";
+ }
+ return s;
+ }
+
+ public boolean isChild(OrmQueryProperties possibleChild) {
+ return possibleChild.getPath().startsWith(path + ".");
+ }
+
+ /**
+ * For secondary queries add a child element.
+ */
+ public void add(OrmQueryProperties child) {
+ if (secondaryChildren == null) {
+ secondaryChildren = new ArrayList();
+ }
+ secondaryChildren.add(child);
+ }
+
+ public int autofetchPlanHash() {
+
+ int hc = (path != null ? path.hashCode() : 1);
+ if (properties != null) {
+ hc = hc * 31 + properties.hashCode();
+ } else {
+ hc = hc * 31 + (included != null ? included.hashCode() : 1);
}
- /**
- * Return true if this property is included as a bean join.
- *
- * If a property is included as a bean join then it should not be included
- * as a reference/proxy to avoid duplication.
- *
- */
- public boolean isIncludedBeanJoin(String propertyName) {
- if (includedBeanJoin == null) {
- return false;
- } else {
- return includedBeanJoin.contains(propertyName);
+ return hc;
+ }
+
+ /**
+ * Calculate the query plan hash.
+ */
+ @SuppressWarnings("unchecked")
+ public void queryPlanHash(BeanQueryRequest> request, HashQueryPlanBuilder builder) {
+
+ builder.add(path);
+ if (properties != null) {
+ builder.add(properties);
+ } else {
+ builder.add(included);
+ }
+ builder.add(filterMany != null);
+ if (filterMany != null) {
+ filterMany.queryPlanHash(request, builder);
+ }
+ }
+
+ public String getProperties() {
+ return properties;
+ }
+
+ /**
+ * Return true if this has properties.
+ */
+ public boolean hasProperties() {
+ return properties != null || included != null;
+ }
+
+ /**
+ * Return true if this property is included as a bean join.
+ *
+ * If a property is included as a bean join then it should not be included as a reference/proxy to
+ * avoid duplication.
+ *
+ */
+ public boolean isIncludedBeanJoin(String propertyName) {
+ if (includedBeanJoin == null) {
+ return false;
+ } else {
+ return includedBeanJoin.contains(propertyName);
+ }
+ }
+
+ /**
+ * Add a bean join property.
+ */
+ public void includeBeanJoin(String propertyName) {
+ if (includedBeanJoin == null) {
+ includedBeanJoin = new HashSet();
+ }
+ includedBeanJoin.add(propertyName);
+ }
+
+ public boolean allProperties() {
+ return included == null;
+ }
+
+ /**
+ * This excludes the bean joined properties.
+ *
+ * This is because bean joins will have there own node in the SqlTree.
+ *
+ */
+ public Iterator getSelectProperties() {
+
+ if (secondaryQueryJoins == null) {
+ return included.iterator();
+ }
+
+ LinkedHashSet temp = new LinkedHashSet(secondaryQueryJoins.size() + included.size());
+ temp.addAll(included);
+ temp.addAll(secondaryQueryJoins);
+ return temp.iterator();
+ }
+
+ public void addSecondaryQueryJoin(String property) {
+ if (secondaryQueryJoins == null) {
+ secondaryQueryJoins = new HashSet(4);
+ }
+ secondaryQueryJoins.add(property);
+ }
+
+ /**
+ * Return all the properties including the bean joins. This is the set that will be used by
+ * EntityBeanIntercept to determine if a property needs to be lazy loaded.
+ */
+ public Set getAllIncludedProperties() {
+
+ if (included == null) {
+ return null;
+ }
+
+ if (includedBeanJoin == null && secondaryQueryJoins == null) {
+ return new LinkedHashSet(included);
+ }
+
+ LinkedHashSet s = new LinkedHashSet(2 * (included.size() + 5));
+ if (included != null) {
+ s.addAll(included);
+ }
+ if (includedBeanJoin != null) {
+ s.addAll(includedBeanJoin);
+ }
+ if (secondaryQueryJoins != null) {
+ s.addAll(secondaryQueryJoins);
+ }
+ return s;
+ }
+
+ public boolean isIncluded(String propName) {
+
+ if (includedBeanJoin != null && includedBeanJoin.contains(propName)) {
+ return false;
+ }
+ if (included == null) {
+ // all properties included
+ return true;
+ }
+ return included.contains(propName);
+ }
+
+ /**
+ * Used to convert this join to a query join.
+ *
+ * @param queryJoinBatch
+ * where -1 means not a query join and 0 means use the default batch size.
+ */
+ public OrmQueryProperties setQueryFetchBatch(int queryFetchBatch) {
+ this.queryFetchBatch = queryFetchBatch;
+ return this;
+ }
+
+ public OrmQueryProperties setQueryFetchAll(boolean queryFetchAll) {
+ this.queryFetchAll = queryFetchAll;
+ return this;
+ }
+
+ public OrmQueryProperties setQueryFetch(int batch, boolean queryFetchAll) {
+ this.queryFetchBatch = batch;
+ this.queryFetchAll = queryFetchAll;
+ return this;
+ }
+
+ /**
+ * Set the lazy loading batch size.
+ */
+ public OrmQueryProperties setLazyFetchBatch(int lazyFetchBatch) {
+ this.lazyFetchBatch = lazyFetchBatch;
+ return this;
+ }
+
+ public boolean isFetchJoin() {
+ return !isQueryFetch() && !isLazyFetch();
+ }
+
+ public boolean isQueryFetch() {
+ return queryFetchBatch > -1;
+ }
+
+ public int getQueryFetchBatch() {
+ return queryFetchBatch;
+ }
+
+ public boolean isQueryFetchAll() {
+ return queryFetchAll;
+ }
+
+ public boolean isLazyFetch() {
+ return lazyFetchBatch > -1;
+ }
+
+ public int getLazyFetchBatch() {
+ return lazyFetchBatch;
+ }
+
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ public boolean isCache() {
+ return cache;
+ }
+
+ public String getParentPath() {
+ return parentPath;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ private void parseProperties() {
+ if (trimmedProperties == null) {
+ return;
+ }
+ int pos = trimmedProperties.indexOf("+readonly");
+ if (pos > -1) {
+ trimmedProperties = StringHelper.replaceString(trimmedProperties, "+readonly", "");
+ this.readOnly = true;
+ }
+ pos = trimmedProperties.indexOf("+cache");
+ if (pos > -1) {
+ trimmedProperties = StringHelper.replaceString(trimmedProperties, "+cache", "");
+ this.cache = true;
+ }
+ pos = trimmedProperties.indexOf("+query");
+ if (pos > -1) {
+ queryFetchBatch = parseBatchHint(pos, "+query");
+ }
+ pos = trimmedProperties.indexOf("+lazy");
+ if (pos > -1) {
+ lazyFetchBatch = parseBatchHint(pos, "+lazy");
+ }
+
+ trimmedProperties = trimmedProperties.trim();
+ while (trimmedProperties.startsWith(",")) {
+ trimmedProperties = trimmedProperties.substring(1).trim();
+ }
+ }
+
+ private int parseBatchHint(int pos, String option) {
+
+ int startPos = pos + option.length();
+
+ int endPos = findEndPos(startPos, trimmedProperties);
+ if (endPos == -1) {
+ trimmedProperties = StringHelper.replaceString(trimmedProperties, option, "");
+ return 0;
+
+ } else {
+
+ String batchParam = trimmedProperties.substring(startPos + 1, endPos);
+
+ if (endPos + 1 >= trimmedProperties.length()) {
+ trimmedProperties = trimmedProperties.substring(0, pos);
+ } else {
+ trimmedProperties = trimmedProperties.substring(0, pos) + trimmedProperties.substring(endPos + 1);
+ }
+ return Integer.parseInt(batchParam);
+ }
+ }
+
+ private int findEndPos(int pos, String props) {
+
+ if (pos < props.length()) {
+ if (props.charAt(pos) == '(') {
+ int endPara = props.indexOf(')', pos + 1);
+ if (endPara == -1) {
+ String m = "Error could not find ')' in " + props + " after position " + pos;
+ throw new RuntimeException(m);
}
+ return endPara;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Parse the include separating by comma or semicolon.
+ */
+ private static Set parseIncluded(String rawList) {
+
+ String[] res = rawList.split(",");
+
+ LinkedHashSet set = new LinkedHashSet(res.length + 3);
+
+ String temp = null;
+ for (int i = 0; i < res.length; i++) {
+ temp = res[i].trim();
+ if (temp.length() > 0) {
+ set.add(temp);
+ }
}
- /**
- * Add a bean join property.
- */
- public void includeBeanJoin(String propertyName) {
- if (includedBeanJoin == null) {
- includedBeanJoin = new HashSet();
- }
- includedBeanJoin.add(propertyName);
+ if (set.isEmpty()) {
+ return null;
}
- public boolean allProperties() {
- return included == null;
- }
-
- /**
- * This excludes the bean joined properties.
- *
- * This is because bean joins will have there own node in the SqlTree.
- *
- */
- public Iterator getSelectProperties() {
-
- if (secondaryQueryJoins == null) {
- return included.iterator();
- }
-
- LinkedHashSet temp = new LinkedHashSet(secondaryQueryJoins.size() + included.size());
- temp.addAll(included);
- temp.addAll(secondaryQueryJoins);
- return temp.iterator();
- }
-
- public void addSecondaryQueryJoin(String property) {
- if (secondaryQueryJoins == null) {
- secondaryQueryJoins = new HashSet(4);
- }
- secondaryQueryJoins.add(property);
- }
-
- /**
- * Return all the properties including the bean joins. This is the set that
- * will be used by EntityBeanIntercept to determine if a property needs to
- * be lazy loaded.
- */
- public Set getAllIncludedProperties() {
-
- if (included == null) {
- return null;
- }
-
- if (includedBeanJoin == null && secondaryQueryJoins == null) {
- return new LinkedHashSet(included);
- }
-
- LinkedHashSet s = new LinkedHashSet(2 * (included.size() + 5));
- if (included != null) {
- s.addAll(included);
- }
- if (includedBeanJoin != null) {
- s.addAll(includedBeanJoin);
- }
- if (secondaryQueryJoins != null) {
- s.addAll(secondaryQueryJoins);
- }
- return s;
- }
-
- public boolean isIncluded(String propName) {
-
- if (includedBeanJoin != null && includedBeanJoin.contains(propName)) {
- return false;
- }
- if (included == null) {
- // all properties included
- return true;
- }
- return included.contains(propName);
- }
-
- /**
- * Used to convert this join to a query join.
- *
- * @param queryJoinBatch
- * where -1 means not a query join and 0 means use the default
- * batch size.
- */
- public OrmQueryProperties setQueryFetchBatch(int queryFetchBatch) {
- this.queryFetchBatch = queryFetchBatch;
- return this;
- }
-
- public OrmQueryProperties setQueryFetchAll(boolean queryFetchAll) {
- this.queryFetchAll = queryFetchAll;
- return this;
- }
-
- public OrmQueryProperties setQueryFetch(int batch, boolean queryFetchAll) {
- this.queryFetchBatch = batch;
- this.queryFetchAll = queryFetchAll;
- return this;
- }
-
- /**
- * Set the lazy loading batch size.
- */
- public OrmQueryProperties setLazyFetchBatch(int lazyFetchBatch) {
- this.lazyFetchBatch = lazyFetchBatch;
- return this;
- }
-
- public boolean isFetchJoin() {
- return !isQueryFetch() && !isLazyFetch();
- }
-
- public boolean isQueryFetch() {
- return queryFetchBatch > -1;
- }
-
- public int getQueryFetchBatch() {
- return queryFetchBatch;
- }
-
- public boolean isQueryFetchAll() {
- return queryFetchAll;
- }
-
- public boolean isLazyFetch() {
- return lazyFetchBatch > -1;
- }
-
- public int getLazyFetchBatch() {
- return lazyFetchBatch;
- }
-
- public boolean isReadOnly() {
- return readOnly;
- }
-
- public boolean isCache() {
- return cache;
- }
-
- public String getParentPath() {
- return parentPath;
- }
-
- public String getPath() {
- return path;
- }
-
- private void parseProperties() {
- if (trimmedProperties == null) {
- return;
- }
- int pos = trimmedProperties.indexOf("+readonly");
- if (pos > -1) {
- trimmedProperties = StringHelper.replaceString(trimmedProperties, "+readonly", "");
- this.readOnly = true;
- }
- pos = trimmedProperties.indexOf("+cache");
- if (pos > -1) {
- trimmedProperties = StringHelper.replaceString(trimmedProperties, "+cache", "");
- this.cache = true;
- }
- pos = trimmedProperties.indexOf("+query");
- if (pos > -1) {
- queryFetchBatch = parseBatchHint(pos, "+query");
- }
- pos = trimmedProperties.indexOf("+lazy");
- if (pos > -1) {
- lazyFetchBatch = parseBatchHint(pos, "+lazy");
- }
-
- trimmedProperties = trimmedProperties.trim();
- while (trimmedProperties.startsWith(",")) {
- trimmedProperties = trimmedProperties.substring(1).trim();
- }
- }
-
- private int parseBatchHint(int pos, String option) {
-
- int startPos = pos + option.length();
-
- int endPos = findEndPos(startPos, trimmedProperties);
- if (endPos == -1) {
- trimmedProperties = StringHelper.replaceString(trimmedProperties, option, "");
- return 0;
-
- } else {
-
- String batchParam = trimmedProperties.substring(startPos + 1, endPos);
-
- if (endPos + 1 >= trimmedProperties.length()) {
- trimmedProperties = trimmedProperties.substring(0, pos);
- } else {
- trimmedProperties = trimmedProperties.substring(0, pos) + trimmedProperties.substring(endPos + 1);
- }
- return Integer.parseInt(batchParam);
- }
- }
-
- private int findEndPos(int pos, String props) {
-
- if (pos < props.length()) {
- if (props.charAt(pos) == '(') {
- int endPara = props.indexOf(')', pos + 1);
- if (endPara == -1) {
- String m = "Error could not find ')' in " + props + " after position " + pos;
- throw new RuntimeException(m);
- }
- return endPara;
- }
- }
- return -1;
- }
-
- /**
- * Parse the include separating by comma or semicolon.
- */
- private static Set parseIncluded(String rawList) {
-
- String[] res = rawList.split(",");
-
- LinkedHashSet set = new LinkedHashSet(res.length + 3);
-
- String temp = null;
- for (int i = 0; i < res.length; i++) {
- temp = res[i].trim();
- if (temp.length() > 0) {
- set.add(temp);
- }
- }
-
- if (set.isEmpty()){
- return null;
- }
-
- return Collections.unmodifiableSet(set);
- }
+ return Collections.unmodifiableSet(set);
+ }
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/querydefn/SimpleTextParser.java b/src/main/java/com/avaje/ebeaninternal/server/querydefn/SimpleTextParser.java
index dd1bffaea..e60f0683e 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/querydefn/SimpleTextParser.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/querydefn/SimpleTextParser.java
@@ -2,176 +2,176 @@ package com.avaje.ebeaninternal.server.querydefn;
public class SimpleTextParser {
- private final String oql;
- private final char[] chars;
- private final int eof;
+ private final String oql;
+ private final char[] chars;
+ private final int eof;
- private int pos;
- private String word;
- private String lowerWord;
+ private int pos;
+ private String word;
+ private String lowerWord;
- private int openParenthesisCount;
+ private int openParenthesisCount;
- public SimpleTextParser(String oql) {
- this.oql = oql;
- this.chars = oql.toCharArray();
- this.eof = oql.length();
- }
+ public SimpleTextParser(String oql) {
+ this.oql = oql;
+ this.chars = oql.toCharArray();
+ this.eof = oql.length();
+ }
- public int getPos() {
+ public int getPos() {
return pos;
}
public String getOql() {
- return oql;
- }
+ return oql;
+ }
- public String getWord() {
- return word;
- }
+ public String getWord() {
+ return word;
+ }
- public String peekNextWord() {
- int origPos = pos;
- String nw = nextWordInternal();
- pos = origPos;
- return nw;
- }
+ public String peekNextWord() {
+ int origPos = pos;
+ String nw = nextWordInternal();
+ pos = origPos;
+ return nw;
+ }
- /**
- * Match the current and the next word.
- */
- public boolean isMatch(String lowerMatch, String nextWordMatch) {
+ /**
+ * Match the current and the next word.
+ */
+ public boolean isMatch(String lowerMatch, String nextWordMatch) {
- if (isMatch(lowerMatch)) {
- String nw = peekNextWord();
- if (nw != null) {
- nw = nw.toLowerCase();
- return nw.equals(nextWordMatch);
- }
- }
- return false;
- }
+ if (isMatch(lowerMatch)) {
+ String nw = peekNextWord();
+ if (nw != null) {
+ nw = nw.toLowerCase();
+ return nw.equals(nextWordMatch);
+ }
+ }
+ return false;
+ }
- public boolean isFinished() {
- return word == null;
- }
+ public boolean isFinished() {
+ return word == null;
+ }
- public int findWordLower(String lowerMatch, int afterPos) {
- this.pos = afterPos;
- return findWordLower(lowerMatch);
- }
+ public int findWordLower(String lowerMatch, int afterPos) {
+ this.pos = afterPos;
+ return findWordLower(lowerMatch);
+ }
- public int findWordLower(String lowerMatch) {
- do {
- if (nextWord() == null) {
- return -1;
- }
- if (lowerMatch.equals(lowerWord)) {
- return pos - lowerWord.length();
- }
- } while (true);
- }
+ public int findWordLower(String lowerMatch) {
+ do {
+ if (nextWord() == null) {
+ return -1;
+ }
+ if (lowerMatch.equals(lowerWord)) {
+ return pos - lowerWord.length();
+ }
+ } while (true);
+ }
- /**
- * Match the current word.
- */
- public boolean isMatch(String lowerMatch) {
- return lowerMatch.equals(lowerWord);
- }
+ /**
+ * Match the current word.
+ */
+ public boolean isMatch(String lowerMatch) {
+ return lowerMatch.equals(lowerWord);
+ }
- public String nextWord() {
- word = nextWordInternal();
- if (word != null) {
- lowerWord = word.toLowerCase();
- }
- return word;
- }
+ public String nextWord() {
+ word = nextWordInternal();
+ if (word != null) {
+ lowerWord = word.toLowerCase();
+ }
+ return word;
+ }
- private String nextWordInternal() {
- trimLeadingWhitespace();
- if (pos >= eof) {
- return null;
- }
- int start = pos;
- if (chars[pos] == '(') {
- moveToClose();
- } else {
- moveToEndOfWord();
- }
- return oql.substring(start, pos);
- }
+ private String nextWordInternal() {
+ trimLeadingWhitespace();
+ if (pos >= eof) {
+ return null;
+ }
+ int start = pos;
+ if (chars[pos] == '(') {
+ moveToClose();
+ } else {
+ moveToEndOfWord();
+ }
+ return oql.substring(start, pos);
+ }
- private void moveToClose() {
+ private void moveToClose() {
- pos++;
- openParenthesisCount = 0;
+ pos++;
+ openParenthesisCount = 0;
- for (; pos < eof; pos++) {
- char c = chars[pos];
- if (c == '(') {
- // count nested parenthesis
- openParenthesisCount++;
+ for (; pos < eof; pos++) {
+ char c = chars[pos];
+ if (c == '(') {
+ // count nested parenthesis
+ openParenthesisCount++;
- } else if (c == ')') {
- if (openParenthesisCount > 0) {
- // still in nested parenthesis
- --openParenthesisCount;
- } else {
- // we have found the end
- pos++;
- return;
- }
- }
- }
- }
+ } else if (c == ')') {
+ if (openParenthesisCount > 0) {
+ // still in nested parenthesis
+ --openParenthesisCount;
+ } else {
+ // we have found the end
+ pos++;
+ return;
+ }
+ }
+ }
+ }
- private void moveToEndOfWord() {
- char c = chars[pos];
- boolean isOperator = isOperator(c);
- for (; pos < eof; pos++) {
- c = chars[pos];
- if (isWordTerminator(c, isOperator)) {
- return;
- }
- }
- }
+ private void moveToEndOfWord() {
+ char c = chars[pos];
+ boolean isOperator = isOperator(c);
+ for (; pos < eof; pos++) {
+ c = chars[pos];
+ if (isWordTerminator(c, isOperator)) {
+ return;
+ }
+ }
+ }
- private boolean isWordTerminator(char c, boolean isOperator) {
- if (Character.isWhitespace(c)) {
- return true;
- }
- if (isOperator(c)) {
- return !isOperator;
- }
- if (c == '('){
- return true;
- }
+ private boolean isWordTerminator(char c, boolean isOperator) {
+ if (Character.isWhitespace(c)) {
+ return true;
+ }
+ if (isOperator(c)) {
+ return !isOperator;
+ }
+ if (c == '(') {
+ return true;
+ }
- return isOperator;
- }
+ return isOperator;
+ }
- private boolean isOperator(char c) {
- switch (c) {
- case '<':
- return true;
- case '>':
- return true;
- case '=':
- return true;
- case '!':
- return true;
+ private boolean isOperator(char c) {
+ switch (c) {
+ case '<':
+ return true;
+ case '>':
+ return true;
+ case '=':
+ return true;
+ case '!':
+ return true;
- default:
- return false;
- }
- }
+ default:
+ return false;
+ }
+ }
- private void trimLeadingWhitespace() {
- for (; pos < eof; pos++) {
- char c = chars[pos];
- if (!Character.isWhitespace(c)) {
- break;
- }
- }
- }
+ private void trimLeadingWhitespace() {
+ for (; pos < eof; pos++) {
+ char c = chars[pos];
+ if (!Character.isWhitespace(c)) {
+ break;
+ }
+ }
+ }
}
\ No newline at end of file