/* * ==================================================================== * * The ObjectStyle Group Software License, Version 1.0 * * Copyright (c) 2006 The ObjectStyle Group and individual authors of the * software. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, must * include the following acknowlegement: "This product includes software * developed by the ObjectStyle Group (http://objectstyle.org/)." Alternately, * this acknowlegement may appear in the software itself, if and wherever such * third-party acknowlegements normally appear. * * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse or * promote products derived from this software without prior written permission. * For written permission, please contact andrus@objectstyle.org. * * 5. Products derived from this software may not be called "ObjectStyle" nor * may "ObjectStyle" appear in their names without prior written permission of * the ObjectStyle Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * OBJECTSTYLE GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many individuals on * behalf of the ObjectStyle Group. For more information on the ObjectStyle * Group, please see <http://objectstyle.org/>. * */ package org.objectstyle.wolips.eomodeler.core.model; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.objectstyle.wolips.baseforplugins.util.StringUtils; import org.objectstyle.wolips.eomodeler.core.model.qualifier.EOQualifier; import org.objectstyle.wolips.eomodeler.core.model.qualifier.EOQualifierBinding; public class EOFetchSpecification extends UserInfoableEOModelObject<EOEntity> implements IEOEntityRelative, ISortableEOModelObject, PropertyChangeListener { public static final String NAME = "name"; public static final String SORT_ORDERING = "sortOrdering"; public static final String SORT_ORDERINGS = "sortOrderings"; public static final String QUALIFIER = "qualifier"; public static final String QUALIFIER_STRING = "qualifierString"; public static final String ENTITY = "entity"; public static final String FETCH_LIMIT = "fetchLimit"; public static final String DEEP = "deep"; public static final String LOCKS_OBJECTS = "locksObjects"; public static final String PREFETCHING_RELATIONSHIP_KEY_PATH = "prefetchingRelationshipKeyPath"; public static final String PREFETCHING_RELATIONSHIP_KEY_PATHS = "prefetchingRelationshipKeyPaths"; public static final String PROMPTS_AFTER_FETCH_LIMIT = "promptsAfterFetchLimit"; public static final String RAW_ROW_KEY_PATH = "rawRowKeyPath"; public static final String RAW_ROW_KEY_PATHS = "rawRowKeyPaths"; public static final String REFRESHES_REFETCHED_OBJECTS = "refreshesRefetchedObjects"; public static final String REQUIRES_ALL_QUALIFIER_BINDING_VARIABLES = "requiresAllQualifierBindingVariables"; public static final String USES_DISTINCT = "usesDistinct"; public static final String SHARES_OBJECTS = "sharesObjects"; public static final String CUSTOM_QUERY_EXPRESSION = "customQueryExpression"; public static final String STORED_PROCEDURE = "storedProcedure"; private EOEntity myEntity; private String myName; private String myClass; private Integer myFetchLimit; private Boolean myDeep; private Boolean myLocksObjects; private Set<String> myPrefetchingRelationshipKeyPaths; private Boolean myPromptsAfterFetchLimit; private Set<String> myRawRowKeyPaths; private Boolean myRefreshesRefetchedObjects; private Boolean myRequiresAllQualifierBindingVariables; private Boolean myUsesDistinct; private List<EOSortOrdering> mySortOrderings; private EOQualifier myQualifier; private String myQualifierString; private EOModelMap myFetchSpecMap; private Boolean mySharesObjects; private String myCustomQueryExpression; private EOStoredProcedure myStoredProcedure; public EOFetchSpecification(String _name) { myName = _name; myClass = "EOFetchSpecification"; mySortOrderings = new LinkedList<EOSortOrdering>(); myFetchSpecMap = new EOModelMap(); myPrefetchingRelationshipKeyPaths = new TreeSet<String>(); } public List<EOQualifierBinding> getAllBindings() { return EOQualifierFactory.getQualifierBindingsFromQualifier(getEntity(), getQualifier()); } public Set<EOQualifierBinding> getDistinctBindings() { Map<String, EOQualifierBinding> bindings = new HashMap<String, EOQualifierBinding>(); for (EOQualifierBinding binding : getAllBindings()) { if (!bindings.containsKey(binding.getName())) { bindings.put(binding.getName(), binding); } } return new PropertyListSet<EOQualifierBinding>(bindings.values()); } public Set<EOQualifierBinding> getQualifierOrderDistinctBindings() { LinkedHashMap<String, EOQualifierBinding> bindings = new LinkedHashMap<String, EOQualifierBinding>(); for (EOQualifierBinding binding : getAllBindings()) { if (!bindings.containsKey(binding.getName())) { bindings.put(binding.getName(), binding); } } return new LinkedHashSet<EOQualifierBinding>(bindings.values()); } public Set getReferenceFailures() { return new HashSet(); } public void _setEntity(EOEntity _entity) { myEntity = _entity; } public void propertyChange(PropertyChangeEvent _event) { Object source = _event.getSource(); if (source instanceof EOSortOrdering) { firePropertyChange(EOFetchSpecification.SORT_ORDERING, null, source); } } protected void _propertyChanged(String _propertyName, Object _oldValue, Object _newValue) { if (myEntity != null) { myEntity._fetchSpecificationChanged(this, _propertyName, _oldValue, _newValue); } } // public int hashCode() { // return ((myEntity == null) ? 1 : myEntity.hashCode()) * ((myName == null) ? super.hashCode() : myName.hashCode()); // } // // public boolean equals(Object _obj) { // boolean equals = false; // if (_obj instanceof EOFetchSpecification) { // EOFetchSpecification fetchSpec = (EOFetchSpecification) _obj; // equals = (fetchSpec == this) || (ComparisonUtils.equals(fetchSpec.myEntity, myEntity) && ComparisonUtils.equals(fetchSpec.myName, myName)); // } // return equals; // } public void setName(String _name) throws DuplicateFetchSpecNameException { setName(_name, true); } public void setName(String _name, boolean _fireEvents) throws DuplicateFetchSpecNameException { if (myEntity != null) { myEntity._checkForDuplicateFetchSpecName(this, _name, null); } String oldName = myName; myName = _name; if (_fireEvents) { firePropertyChange(EOFetchSpecification.NAME, oldName, myName); } } public String getName() { return myName; } public String getUppercaseUnderscoreName() { return StringUtils.camelCaseToUnderscore(getName()).toUpperCase(); } public String getCapitalizedName() { String name = getName(); if (name != null) { name = StringUtils.toUppercaseFirstLetter(name); } return name; } public String getInitialLowercaseName() { String name = getName(); if (name != null) { name = StringUtils.toLowercaseFirstLetter(name); } return name; } public void addSortOrdering(EOSortOrdering _sortOrdering, boolean _fireEvents) { if (_fireEvents) { List<EOSortOrdering> oldSortOrderings = mySortOrderings; mySortOrderings = new LinkedList<EOSortOrdering>(mySortOrderings); mySortOrderings.add(_sortOrdering); firePropertyChange(EOFetchSpecification.SORT_ORDERINGS, oldSortOrderings, mySortOrderings); } else { mySortOrderings.add(_sortOrdering); } _sortOrdering.addPropertyChangeListener(this); } public void removeSortOrdering(EOSortOrdering _sortOrdering, boolean _fireEvents) { if (_fireEvents) { List<EOSortOrdering> oldSortOrderings = mySortOrderings; mySortOrderings = new LinkedList<EOSortOrdering>(mySortOrderings); mySortOrderings.remove(_sortOrdering); firePropertyChange(EOFetchSpecification.SORT_ORDERINGS, oldSortOrderings, mySortOrderings); } else { mySortOrderings.remove(_sortOrdering); } _sortOrdering.removePropertyChangeListener(this); } public void setSortOrderings(List<EOSortOrdering> _sortOrderings, boolean _fireEvents) { if (_fireEvents) { List<EOSortOrdering> oldSortOrderings = mySortOrderings; if (oldSortOrderings != null) { for (EOSortOrdering sortOrdering : oldSortOrderings) { sortOrdering.removePropertyChangeListener(this); } } mySortOrderings = _sortOrderings; if (mySortOrderings != null) { for (EOSortOrdering sortOrdering : mySortOrderings) { sortOrdering.addPropertyChangeListener(this); } } firePropertyChange(EOFetchSpecification.SORT_ORDERINGS, oldSortOrderings, mySortOrderings); } else { mySortOrderings = _sortOrderings; } } public List<EOSortOrdering> getSortOrderings() { return mySortOrderings; } public Boolean getSharesObjects() { return isSharesObjects(); } public Boolean isSharesObjects() { return mySharesObjects; } public void setSharesObjects(Boolean _sharesObjects) { setSharesObjects(_sharesObjects, true); } public void setSharesObjects(Boolean _sharesObjects, boolean _fireEvents) { Boolean oldSharesObjects = mySharesObjects; mySharesObjects = _sharesObjects; if (_fireEvents) { firePropertyChange(EOFetchSpecification.SHARES_OBJECTS, oldSharesObjects, mySharesObjects); } } public void useQualifier() { setCustomQueryExpression(null); setStoredProcedure(null); } public boolean isUsingQualifier() { return myCustomQueryExpression == null && myStoredProcedure == null; } public boolean isUsingCustomQuery() { return myCustomQueryExpression != null && myStoredProcedure == null; } public boolean isUsingStoredProcedure() { return myCustomQueryExpression == null && myStoredProcedure != null; } public void useCustomQueryExpression() { setCustomQueryExpression(""); } public void setCustomQueryExpression(String _customQueryExpression) { if (_customQueryExpression != null) { setStoredProcedure(null); } if (_customQueryExpression != null || myCustomQueryExpression != null) { String oldCustomQueryExpression = myCustomQueryExpression; myCustomQueryExpression = _customQueryExpression; firePropertyChange(EOFetchSpecification.CUSTOM_QUERY_EXPRESSION, oldCustomQueryExpression, myCustomQueryExpression); } } public String getCustomQueryExpression() { return myCustomQueryExpression; } public void setStoredProcedure(EOStoredProcedure _storedProcedure) { if (_storedProcedure != null) { setCustomQueryExpression(null); } if (_storedProcedure != null || myStoredProcedure != null) { EOStoredProcedure oldStoredProcedure = myStoredProcedure; myStoredProcedure = _storedProcedure; firePropertyChange(EOFetchSpecification.STORED_PROCEDURE, oldStoredProcedure, myStoredProcedure); } } public EOStoredProcedure getStoredProcedure() { return myStoredProcedure; } public void setQualifier(EOQualifier _qualifier) { setQualifier(_qualifier, true); } public void setQualifier(EOQualifier _qualifier, boolean updateQualifierString) { EOQualifier oldQualifier = myQualifier; myQualifier = _qualifier; firePropertyChange(EOFetchSpecification.QUALIFIER, oldQualifier, myQualifier); if (updateQualifierString) { setQualifierString(EOQualifierFactory.toString(myQualifier), false); } } public EOQualifier getQualifier() { return myQualifier; } public void setQualifierString(String _qualifierString) { setQualifierString(_qualifierString, true); } public void setQualifierString(String _qualifierString, boolean updateQualifier) { String oldQualifierString = myQualifierString; myQualifierString = _qualifierString; if (updateQualifier) { try { EOQualifier qualifier = EOQualifierFactory.fromString(_qualifierString); setQualifier(qualifier, false); } catch (RuntimeException e) { e.printStackTrace(); setQualifier(null, false); throw e; } finally { firePropertyChange(EOFetchSpecification.QUALIFIER_STRING, oldQualifierString, myQualifierString); } } else { firePropertyChange(EOFetchSpecification.QUALIFIER_STRING, oldQualifierString, myQualifierString); } } public String getQualifierString() { return myQualifierString; } public void setEntity(EOEntity _entity) { EOEntity oldEntity = myEntity; _setEntity(_entity); firePropertyChange(EOFetchSpecification.ENTITY, oldEntity, myEntity); } public EOEntity getEntity() { return myEntity; } public Boolean isDeep() { return myDeep; } public Boolean getDeep() { return isDeep(); } public void setDeep(Boolean _deep) { Boolean oldDeep = myDeep; myDeep = _deep; firePropertyChange(EOFetchSpecification.DEEP, oldDeep, myDeep); } public Integer getFetchLimit() { return myFetchLimit; } public void setFetchLimit(Integer _fetchLimit) { Integer oldFetchLimit = myFetchLimit; myFetchLimit = _fetchLimit; firePropertyChange(EOFetchSpecification.FETCH_LIMIT, oldFetchLimit, myFetchLimit); } public Boolean isLocksObjects() { return myLocksObjects; } public Boolean getLocksObjects() { return isLocksObjects(); } public void setLocksObjects(Boolean _locksObjects) { Boolean oldLocksObjects = myLocksObjects; myLocksObjects = _locksObjects; firePropertyChange(EOFetchSpecification.LOCKS_OBJECTS, oldLocksObjects, myLocksObjects); } public Collection<String> getPrefetchingRelationshipKeyPaths() { return myPrefetchingRelationshipKeyPaths; } public void addPrefetchingRelationshipKeyPath(String _prefetchingRelationshipKeyPath, boolean _fireEvents) { if (_fireEvents) { Set<String> oldPrefetchingRelationshipKeyPaths = myPrefetchingRelationshipKeyPaths; myPrefetchingRelationshipKeyPaths = new TreeSet<String>(); if (oldPrefetchingRelationshipKeyPaths != null) { myPrefetchingRelationshipKeyPaths.addAll(oldPrefetchingRelationshipKeyPaths); } myPrefetchingRelationshipKeyPaths.add(_prefetchingRelationshipKeyPath); firePropertyChange(EOFetchSpecification.PREFETCHING_RELATIONSHIP_KEY_PATHS, oldPrefetchingRelationshipKeyPaths, myPrefetchingRelationshipKeyPaths); } else { myPrefetchingRelationshipKeyPaths.add(_prefetchingRelationshipKeyPath); } } public void removePrefetchingRelationshipKeyPath(String _prefetchingRelationshipKeyPath, boolean _fireEvents) { if (_fireEvents) { Set<String> oldPrefetchingRelationshipKeyPaths = myPrefetchingRelationshipKeyPaths; if (oldPrefetchingRelationshipKeyPaths != null) { myPrefetchingRelationshipKeyPaths = new TreeSet<String>(); myPrefetchingRelationshipKeyPaths.addAll(oldPrefetchingRelationshipKeyPaths); myPrefetchingRelationshipKeyPaths.remove(_prefetchingRelationshipKeyPath); } firePropertyChange(EOFetchSpecification.PREFETCHING_RELATIONSHIP_KEY_PATHS, oldPrefetchingRelationshipKeyPaths, myPrefetchingRelationshipKeyPaths); } else { myPrefetchingRelationshipKeyPaths.remove(_prefetchingRelationshipKeyPath); } } public void fetchEnterpriseObjects() { Set<String> oldRawRowKeyPaths = myRawRowKeyPaths; myRawRowKeyPaths = null; firePropertyChange(EOFetchSpecification.RAW_ROW_KEY_PATHS, oldRawRowKeyPaths, myRawRowKeyPaths); } public void fetchAllAttributesAsRawRows() { Set<String> oldRawRowKeyPaths = myRawRowKeyPaths; myRawRowKeyPaths = new TreeSet<String>(); firePropertyChange(EOFetchSpecification.RAW_ROW_KEY_PATHS, oldRawRowKeyPaths, myRawRowKeyPaths); } public void fetchSpecificAttributesAsRawRows() { if (myEntity != null) { for (String attributeName : myEntity.getAttributeNames()) { addRawRowKeyPath(attributeName, true); } } } public boolean isFetchEnterpriseObjects() { return myRawRowKeyPaths == null; } public boolean isFetchAllAttributesAsRawRows() { return myRawRowKeyPaths != null && myRawRowKeyPaths.isEmpty(); } public boolean isFetchSpecificAttributesAsRawRows() { return myRawRowKeyPaths != null && !myRawRowKeyPaths.isEmpty(); } public void addRawRowKeyPath(String _rawRowKeyPath, boolean _fireEvents) { if (_fireEvents) { Set<String> oldRawRowKeyPaths = myRawRowKeyPaths; myRawRowKeyPaths = new TreeSet<String>(); if (oldRawRowKeyPaths != null) { myRawRowKeyPaths.addAll(oldRawRowKeyPaths); } myRawRowKeyPaths.add(_rawRowKeyPath); firePropertyChange(EOFetchSpecification.RAW_ROW_KEY_PATHS, oldRawRowKeyPaths, myRawRowKeyPaths); } else { myRawRowKeyPaths.add(_rawRowKeyPath); } } public void removeRawRowKeyPath(String _rawRowKeyPath, boolean _fireEvents) { if (_fireEvents) { Set<String> oldRawRowKeyPaths = myRawRowKeyPaths; if (oldRawRowKeyPaths != null) { myRawRowKeyPaths = new TreeSet<String>(); myRawRowKeyPaths.addAll(oldRawRowKeyPaths); myRawRowKeyPaths.remove(_rawRowKeyPath); } firePropertyChange(EOFetchSpecification.RAW_ROW_KEY_PATHS, oldRawRowKeyPaths, myRawRowKeyPaths); } else { myRawRowKeyPaths.remove(_rawRowKeyPath); } } public Boolean isPromptsAfterFetchLimit() { return myPromptsAfterFetchLimit; } public Boolean getPromptsAfterFetchLimit() { return isPromptsAfterFetchLimit(); } public void setPromptsAfterFetchLimit(Boolean _promptsAfterFetchLimit) { Boolean oldPromptsAfterFetchLimit = myPromptsAfterFetchLimit; myPromptsAfterFetchLimit = _promptsAfterFetchLimit; firePropertyChange(EOFetchSpecification.PROMPTS_AFTER_FETCH_LIMIT, oldPromptsAfterFetchLimit, myPromptsAfterFetchLimit); } public Collection<String> getRawRowKeyPaths() { return myRawRowKeyPaths; } public void setRawRowKeyPaths(Set<String> _rawRowKeyPaths) { myRawRowKeyPaths = _rawRowKeyPaths; firePropertyChange(EOFetchSpecification.RAW_ROW_KEY_PATHS, null, null); } public Boolean isRefreshesRefetchedObjects() { return myRefreshesRefetchedObjects; } public Boolean getRefreshesRefetchedObjects() { return isRefreshesRefetchedObjects(); } public void setRefreshesRefetchedObjects(Boolean _refreshesRefetchedObjects) { Boolean oldRefreshesRefetchedObjects = myRefreshesRefetchedObjects; myRefreshesRefetchedObjects = _refreshesRefetchedObjects; firePropertyChange(EOFetchSpecification.REFRESHES_REFETCHED_OBJECTS, oldRefreshesRefetchedObjects, myRefreshesRefetchedObjects); } public Boolean isRequiresAllQualifierBindingVariables() { return myRequiresAllQualifierBindingVariables; } public Boolean getRequiresAllQualifierBindingVariables() { return isRequiresAllQualifierBindingVariables(); } public void setRequiresAllQualifierBindingVariables(Boolean _requiresAllQualifierBindingVariables) { Boolean oldRequiresAllQualifierBindingVariables = myRequiresAllQualifierBindingVariables; myRequiresAllQualifierBindingVariables = _requiresAllQualifierBindingVariables; firePropertyChange(EOFetchSpecification.REQUIRES_ALL_QUALIFIER_BINDING_VARIABLES, oldRequiresAllQualifierBindingVariables, myRequiresAllQualifierBindingVariables); } public Boolean isUsesDistinct() { return myUsesDistinct; } public Boolean getUsesDistinct() { return isUsesDistinct(); } public void setUsesDistinct(Boolean _usesDistinct) { Boolean oldUsesDistinct = myUsesDistinct; myUsesDistinct = _usesDistinct; firePropertyChange(EOFetchSpecification.USES_DISTINCT, oldUsesDistinct, myUsesDistinct); } @SuppressWarnings("unused") public void loadFromMap(EOModelMap _map, Set _failures) { myFetchSpecMap = _map; // "entityName" = myEntity myClass = _map.getString("class", true); myFetchLimit = _map.getInteger("fetchLimit"); myDeep = _map.getBoolean("isDeep"); myLocksObjects = _map.getBoolean("locksObjects"); myPrefetchingRelationshipKeyPaths = _map.getSet("prefetchingRelationshipKeyPaths", true); myPromptsAfterFetchLimit = _map.getBoolean("prompsAfterFetchLimit"); Map qualifierMap = _map.getMap("qualifier"); if (qualifierMap != null) { myQualifier = EOQualifierFactory.createQualifierFromQualifierMap(new EOModelMap(qualifierMap)); myQualifierString = EOQualifierFactory.toString(myQualifier); } myRawRowKeyPaths = _map.getSet("rawRowKeyPaths", true); myRefreshesRefetchedObjects = _map.getBoolean("refreshesRefetchedObjects"); myRequiresAllQualifierBindingVariables = _map.getBoolean("requiresAllQualifierBindingVariables"); myUsesDistinct = _map.getBoolean("usesDistinct"); loadUserInfo(_map); List<Map> sortOrderings = _map.getList("sortOrderings"); if (sortOrderings != null) { for (Map originalSortOrderingMap : sortOrderings) { EOModelMap sortOrderingMap = new EOModelMap(originalSortOrderingMap); EOSortOrdering sortOrdering = new EOSortOrdering(); sortOrdering.loadFromMap(sortOrderingMap); addSortOrdering(sortOrdering, false); } } Map hintsMap = _map.getMap("hints"); if (hintsMap != null) { myCustomQueryExpression = (String) hintsMap.get("EOCustomQueryExpressionHintKey"); } } public EOModelMap toMap() { EOModelMap fetchSpecMap = myFetchSpecMap.cloneModelMap(); if (myEntity != null) { fetchSpecMap.setString("entityName", myEntity.getName(), true); } fetchSpecMap.setString("class", myClass, true); fetchSpecMap.setInteger("fetchLimit", myFetchLimit); fetchSpecMap.setBoolean("isDeep", myDeep, EOModelMap.YESNO); fetchSpecMap.setBoolean("locksObjects", myLocksObjects, EOModelMap.YESNO); if (myPrefetchingRelationshipKeyPaths == null || !myPrefetchingRelationshipKeyPaths.equals(fetchSpecMap.get("prefetchingRelationshipKeyPaths"))) { fetchSpecMap.setSet("prefetchingRelationshipKeyPaths", myPrefetchingRelationshipKeyPaths, false); } fetchSpecMap.setBoolean("prompsAfterFetchLimit", myPromptsAfterFetchLimit, EOModelMap.YESNO); if (myQualifier == null) { fetchSpecMap.setMap("qualifier", null, true); } else { fetchSpecMap.setMap("qualifier", EOQualifierFactory.createQualifierMapFromQualifier(myQualifier), true); } if (myRawRowKeyPaths != null && myRawRowKeyPaths.equals(myFetchSpecMap.get("rawRowKeyPaths"))) { fetchSpecMap.setSet("rawRowKeyPaths", (Set) myFetchSpecMap.get("rawRowKeyPaths"), false); } else { fetchSpecMap.setSet("rawRowKeyPaths", myRawRowKeyPaths, false); } fetchSpecMap.setBoolean("refreshesRefetchedObjects", myRefreshesRefetchedObjects, EOModelMap.YESNO); fetchSpecMap.setBoolean("requiresAllQualifierBindingVariables", myRequiresAllQualifierBindingVariables, EOModelMap.YESNO); fetchSpecMap.setBoolean("usesDistinct", myUsesDistinct, EOModelMap.YESNO); writeUserInfo(fetchSpecMap); List<Map> sortOrderings = new LinkedList<Map>(); for (EOSortOrdering sortOrdering : mySortOrderings) { EOModelMap sortOrderingMap = sortOrdering.toMap(); sortOrderings.add(sortOrderingMap); } fetchSpecMap.setList("sortOrderings", sortOrderings, true); Map rawHintsMap = fetchSpecMap.getMap("hints", true); if (rawHintsMap == null) { rawHintsMap = new PropertyListMap(); } EOModelMap hintsMap = new EOModelMap(rawHintsMap); hintsMap.setString("EOCustomQueryExpressionHintKey", myCustomQueryExpression, false); String storedProcedureName = (myStoredProcedure != null) ? myStoredProcedure.getName() : null; hintsMap.setString("EOStoredProcedureNameHintKey", storedProcedureName, true); fetchSpecMap.setMap("hints", hintsMap, true); return fetchSpecMap; } public void resolve(Set<EOModelVerificationFailure> _failures) { Map hintsMap = myFetchSpecMap.getMap("hints"); if (hintsMap != null) { String storedProcedureName = (String) hintsMap.get("EOStoredProcedureNameHintKey"); if (storedProcedureName != null) { myStoredProcedure = myEntity.getModel().getStoredProcedureNamed(storedProcedureName); if (myStoredProcedure == null) { _failures.add(new EOModelVerificationFailure(myEntity.getModel(), this, "The fetch specification " + getName() + " specifies a stored procedure name '" + myStoredProcedure + "' which does not exist.", false)); } } } // TODO } public void verify(Set<EOModelVerificationFailure> _failures) { // TODO // if (myQualifier != null) { // myQualifier.verify(_failures); // } if (myQualifierString != null && myQualifierString.length() > 0 && myQualifier == null) { String reason; try { EOQualifierFactory.fromString(myQualifierString); reason = "Unknown failure."; } catch (Throwable t) { reason = StringUtils.getErrorMessage(t); } _failures.add(new EOModelVerificationFailure(myEntity.getModel(), this, "The fetch specification " + getName() + " specifies an invalid qualifier, and cannot be saved: " + reason, false)); } else if (myQualifier != null) { EOEntity entity = getEntity(); Set<String> qualifierKeys = EOQualifierFactory.getQualifierKeysFromQualifier(myQualifier); for (String qualifierKey : qualifierKeys) { AbstractEOAttributePath definitionPath = entity.resolveKeyPath(qualifierKey); if (definitionPath == null || !definitionPath.isValid()) { //_failures.add(new EOModelVerificationFailure(myEntity.getModel(), this, "The fetch specification " + getName() + " has a qualifier that refers to an invalid key '" + qualifierKey + "'.", false)); } } } for (EOSortOrdering sortOrdering : mySortOrderings) { sortOrdering.verify(_failures); } if (myCustomQueryExpression != null && myCustomQueryExpression.trim().length() == 0) { _failures.add(new EOModelVerificationFailure(myEntity.getModel(), this, "The fetch specification " + getName() + " has an empty custom SQL expression.", false)); } if (myCustomQueryExpression != null && myStoredProcedure != null) { _failures.add(new EOModelVerificationFailure(myEntity.getModel(), this, "The fetch specification " + getName() + " specifies a custom SQL expression AND a stored procedure name, which is invalid.", false)); } } public String getFullyQualifiedName() { return ((myEntity == null) ? "?" : myEntity.getFullyQualifiedName()) + "/fspec: " + getName(); } @Override public EOFetchSpecification _cloneModelObject() { EOFetchSpecification fetchSpec = new EOFetchSpecification(myName); fetchSpec.myClass = myClass; fetchSpec.myFetchLimit = myFetchLimit; fetchSpec.myDeep = myDeep; fetchSpec.myLocksObjects = myLocksObjects; if (myPrefetchingRelationshipKeyPaths != null) { fetchSpec.myPrefetchingRelationshipKeyPaths = new TreeSet<String>(); fetchSpec.myPrefetchingRelationshipKeyPaths.addAll(myPrefetchingRelationshipKeyPaths); } fetchSpec.myPromptsAfterFetchLimit = myPromptsAfterFetchLimit; if (myRawRowKeyPaths != null) { fetchSpec.myRawRowKeyPaths = new TreeSet<String>(); fetchSpec.myRawRowKeyPaths.addAll(myRawRowKeyPaths); } fetchSpec.myRefreshesRefetchedObjects = myRefreshesRefetchedObjects; fetchSpec.myRequiresAllQualifierBindingVariables = myRequiresAllQualifierBindingVariables; fetchSpec.myUsesDistinct = myUsesDistinct; fetchSpec.mySortOrderings.addAll(mySortOrderings); if (myQualifier != null) { fetchSpec.myQualifier = EOQualifierFactory.createQualifierFromQualifierMap(EOQualifierFactory.createQualifierMapFromQualifier(myQualifier)); } fetchSpec.mySharesObjects = mySharesObjects; _cloneUserInfoInto(fetchSpec); return fetchSpec; } @Override public Class<EOEntity> _getModelParentType() { return EOEntity.class; } public EOEntity _getModelParent() { return getEntity(); } public void _removeFromModelParent(Set<EOModelVerificationFailure> failures) { getEntity().removeFetchSpecification(this); } public void _addToModelParent(EOEntity modelParent, boolean findUniqueName, Set<EOModelVerificationFailure> failures) throws EOModelException { if (findUniqueName) { setName(modelParent.findUnusedFetchSpecificationName(getName())); } modelParent.addFetchSpecification(this); } public String toString() { return "[EOFetchSpecification: name = " + myName + "]"; } }