summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/EOFetchSpecification.java
diff options
context:
space:
mode:
authorBenjamin Culkin <scorpress@gmail.com>2024-05-19 17:56:33 -0400
committerBenjamin Culkin <scorpress@gmail.com>2024-05-19 17:56:33 -0400
commitaedc34d55462a75e329bbf342251ff6504cd117e (patch)
treebcc8f1f2352582717b484df302aeea6696b8f000 /projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/EOFetchSpecification.java
Initial import from SVN
Diffstat (limited to 'projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/EOFetchSpecification.java')
-rw-r--r--projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/EOFetchSpecification.java565
1 files changed, 565 insertions, 0 deletions
diff --git a/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/EOFetchSpecification.java b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/EOFetchSpecification.java
new file mode 100644
index 0000000..71f3b78
--- /dev/null
+++ b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/EOFetchSpecification.java
@@ -0,0 +1,565 @@
+/*
+Wotonomy: OpenStep design patterns for pure Java applications.
+Copyright (C) 2001 Michael Powers
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, see http://www.gnu.org
+*/
+
+package net.wotonomy.control;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import net.wotonomy.foundation.NSArray;
+import net.wotonomy.foundation.NSDictionary;
+import net.wotonomy.foundation.NSMutableArray;
+import net.wotonomy.foundation.NSMutableDictionary;
+import net.wotonomy.foundation.NSSelector;
+import net.wotonomy.foundation.internal.WotonomyException;
+
+/**
+* EOFetchSpecification defines the parameters used to request
+* objects from an EOObjectStore. They are commonly created
+* and passed to a EODataSource which fetches from its
+* EOEditingContext, which passes the call up to its root
+* EOObjectStore's objectsWithFetchSpecification method.
+*
+* @author michael@mpowers.net
+* @author $Author: cgruber $
+* @version $Revision: 894 $
+*/
+public class EOFetchSpecification implements EOKeyValueArchiving {
+ private boolean fetchesRawRows;
+ private String entityName;
+ private NSDictionary hints;
+ private boolean deep;
+ private int fetchLimit;
+ private boolean locksObjects;
+ private NSArray prefetchingRelationshipKeyPaths;
+ private boolean promptsAfterFetchLimit;
+ private EOQualifier qualifier;
+ private NSArray rawRowKeyPaths;
+ private boolean refreshesRefetchedObjects;
+ private boolean requiresAllQualifierBindingVariables;
+ private NSArray sortOrderings;
+ private boolean distinct;
+
+ /**
+ * Default constructor initializes internal state.
+ */
+ public EOFetchSpecification()
+ {
+ fetchesRawRows = false;
+ entityName = null;
+ hints = null;
+ deep = true;
+ fetchLimit = 0;
+ locksObjects = false;
+ prefetchingRelationshipKeyPaths = null;
+ promptsAfterFetchLimit = false;
+ qualifier = null;
+ rawRowKeyPaths = null;
+ refreshesRefetchedObjects = false;
+ requiresAllQualifierBindingVariables = false;
+ sortOrderings = null;
+ distinct = false;
+ }
+
+ /**
+ * Constructs a fetch specification for the specified entity type using
+ * the specified qualifier and sort ordering.
+ */
+ public EOFetchSpecification( String anEntityName, EOQualifier aQualifier, List aSortOrderingList )
+ {
+ this();
+ entityName = anEntityName;
+ qualifier = aQualifier;
+ sortOrderings = new NSArray( (Collection) aSortOrderingList );
+ }
+
+ /**
+ * Constructs a fetch specification for the specified entity type using
+ * the specified qualifier and sort ordering, distinct flag, deep flag,
+ * and hints dictionary.
+ */
+ public EOFetchSpecification( String anEntityName, EOQualifier aQualifier, NSArray aSortOrderingList,
+ boolean usesDistinct, boolean isDeep, Map aHintMap)
+ {
+ this();
+ entityName = anEntityName;
+ qualifier = aQualifier;
+ sortOrderings = new NSArray( (Collection) aSortOrderingList );
+ distinct = usesDistinct;
+ deep = isDeep;
+ hints = new NSMutableDictionary( (Map) aHintMap );
+ }
+
+ /**
+ * Convenience to return the named fetch specification from the class description
+ * corresponding to the specified entity name. Returns null if either entityName
+ * or spec name cannot be resolved.
+ */
+ public static EOFetchSpecification fetchSpecificationNamed( String name, String entityName)
+ {
+ EOClassDescription classDesc = EOClassDescription.classDescriptionForEntityName( entityName );
+ if ( classDesc == null ) return null;
+ return classDesc.fetchSpecificationNamed( name );
+ }
+
+ /**
+ * Implemented to return a new fetch specification that is a deep copy of this one.
+ */
+ public Object clone()
+ {
+ EOFetchSpecification clone = new EOFetchSpecification();
+
+ clone.fetchesRawRows = this.fetchesRawRows;
+ clone.entityName = this.entityName;
+ if ( this.hints != null )
+ clone.hints = new NSDictionary( (Map) this.hints );
+ clone.deep = this.deep;
+ clone.locksObjects = this.locksObjects;
+ if ( this.prefetchingRelationshipKeyPaths != null )
+ clone.prefetchingRelationshipKeyPaths =
+ new NSArray( (List) prefetchingRelationshipKeyPaths );
+ clone.promptsAfterFetchLimit = this.promptsAfterFetchLimit;
+ if ( this.qualifier != null )
+ clone.qualifier = this.qualifier; //FIXME: probably should clone?
+ if ( this.rawRowKeyPaths != null )
+ clone.rawRowKeyPaths = new NSArray( (List) this.rawRowKeyPaths );
+ clone.refreshesRefetchedObjects = this.refreshesRefetchedObjects;
+ clone.requiresAllQualifierBindingVariables =
+ this.requiresAllQualifierBindingVariables;
+ if ( this.sortOrderings != null )
+ clone.sortOrderings = new NSArray( (List) this.sortOrderings );
+ clone.distinct = this.distinct;
+
+ return clone;
+ }
+
+ /**
+ * Returns the name of the entity fetched by this fetch spec.
+ */
+ public String entityName()
+ {
+ return entityName;
+ }
+
+ /**
+ * Returns the current fetch limit.
+ * A fetch limit of zero indicates no fetch limit.
+ * Zero is the default.
+ */
+ public int fetchLimit()
+ {
+ return fetchLimit;
+ }
+
+ /**
+ * Returns whether this fetch spec will fetch raw rows.
+ * Default is false.
+ */
+ public boolean fetchesRawRows()
+ {
+ return fetchesRawRows;
+ }
+
+ /**
+ * Returns a fetch specification that resolves the bindings
+ * in the specified map.
+ */
+ public EOFetchSpecification
+ fetchSpecificationWithQualifierBindings(Map aBindingMap)
+ {
+ throw new WotonomyException( "Not implemented yet" );
+ }
+
+ /**
+ * Returns a Map containing the hints used by this fetch specification,
+ * or null if no hints have been specified.
+ */
+ public NSDictionary hints()
+ {
+ if ( hints == null ) return null;
+ return new NSDictionary( (NSDictionary) hints );
+ }
+
+ /**
+ * Returns whether entities related to the primary
+ * entities are fetched by this fetch spec. If true, all relationships
+ * whose destinations meet the qualifier criteria will be returned
+ * in addition to primary results. If false, only the primary entities
+ * will be returned. Default is true.
+ */
+ public boolean isDeep()
+ {
+ return deep;
+ }
+
+ /**
+ * Returns whether this data source should lock objects that
+ * are fetched. Default is false.
+ */
+ public boolean locksObjects()
+ {
+ return locksObjects;
+ }
+
+ /***
+ * Returns a List of relationships for the fetched objects that
+ * should also be fetched, or null if no such list has been specified.
+ * Use this to avoid additional calls to the server to fetch
+ * relationships that you know you will use.
+ * NOTE: wotonomy allows you to specify non-relational keys
+ * as well.
+ */
+ public NSArray prefetchingRelationshipKeyPaths()
+ {
+ return prefetchingRelationshipKeyPaths;
+ }
+
+ /**
+ * Returns whether the user should be prompted to continue
+ * when the fetch limit has been exceeded.
+ * Default is false.
+ */
+ public boolean promptsAfterFetchLimit()
+ {
+ return promptsAfterFetchLimit;
+ }
+
+ /**
+ * Returns the qualifier used by this fetch specification,
+ * or null if none has been specified.
+ */
+ public EOQualifier qualifier()
+ {
+ return qualifier;
+ }
+
+ /**
+ * Returns a List of keys or key paths for which
+ * values should be returned when fetching raw rows,
+ * or null if no raw row key paths have been specified.
+ */
+ public NSArray rawRowKeyPaths()
+ {
+ return rawRowKeyPaths;
+ }
+
+ /**
+ * Returns whether fetched objects should replace
+ * modified versions already fetched into an editing context.
+ * If true, those changes will be lost.
+ * Default is false.
+ */
+ public boolean refreshesRefetchedObjects()
+ {
+ return refreshesRefetchedObjects;
+ }
+
+ /**
+ * Returns whether all qualifier bindings must be specified
+ * in order to fetch. If true, an exception is thrown if
+ * unspecified bindings exist. If false, unspecified bindings
+ * will be removed from the qualifier. Default is false.
+ */
+ public boolean requiresAllQualifierBindingVariables()
+ {
+ return requiresAllQualifierBindingVariables;
+ }
+
+ /**
+ * Sets the name of the entity fetched by this spec.
+ */
+ public void setEntityName(String aName)
+ {
+ entityName = aName;
+ }
+
+ /**
+ * Sets whether this fetch spec will return raw rows.
+ */
+ public void setFetchesRawRows(boolean shouldFetchRawRows)
+ {
+ fetchesRawRows = shouldFetchRawRows;
+ }
+
+ /**
+ * Sets the limit on the number of records returned for this fetch spec.
+ * Zero indicates no limit on fetches.
+ */
+ public void setFetchLimit(int aLimit)
+ {
+ fetchLimit = aLimit;
+ }
+
+ /**
+ * Sets the hints passed by this fetch spec.
+ */
+ public void setHints(Map aHintMap)
+ {
+ if ( aHintMap == null )
+ {
+ hints = null;
+ }
+ else
+ {
+ hints = new NSDictionary( (Map) aHintMap );
+ }
+ }
+
+ /**
+ * Sets whether this fetch specification fetches deeply.
+ */
+ public void setIsDeep(boolean isDeep)
+ {
+ deep = isDeep;
+ }
+
+ /**
+ * Sets whether this fetch spec locks objects that
+ * are returned by the fetch.
+ */
+ public void setLocksObjects(boolean shouldLockObjects)
+ {
+ locksObjects = shouldLockObjects;
+ }
+
+ /**
+ * Sets the prefetch key paths that should be used as an optimization
+ * hint to the server. NOTE: wotonomy allows you to specify non-relationship
+ * keys as well.
+ */
+ public void setPrefetchingRelationshipKeyPaths(List aKeyPathList)
+ {
+ if ( aKeyPathList == null )
+ {
+ prefetchingRelationshipKeyPaths = null;
+ }
+ else
+ {
+ prefetchingRelationshipKeyPaths = new NSArray( (List) aKeyPathList );
+ }
+ }
+
+ /**
+ * Sets whether the user should be prompted when the fetch limit has been
+ * reached.
+ */
+ public void setPromptsAfterFetchLimit(boolean shouldPrompt)
+ {
+ promptsAfterFetchLimit = shouldPrompt;
+ }
+
+ /**
+ * Sets the qualifier used by this fetch specification.
+ */
+ public void setQualifier(EOQualifier aQualifier)
+ {
+ qualifier = aQualifier;
+ }
+
+ /**
+ * Sets the key paths to be returned if this fetch spec
+ * is returning raw rows.
+ */
+ public void setRawRowKeyPaths(List aKeyPathList)
+ {
+ if ( aKeyPathList == null )
+ {
+ rawRowKeyPaths = null;
+ }
+ else
+ {
+ rawRowKeyPaths = new NSArray( (List) aKeyPathList );
+ }
+ }
+
+ /**
+ * Sets whether modified objects in an editing context should
+ * be replaced by newer versions returned by this fetch spec.
+ */
+ public void setRefreshesRefetchedObjects(boolean shouldRefresh)
+ {
+ refreshesRefetchedObjects = shouldRefresh;
+ }
+
+ /**
+ * Sets whether this fetch spec should require all bindings to be
+ * resolved before executing.
+ */
+ public void setRequiresAllQualifierBindingVariables(boolean shouldRequireAll)
+ {
+ requiresAllQualifierBindingVariables = shouldRequireAll;
+ }
+
+ /**
+ * Sets the sort orderings used by this fetch spec.
+ */
+ public void setSortOrderings(List aSortList)
+ {
+ if ( aSortList == null )
+ {
+ sortOrderings = null;
+ }
+ else
+ {
+ sortOrderings = new NSArray( (List) aSortList );
+ }
+ }
+
+ /**
+ * Sets whether this fetch spec should return only distinct
+ * objects.
+ */
+ public void setUsesDistinct(boolean shouldUseDistinct)
+ {
+ distinct = shouldUseDistinct;
+ }
+
+ /**
+ * Returns a List of the sort orderings used by this fetch spec,
+ * or null if none have been specified.
+ */
+ public NSArray sortOrderings()
+ {
+ return sortOrderings;
+ }
+
+ /**
+ * Returns a string representation of this fetch specification.
+ */
+ public String toString()
+ {
+ return "[FetchSpecification:qualifier=("+qualifier+"),sortOrderings="+sortOrderings+"]";
+ }
+
+ /**
+ * Returns whether this fetch specification will return only one
+ * reference to each distinct object returned by the fetch.
+ * Default is false.
+ */
+ public boolean usesDistinct()
+ {
+ return distinct;
+ }
+
+ public void encodeWithKeyValueArchiver(EOKeyValueArchiver arch) {
+ arch.encodeObject("EOFetchSpecification", "class");
+ arch.encodeObject(entityName(), "entityName");
+ arch.encodeInt(fetchLimit(), "fetchLimit");
+
+ //flags
+ if (isDeep())
+ arch.encodeObject("YES", "isDeep");
+ arch.encodeObject(qualifier(), "qualifier");
+ if (refreshesRefetchedObjects())
+ arch.encodeObject("YES", "refreshesRefetchedObjects");
+ if (locksObjects())
+ arch.encodeObject("YES", "locksObjects");
+ if (fetchesRawRows())
+ arch.encodeObject("YES", "fetchesRawRows");
+ if (promptsAfterFetchLimit())
+ arch.encodeObject("YES", "promptsAfterFetchLimit");
+ if (requiresAllQualifierBindingVariables())
+ arch.encodeObject("YES", "requiresAllQualifierBindingVariables");
+ if (usesDistinct())
+ arch.encodeObject("YES", "usesDistinct");
+
+ //encode arrays
+ if (sortOrderings() != null) {
+ NSMutableArray arr = new NSMutableArray(sortOrderings().count());
+ for (int i = 0; i < sortOrderings.count(); i++) {
+ EOSortOrdering so = (EOSortOrdering)sortOrderings().objectAtIndex(i);
+ EOKeyValueArchiver ar2 = new EOKeyValueArchiver();
+ so.encodeWithKeyValueArchiver(ar2);
+ arr.addObject(ar2.dictionary());
+ }
+ arch.encodeObject(arr, "sortOrderings");
+ }
+ if (rawRowKeyPaths != null && rawRowKeyPaths.count() > 0)
+ arch.encodeObject(rawRowKeyPaths, "rawRowKeyPaths");
+ if (prefetchingRelationshipKeyPaths != null && prefetchingRelationshipKeyPaths.count() > 0)
+ arch.encodeObject(rawRowKeyPaths, "prefetchingRelationshipKeyPaths");
+ if (hints != null && hints.count() > 0)
+ arch.encodeObject(hints, "hints");
+ }
+
+ public static Object decodeWithKeyValueUnarchiver(EOKeyValueUnarchiver unarch) {
+ EOFetchSpecification fs = new EOFetchSpecification();
+ fs.setEntityName((String)unarch.decodeObjectForKey("entityName"));
+ fs.setFetchLimit(unarch.decodeIntForKey("fetchLimit"));
+ fs.setIsDeep(unarch.decodeBoolForKey("isDeep"));
+ fs.setRefreshesRefetchedObjects(unarch.decodeBoolForKey("refreshesRefetchedObjects"));
+
+ //Sort orderings
+ NSArray arr = (NSArray)unarch.decodeObjectForKey("sortOrderings");
+ if (arr != null && arr.count() > 0) {
+ NSMutableArray orderings = new NSMutableArray(arr.count());
+ for (int i = 0; i < arr.count(); i++) {
+ NSDictionary so = (NSDictionary)arr.objectAtIndex(i);
+ String selname = (String)so.objectForKey("selectorName");
+ NSSelector selector = EOSortOrdering.CompareAscending;
+ if (selname.startsWith("compareDescending"))
+ selector = EOSortOrdering.CompareDescending;
+ else if (selname.startsWith("compareCaseInsensitiveAscending"))
+ selector = EOSortOrdering.CompareCaseInsensitiveAscending;
+ else if (selname.startsWith("compareCaseInsensitiveDescending"))
+ selector = EOSortOrdering.CompareCaseInsensitiveDescending;
+ EOSortOrdering eoso = new EOSortOrdering((String)so.objectForKey("key"), selector);
+ orderings.addObject(eoso);
+ }
+ fs.setSortOrderings(orderings);
+ }
+ //raw rows
+ arr = (NSArray)unarch.decodeObjectForKey("rawRowKeyPaths");
+ if (arr != null && arr.count() > 0) {
+ fs.setFetchesRawRows(true);
+ fs.setRawRowKeyPaths(arr);
+ }
+ //qualifier
+ fs.setQualifier((EOQualifier)unarch.decodeObjectForKey("qualifier"));
+ return fs;
+ }
+
+}
+
+/*
+ * $Log$
+ * Revision 1.2 2006/02/16 16:47:14 cgruber
+ * Move some classes in to "internal" packages and re-work imports, etc.
+ *
+ * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions.
+ *
+ * Revision 1.1 2006/02/16 13:19:57 cgruber
+ * Check in all sources in eclipse-friendly maven-enabled packages.
+ *
+ * Revision 1.4 2003/08/11 18:19:01 chochos
+ * encoding/decoding with EOKeyValueArchiving now works properly
+ *
+ * Revision 1.3 2003/08/09 01:22:20 chochos
+ * implements EOKeyValueArchiving (and unarchiving)
+ *
+ * Revision 1.2 2001/11/24 17:32:57 mpowers
+ * We now have a real implementation.
+ *
+ * Revision 1.1 2001/02/05 03:45:37 mpowers
+ * Starting work on EOEditingContext.
+ *
+ *
+ */
+
+