/*
* ====================================================================
*
* 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.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.objectstyle.woenvironment.plist.PropertyListParserException;
import org.objectstyle.woenvironment.plist.WOLPropertyListSerialization;
import org.objectstyle.wolips.baseforplugins.util.ComparisonUtils;
import org.objectstyle.wolips.baseforplugins.util.URLUtils;
import org.objectstyle.wolips.eomodeler.core.model.history.EOEntityAddedEvent;
import org.objectstyle.wolips.eomodeler.core.model.history.EOEntityDeletedEvent;
import org.objectstyle.wolips.eomodeler.core.model.history.ModelEvents;
import org.objectstyle.wolips.eomodeler.core.utils.NamingConvention;
public class EOModel extends UserInfoableEOModelObject<EOModelGroup> implements ISortableEOModelObject {
public static final String CURRENT_VERSION = "1.0.1";
public static final String DIRTY = "dirty";
public static final String ENTITY = "entity";
public static final String ADAPTOR_NAME = "adaptorName";
public static final String VERSION = "version";
public static final String NAME = "name";
public static final String ENTITIES = "entities";
public static final String STORED_PROCEDURE = "storedProcedure";
public static final String STORED_PROCEDURES = "storedProcedures";
public static final String ACTIVE_DATABASE_CONFIG = "activeDatabaseConfig";
public static final String DATABASE_CONFIG = "databaseConfig";
public static final String DATABASE_CONFIGS = "databaseConfigs";
public static final String ATTRIBUTE_NAMING_CONVENTION = "attributeNamingConvention";
public static final String ENTITY_NAMING_CONVENTION = "entityNamingConvention";
public static final String MODEL_SAVING = "modelSaving";
public static final String REVERSE_ENGINEERED = "reverseEngineered";
private EOModelGroup myModelGroup;
private String myName;
private String myVersion;
private Set<EOEntity> myEntities;
private Set<EODatabaseConfig> myDatabaseConfigs;
private EODatabaseConfig myActiveDatabaseConfig;
private Set<EOStoredProcedure> myStoredProcedures;
private Set<String> myDeletedEntityNamesInObjectStore;
private Set<String> myDeletedEntityNames;
private Set<String> myDeletedStoredProcedureNames;
private EOModelMap myModelMap;
private boolean myDirty;
private URL myModelURL;
private Set<EOAttribute> myPrototypeAttributeCache;
private ModelEvents _modelEvents;
private NamingConvention _entityNamingConvention;
private NamingConvention _attributeNamingConvention;
private boolean _reverseEngineered;
private EOLastModified _lastModified;
public EOModel(String _name) {
myName = _name;
myEntities = new HashSet<EOEntity>();
myStoredProcedures = new HashSet<EOStoredProcedure>();
myDatabaseConfigs = new HashSet<EODatabaseConfig>();
myDeletedEntityNamesInObjectStore = new PropertyListSet<String>();
myDeletedEntityNames = new PropertyListSet<String>();
myDeletedStoredProcedureNames = new PropertyListSet<String>();
myVersion = "2.1";
myModelMap = new EOModelMap();
_modelEvents = new ModelEvents();
_entityNamingConvention = NamingConvention.DEFAULT;
_attributeNamingConvention = NamingConvention.DEFAULT;
}
public EOModel(URL modelURL) throws EOModelException, IOException {
this(EOModelGroup.getModelNameForURL(modelURL));
Set<EOModelVerificationFailure> failures = new HashSet<EOModelVerificationFailure>();
loadFromURL(modelURL, failures);
if (failures.size() > 0) {
throw new EOModelException("Failed to load model from URL '" + modelURL + "': " + failures);
}
}
public EOModel(URL modelURL, Set<EOModelVerificationFailure> failures) throws EOModelException, IOException {
this(EOModelGroup.getModelNameForURL(modelURL));
loadFromURL(modelURL, failures);
}
protected void _storedProcedureChanged(EOStoredProcedure _storedProcedure, String _propertyName, Object _oldValue, Object _newValue) {
firePropertyChange(EOModel.STORED_PROCEDURE + "." + _propertyName, _oldValue, _newValue);
firePropertyChange(EOModel.STORED_PROCEDURE, null, _storedProcedure);
}
public void _setModelGroup(EOModelGroup _modelGroup) {
myModelGroup = _modelGroup;
}
public void setEntityNamingConvention(NamingConvention entityNamingConvention) {
NamingConvention oldEntityNamingConvention = _entityNamingConvention;
_entityNamingConvention = entityNamingConvention;
firePropertyChange(EOModel.ENTITY_NAMING_CONVENTION, oldEntityNamingConvention, _entityNamingConvention);
}
public NamingConvention getEntityNamingConvention() {
return _entityNamingConvention;
}
public void setAttributeNamingConvention(NamingConvention attributeNamingConvention) {
NamingConvention oldAttributeNamingConvention = _attributeNamingConvention;
_attributeNamingConvention = attributeNamingConvention;
firePropertyChange(EOModel.ATTRIBUTE_NAMING_CONVENTION, oldAttributeNamingConvention, _attributeNamingConvention);
}
public NamingConvention getAttributeNamingConvention() {
return _attributeNamingConvention;
}
public Set<EOModelReferenceFailure> getReferenceFailures() {
return new HashSet<EOModelReferenceFailure>();
}
public String guessPackageName() {
return guessPackageName(getEntities());
}
public String guessPackageName(Set<EOEntity> _entities) {
String guessPackageName = null;
for (EOEntity entity : _entities) {
String className = entity.getClassName();
if (className != null) {
int packageNameEnd = className.lastIndexOf('.');
String packageName;
if (packageNameEnd != -1) {
packageName = className.substring(0, packageNameEnd);
} else {
packageName = "";
}
// ignore blank package names ...
if (!"".equals(packageName)) {
if (guessPackageName == null) {
guessPackageName = packageName;
} else if ("".equals(guessPackageName)) {
// it can't change from ""
} else if (!guessPackageName.equals(packageName)) {
guessPackageName = "";
// if (guessPackageName.startsWith(packageName)) {
// guessPackageName = packageName;
// } else if (packageName.startsWith(guessPackageName)) {
// // leave it as is
// } else {
// int lastMatchingIndex = -1;
// for (int index = 0; index < guessPackageName.length() && index < packageName.length(); index++) {
// if (guessPackageName.charAt(index) == packageName.charAt(index)) {
// lastMatchingIndex = index;
// } else {
// break;
// }
// }
// if (lastMatchingIndex != -1) {
// guessPackageName = guessPackageName.substring(0, lastMatchingIndex);
// if (guessPackageName.endsWith(".")) {
// guessPackageName = guessPackageName.substring(0, guessPackageName.length() - 1);
// }
// } else {
// guessPackageName = "";
// }
// }
}
}
}
}
return guessPackageName;
}
public EOEntity addBlankEntity(String name) throws DuplicateNameException {
String newEntityName = findUnusedEntityName(name);
EOEntity entity = new EOEntity(newEntityName);
entity.guessExternalNameInModel(this);
entity.guessClassNameInModel(this);
addEntity(entity);
if (myModelGroup != null && myModelGroup.hasProjectWonder()) {
EOAttribute pk = new EOAttribute("id");
pk.setPrototype(getPrototypeAttributeNamed("id"));
pk.setColumnName("id");
pk.setPrimaryKey(Boolean.TRUE);
pk.setClassProperty(Boolean.FALSE);
pk.setUsedForLocking(Boolean.TRUE);
entity.addAttribute(pk);
}
return entity;
}
public boolean isEditing() {
EOModelGroup modelGroup = getModelGroup();
boolean editing = (modelGroup == null || getName().equals(modelGroup.getEditingModelName()));
return editing;
}
public boolean isReverseEngineered() {
return _reverseEngineered;
}
public void setReverseEngineered(boolean reverseEngineered) {
Boolean oldReverseEngineered = Boolean.valueOf(_reverseEngineered);
_reverseEngineered = reverseEngineered;
firePropertyChange(EOModel.REVERSE_ENGINEERED, oldReverseEngineered, Boolean.valueOf(_reverseEngineered));
}
public boolean isDirty() {
return myDirty;
}
public void setDirty(boolean _dirty) {
Boolean oldDirty = Boolean.valueOf(myDirty);
myDirty = _dirty;
firePropertyChange(EOModel.DIRTY, oldDirty, Boolean.valueOf(myDirty));
}
protected void firePropertyChange(String _propertyName, Object _oldValue, Object _newValue) {
super.firePropertyChange(_propertyName, _oldValue, _newValue);
}
protected void _propertyChanged(String _propertyName, Object _oldValue, Object _newValue) {
if (!myDirty && !EOModel.DIRTY.equals(_propertyName) && !EOModel.MODEL_SAVING.equals(_propertyName)) {
setDirty(true);
}
if (myModelGroup != null) {
myModelGroup._modelChanged(this, _propertyName, _oldValue, _newValue);
}
}
protected void _entityChanged(EOEntity _entity, String _propertyName, Object _oldValue, Object _newValue) {
firePropertyChange(EOModel.ENTITY + "." + _propertyName, _oldValue, _newValue);
firePropertyChange(EOModel.ENTITY, null, _entity);
}
protected void _databaseConfigChanged(EODatabaseConfig _databaseConfig, String _propertyName, Object _oldValue, Object _newValue) {
firePropertyChange(EOModel.DATABASE_CONFIG + "." + _propertyName, _oldValue, _newValue);
firePropertyChange(EOModel.DATABASE_CONFIG, null, _databaseConfig);
if (_databaseConfig == myActiveDatabaseConfig) {
clearCachedPrototypes(null, false);
}
}
public EODatabaseConfig getDatabaseConfigNamed(String _name) {
EODatabaseConfig matchingDatabaseConfig = null;
Iterator<EODatabaseConfig> databaseConfigsIter = myDatabaseConfigs.iterator();
while (matchingDatabaseConfig == null && databaseConfigsIter.hasNext()) {
EODatabaseConfig entity = databaseConfigsIter.next();
if (ComparisonUtils.equals(entity.getName(), _name)) {
matchingDatabaseConfig = entity;
}
}
return matchingDatabaseConfig;
}
public String findUnusedDatabaseConfigName(String _newName) {
return _findUnusedName(_newName, "getDatabaseConfigNamed");
}
public void _checkForDuplicateDatabaseConfigName(EODatabaseConfig _databaseConfig, String _newName, Set<EOModelVerificationFailure> _failures) throws DuplicateDatabaseConfigNameException {
EODatabaseConfig existingDatabaseConfig = getDatabaseConfigNamed(_newName);
if (existingDatabaseConfig != null && existingDatabaseConfig != _databaseConfig) {
if (_failures == null) {
throw new DuplicateDatabaseConfigNameException(_newName, this);
}
String unusedName = findUnusedDatabaseConfigName(_newName);
existingDatabaseConfig.setName(unusedName, true);
_failures.add(new DuplicateDatabaseConfigFailure(this, _newName, unusedName));
}
}
public EODatabaseConfig addBlankDatabaseConfig(String _name) throws DuplicateNameException {
String newDatabaseConfigNameBase = _name;
String newDatabaseConfigName = findUnusedDatabaseConfigName(newDatabaseConfigNameBase);
EODatabaseConfig databaseConfig = new EODatabaseConfig(newDatabaseConfigName);
addDatabaseConfig(databaseConfig);
return databaseConfig;
}
public boolean canConvertDatabaseConfigsToSingleConnectionDictionary() {
boolean canConvertDatabaseConfigsToSingleConnectionDictionary;
if (myDatabaseConfigs == null || myDatabaseConfigs.size() == 0) {
canConvertDatabaseConfigsToSingleConnectionDictionary = true;
}
else if (myDatabaseConfigs.size() == 1) {
EODatabaseConfig databaseConfig = getDatabaseConfigs().iterator().next();
canConvertDatabaseConfigsToSingleConnectionDictionary = databaseConfig.canConvertToConnectionDictionary();
}
else {
canConvertDatabaseConfigsToSingleConnectionDictionary = false;
}
return canConvertDatabaseConfigsToSingleConnectionDictionary;
}
public void addDatabaseConfig(EODatabaseConfig _databaseConfig) throws DuplicateNameException {
addDatabaseConfig(_databaseConfig, true, null);
}
public void addDatabaseConfig(EODatabaseConfig _databaseConfig, boolean _fireEvents, Set<EOModelVerificationFailure> _failures) throws DuplicateNameException {
_databaseConfig._setModel(this);
_checkForDuplicateDatabaseConfigName(_databaseConfig, _databaseConfig.getName(), _failures);
_databaseConfig.pasted();
if (_fireEvents) {
Set<EODatabaseConfig> oldDatabaseConfigs = null;
oldDatabaseConfigs = myDatabaseConfigs;
Set<EODatabaseConfig> newEntities = new HashSet<EODatabaseConfig>();
newEntities.addAll(myDatabaseConfigs);
newEntities.add(_databaseConfig);
myDatabaseConfigs = newEntities;
firePropertyChange(EOModel.DATABASE_CONFIGS, oldDatabaseConfigs, myDatabaseConfigs);
if (myActiveDatabaseConfig == null) {
setActiveDatabaseConfig(_databaseConfig);
}
} else {
myDatabaseConfigs.add(_databaseConfig);
}
}
public void removeDatabaseConfig(EODatabaseConfig _databaseConfig) {
if (ComparisonUtils.equals(myActiveDatabaseConfig, _databaseConfig)) {
EODatabaseConfig newActiveDatabaseConfig = null;
if (!myDatabaseConfigs.isEmpty()) {
Iterator<EODatabaseConfig> databaseConfigsIter = myDatabaseConfigs.iterator();
while (newActiveDatabaseConfig == null && databaseConfigsIter.hasNext()) {
EODatabaseConfig otherDatabaseConfig = databaseConfigsIter.next();
if (otherDatabaseConfig != _databaseConfig) {
newActiveDatabaseConfig = otherDatabaseConfig;
}
}
}
setActiveDatabaseConfig(newActiveDatabaseConfig);
}
Set<EODatabaseConfig> oldDatabaseConfigs = myDatabaseConfigs;
Set<EODatabaseConfig> newDatabaseConfigs = new HashSet<EODatabaseConfig>();
newDatabaseConfigs.addAll(myDatabaseConfigs);
newDatabaseConfigs.remove(_databaseConfig);
myDatabaseConfigs = newDatabaseConfigs;
firePropertyChange(EOModel.DATABASE_CONFIGS, oldDatabaseConfigs, myDatabaseConfigs);
_databaseConfig._setModel(null);
}
public void setActiveDatabaseConfig(EODatabaseConfig activeDatabaseConfig) {
setActiveDatabaseConfig(activeDatabaseConfig, true);
}
public void setActiveDatabaseConfig(EODatabaseConfig activeDatabaseConfig, boolean fireEvents) {
EODatabaseConfig oldActiveDatabaseConfig = myActiveDatabaseConfig;
myActiveDatabaseConfig = activeDatabaseConfig;
clearCachedPrototypes(null, false);
if (fireEvents) {
firePropertyChange(EOModel.ACTIVE_DATABASE_CONFIG, oldActiveDatabaseConfig, myActiveDatabaseConfig);
}
}
public EODatabaseConfig getActiveDatabaseConfig() {
return myActiveDatabaseConfig;
}
public EODatabaseConfig _createDatabaseConfig(String adaptorName, Map<Object, Object> connectionDictionary) {
EODatabaseConfig defaultDatabaseConfig = new EODatabaseConfig(findUnusedDatabaseConfigName("Default"));
defaultDatabaseConfig.setAdaptorName(adaptorName);
if (connectionDictionary != null) {
defaultDatabaseConfig.setConnectionDictionary(new HashMap<Object, Object>(connectionDictionary));
}
defaultDatabaseConfig.setPrototype(_getPreferredPrototypeEntity(adaptorName, connectionDictionary));
defaultDatabaseConfig._setModel(this);
return defaultDatabaseConfig;
}
public Map<EOAttribute, Set<EORelationship>> _createReferencingRelationshipsCache() {
Map<EOAttribute, Set<EORelationship>> cache = new HashMap<EOAttribute, Set<EORelationship>>();
_createReferencingRelationshipsCache(cache);
return cache;
}
public void _createReferencingRelationshipsCache(Map<EOAttribute, Set<EORelationship>> cache) {
for (EOEntity entity : getEntities()) {
for (EORelationship relationship : entity.getRelationships()) {
Set<EOAttribute> relatedAttributes = relationship.getRelatedAttributes();
for (EOAttribute attribute : relatedAttributes) {
Set<EORelationship> relatedRelationships = cache.get(attribute);
if (relatedRelationships == null) {
relatedRelationships = new HashSet<EORelationship>();
cache.put(attribute, relatedRelationships);
}
relatedRelationships.add(relationship);
}
}
}
}
public Map<EOEntity, Set<EOEntity>> _createInheritanceCache() {
Map<EOEntity, Set<EOEntity>> cache = new HashMap<EOEntity, Set<EOEntity>>();
_createInheritanceCache(cache);
return cache;
}
public void _createInheritanceCache(Map<EOEntity, Set<EOEntity>> cache) {
for (EOEntity entity : getEntities()) {
EOEntity parentEntity = entity.getParent();
if (parentEntity != null) {
Set<EOEntity> childrenEntities = cache.get(parentEntity);
if (childrenEntities == null) {
childrenEntities = new HashSet<EOEntity>();
cache.put(parentEntity, childrenEntities);
}
childrenEntities.add(entity);
}
}
}
public Set<EODatabaseConfig> getDatabaseConfigs() {
return myDatabaseConfigs;
}
public Set<EODatabaseConfig> getSortedDatabaseConfigs() {
return new PropertyListSet<EODatabaseConfig>(myDatabaseConfigs);
}
// public int hashCode() {
// return myName.hashCode();
// }
//
// public boolean equals(Object _obj) {
// return (_obj instanceof EOModel && ((EOModel) _obj).myName.equals(myName));
// }
public URL getModelURL() {
return myModelURL;
}
public void setModelURL(URL _modelURL) {
myModelURL = _modelURL;
}
public EOModelGroup getModelGroup() {
return myModelGroup;
}
public String getVersion() {
return myVersion;
}
public void setVersion(String _version) {
String oldVersion = myVersion;
myVersion = _version;
firePropertyChange(EOModel.VERSION, _version, oldVersion);
}
public void setName(String _name) {
String oldName = myName;
myName = _name;
firePropertyChange(EOModel.NAME, _name, oldName);
}
public String getName() {
return myName;
}
/**
* Returns the list of entities that are not prototypes.
*
* @return list of non prototype entities
*/
public Set<EOEntity> getNonPrototypeEntities() {
Set<EOEntity> entities = new HashSet<EOEntity>();
for (EOEntity entity : getEntities()) {
if (!entity.isPrototype()) {
entities.add(entity);
}
}
return entities;
}
public Set<EOEntity> getEntities() {
return myEntities;
}
public Set<EOEntity> getSortedEntities() {
return new PropertyListSet<EOEntity>(myEntities);
}
public EOEntity _getEntityNamedAndCheckModelGroup(String newName) {
EOEntity entity = myModelGroup.getEntityNamed(newName);
if (entity == null) {
entity = getEntityNamed(newName);
}
return entity;
}
public String findUnusedEntityName(String _newName) {
return _findUnusedName(_newName, "_getEntityNamedAndCheckModelGroup");
}
public void _checkForDuplicateEntityName(EOEntity _entity, String _newName, Set<EOModelVerificationFailure> _failures) throws DuplicateEntityNameException {
EOEntity existingEntity = null;
if (myModelGroup != null) {
existingEntity = myModelGroup.getEntityNamed(_newName);
}
// MS: We do this because at load time, the model thinks it's part of
// the model group, but the model group doesnt'
// think it contains the model, so we check both
if (existingEntity == null) {
existingEntity = getEntityNamed(_newName);
}
if (existingEntity != null && existingEntity != _entity) {
// MS: For most duplicates, we can rename the original. But for
// entities, they can be
// in a totally separate model.
if (_failures == null || _entity.getModel() != existingEntity.getModel()) {
throw new DuplicateEntityNameException(_newName, this, existingEntity);
}
String unusedName = findUnusedEntityName(_newName);
existingEntity.setName(unusedName, true);
_failures.add(new DuplicateEntityFailure(this, _newName, unusedName));
}
}
public void _entityNameChanged(String _originalName, String _oldName, String _newName) {
if (myDeletedEntityNamesInObjectStore == null) {
myDeletedEntityNamesInObjectStore = new PropertyListSet<String>();
}
if (_originalName != null && _originalName.length() > 0) {
myDeletedEntityNamesInObjectStore.add(_originalName);
// myDeletedEntityNamesInObjectStore.remove(_newName);
myDeletedEntityNames.add(_originalName);
// myDeletedEntityNames.remove(_newName);
synchronized (_entitiesCache) {
EOEntity entity = _entitiesCache.remove(_oldName);
if (entity != null) {
_entitiesCache.put(_newName, entity);
}
}
}
}
public boolean containsEntityNamed(String _entityName) {
return getEntityNamed(_entityName) != null;
}
public Set importEntitiesFromModel(URL sourceModelURL, Set<EOModelVerificationFailure> failures) throws EOModelException, IOException {
EOModelGroup sourceModelGroup = new EOModelGroup();
EOModel sourceModel = new EOModel("Temp");
sourceModelGroup.addModel(sourceModel);
sourceModel.loadFromURL(sourceModelURL, failures);
sourceModel.resolve(failures);
sourceModel.resolveFlattened(failures);
return importEntitiesFromModel(sourceModel, failures);
}
public Set<EOEntity> importEntitiesFromModel(EOModel sourceModel, Set<EOModelVerificationFailure> failures) throws DuplicateNameException {
Set<EOEntity> clonedEntities = new HashSet<EOEntity>();
for (EOEntity entity : sourceModel.getEntities()) {
clonedEntities.add(entity._cloneModelObject());
}
addEntities(clonedEntities, failures);
guessPrototypes(clonedEntities);
return clonedEntities;
}
public void guessPrototypes() {
guessPrototypes(getEntities());
}
public void guessPrototypes(Set<EOEntity> entities) {
for (EOEntity entity : entities) {
// clonedEntity.setName(StringUtils.toUppercaseFirstLetter(clonedEntity.getName().toLowerCase()));
for (EOAttribute attribute : entity.getAttributes()) {
attribute.guessPrototype(true);
// clonedAttribute.setName(clonedAttribute.getName().toLowerCase());
}
// Iterator clonedRelationshipsIter =
// clonedEntity.getRelationships().iterator();
// while (clonedRelationshipsIter.hasNext()) {
// EORelationship clonedRelationship = (EORelationship)
// clonedRelationshipsIter.next();
// clonedRelationship.setName(clonedRelationship.getName().toLowerCase());
// }
}
}
private Map<String, EOEntity> _entitiesCache = new HashMap<String, EOEntity>();
public void addEntities(Set<EOEntity> entities, Set<EOModelVerificationFailure> failures) throws DuplicateNameException {
Set<EOEntity> oldEntities = new HashSet<EOEntity>();
oldEntities.addAll(myEntities);
for (EOEntity entity : entities) {
addEntity(entity, false, false, failures);
}
for (EOEntity entity : entities) {
entity.pasted();
}
firePropertyChange(EOModel.ENTITIES, oldEntities, myEntities);
}
public void addEntity(EOEntity _entity) throws DuplicateNameException {
addEntity(_entity, true, true, null);
}
public void addEntity(EOEntity entity, boolean pasteImmediately, boolean fireEvents, Set<EOModelVerificationFailure> failures) throws DuplicateNameException {
entity._setModel(this);
_checkForDuplicateEntityName(entity, entity.getName(), failures);
if (pasteImmediately) {
entity.pasted();
}
synchronized (_entitiesCache) {
_entitiesCache.put(entity.getName(), entity);
}
myDeletedEntityNames.remove(entity.getName());
if (fireEvents) {
Set<EOEntity> oldEntities = null;
oldEntities = myEntities;
Set<EOEntity> newEntities = new HashSet<EOEntity>();
newEntities.addAll(myEntities);
newEntities.add(entity);
myEntities = newEntities;
_modelEvents.addEvent(new EOEntityAddedEvent(entity));
firePropertyChange(EOModel.ENTITIES, oldEntities, myEntities);
} else {
myEntities.add(entity);
}
}
public void removeEntity(EOEntity _entity) {
myDeletedEntityNames.add(_entity.getName());
synchronized (_entitiesCache) {
_entitiesCache.remove(_entity.getName());
}
Set<EOEntity> oldEntities = myEntities;
Set<EOEntity> newEntities = new HashSet<EOEntity>();
newEntities.addAll(myEntities);
newEntities.remove(_entity);
myEntities = newEntities;
_modelEvents.addEvent(new EOEntityDeletedEvent(_entity));
firePropertyChange(EOModel.ENTITIES, oldEntities, myEntities);
_entity._setModel(null);
}
public EOEntity getEntityNamed(String name) {
synchronized (_entitiesCache) {
return _entitiesCache.get(name);
}
}
public void _storedProcedureNameChanged(String _oldName, String _newName) {
myDeletedStoredProcedureNames.add(_oldName);
myDeletedStoredProcedureNames.remove(_newName);
}
public EOStoredProcedure addBlankStoredProcedure(String _name) throws DuplicateStoredProcedureNameException {
String newStoredProcedureNameBase = _name;
String newStoredProcedureName = findUnusedStoredProcedureName(newStoredProcedureNameBase);
EOStoredProcedure storedProcedure = new EOStoredProcedure(newStoredProcedureName);
addStoredProcedure(storedProcedure);
return storedProcedure;
}
public void addStoredProcedure(EOStoredProcedure _storedProcedure) throws DuplicateStoredProcedureNameException {
addStoredProcedure(_storedProcedure, true, null);
}
public void addStoredProcedure(EOStoredProcedure _storedProcedure, boolean _fireEvents, Set<EOModelVerificationFailure> _failures) throws DuplicateStoredProcedureNameException {
_storedProcedure._setModel(this);
_checkForDuplicateStoredProcedureName(_storedProcedure, _storedProcedure.getName(), _failures);
_storedProcedure.pasted();
myDeletedStoredProcedureNames.remove(_storedProcedure.getName());
if (_fireEvents) {
Set<EOStoredProcedure> oldStoredProcedures = myStoredProcedures;
Set<EOStoredProcedure> newStoredProcedures = new HashSet<EOStoredProcedure>();
newStoredProcedures.addAll(myStoredProcedures);
newStoredProcedures.add(_storedProcedure);
myStoredProcedures = newStoredProcedures;
firePropertyChange(EOModel.STORED_PROCEDURES, oldStoredProcedures, myStoredProcedures);
} else {
myStoredProcedures.add(_storedProcedure);
}
}
public void removeStoredProcedure(EOStoredProcedure _storedProcedure) {
myDeletedStoredProcedureNames.add(_storedProcedure.getName());
Set<EOStoredProcedure> oldStoredProcedures = myStoredProcedures;
Set<EOStoredProcedure> newStoredProcedures = new HashSet<EOStoredProcedure>();
newStoredProcedures.addAll(myStoredProcedures);
newStoredProcedures.remove(_storedProcedure);
myStoredProcedures = newStoredProcedures;
firePropertyChange(EOModel.STORED_PROCEDURES, oldStoredProcedures, myStoredProcedures);
_storedProcedure._setModel(null);
}
public String findUnusedStoredProcedureName(String _newName) {
return _findUnusedName(_newName, "getStoredProcedureNamed");
}
public Set<EOStoredProcedure> getStoredProcedures() {
return myStoredProcedures;
}
public Set<EOStoredProcedure> getSortedStoredProcedures() {
return new PropertyListSet<EOStoredProcedure>(myStoredProcedures);
}
public EOStoredProcedure getStoredProcedureNamed(String _name) {
EOStoredProcedure matchingStoredProcedure = null;
Iterator<EOStoredProcedure> storedProceduresIter = myStoredProcedures.iterator();
while (matchingStoredProcedure == null && storedProceduresIter.hasNext()) {
EOStoredProcedure attribute = storedProceduresIter.next();
if (ComparisonUtils.equals(attribute.getName(), _name)) {
matchingStoredProcedure = attribute;
}
}
return matchingStoredProcedure;
}
public void _checkForDuplicateStoredProcedureName(EOStoredProcedure _storedProcedure, String _newName, Set<EOModelVerificationFailure> _failures) throws DuplicateStoredProcedureNameException {
EOStoredProcedure existingStoredProcedure = getStoredProcedureNamed(_newName);
if (existingStoredProcedure != null && existingStoredProcedure != _storedProcedure) {
if (_failures == null) {
throw new DuplicateStoredProcedureNameException(_newName, this);
}
String unusedName = findUnusedStoredProcedureName(_newName);
existingStoredProcedure.setName(unusedName, true);
_failures.add(new DuplicateStoredProcedureFailure(this, _newName, unusedName));
}
}
public URL getIndexURL() throws MalformedURLException {
URL indexURL = null;
if (myModelURL != null) {
indexURL = new URL(myModelURL, "index.eomodeld");
}
return indexURL;
}
public void checkLastModified(Set<EOLastModified> lastModified) {
if (_lastModified != null && _lastModified.hasBeenModified()) {
lastModified.add(_lastModified);
}
for (EOEntity entity : getEntities()) {
entity.checkLastModified(lastModified);
}
for (EOStoredProcedure storedProc : getStoredProcedures()) {
storedProc.checkLastModified(lastModified);
}
}
public void loadFromURL(URL _modelFolder, Set<EOModelVerificationFailure> _failures) throws EOModelException, MalformedURLException {
// System.out.println("EOModel.loadFromURL: " + _modelFolder);
URL indexURL = new URL(_modelFolder, "index.eomodeld");
// if (!indexURL.exists()) {
// throw new EOModelException(indexURL + " does not exist.");
// }
myModelURL = _modelFolder;
Map rawModelMap;
try {
rawModelMap = (Map) WOLPropertyListSerialization.propertyListFromURL(indexURL, new EOModelParserDataStructureFactory());
} catch (Exception e) {
throw new EOModelException("index.eomodeld is corrupted.", e);
}
if (rawModelMap == null) {
throw new EOModelException("index.eomodeld is corrupted.");
}
EOModelMap modelMap = new EOModelMap(rawModelMap);
myModelMap = modelMap;
Object version = modelMap.get("EOModelVersion");
if (version instanceof String) {
myVersion = (String) version;
} else if (version instanceof Number) {
myVersion = String.valueOf(((Number) version).floatValue());
} else {
throw new IllegalArgumentException("Unknown version format:" + version);
}
loadUserInfo(modelMap);
Set<Map> entities = modelMap.getSet("entities");
if (entities != null) {
for (Map entitiesMap : entities) {
EOModelMap entityMap = new EOModelMap(entitiesMap);
String entityName = entityMap.getString("name", true);
EOEntity entity = new EOEntity();
URL entityURL = new URL(_modelFolder, entityName + ".plist");
if (URLUtils.exists(entityURL)) {
entity.loadFromURL(entityURL, _failures);
URL fspecURL = new URL(_modelFolder, entityName + ".fspec");
if (URLUtils.exists(fspecURL)) {
entity.loadFetchSpecsFromURL(fspecURL, _failures);
}
if (entity.getName() == null) {
_failures.add(new EOModelVerificationFailure(this, this, "The entity file " + entityURL + " defines an entity with no name.", false));
}
addEntity(entity, true, false, _failures);
} else {
_failures.add(new EOModelVerificationFailure(this, this, "The entity file " + entityURL + " was missing.", false));
}
}
}
Set<String> storedProcedureNames = modelMap.getSet("storedProcedures");
if (storedProcedureNames != null) {
for (String storedProcedureName : storedProcedureNames) {
EOStoredProcedure storedProcedure = new EOStoredProcedure();
URL storedProcedureURL = new URL(_modelFolder, storedProcedureName + ".storedProcedure");
if (URLUtils.exists(storedProcedureURL)) {
storedProcedure.loadFromURL(storedProcedureURL, _failures);
addStoredProcedure(storedProcedure, false, _failures);
} else {
_failures.add(new EOModelVerificationFailure(this, this, "The stored procedure file " + storedProcedureURL + " was missing.", false));
}
}
}
Map<Object, Object> internalInfoMap = modelMap.getMap("internalInfo");
if (internalInfoMap != null) {
Set<String> deletedEntityNamesInObjectStore = modelMap.getSet("_deletedEntityNamesInObjectStore", true);
if (deletedEntityNamesInObjectStore != null) {
myDeletedEntityNamesInObjectStore = deletedEntityNamesInObjectStore;
}
}
EOModelMap entityModelerMap = getEntityModelerMap(false);
_entityNamingConvention = NamingConvention.loadFromMap("entityNamingConvention", entityModelerMap);
_attributeNamingConvention = NamingConvention.loadFromMap("attributeNamingConvention", entityModelerMap);
_reverseEngineered = entityModelerMap.getBoolean("reverseEngineered", false);
Map<String, Map> databaseConfigs = entityModelerMap.getMap("databaseConfigs");
if (databaseConfigs != null) {
for (Map.Entry<String, Map> databaseConfigEntry : databaseConfigs.entrySet()) {
String name = databaseConfigEntry.getKey();
EODatabaseConfig databaseConfig = new EODatabaseConfig(name);
databaseConfig.loadFromMap(new EOModelMap(databaseConfigEntry.getValue()), _failures);
addDatabaseConfig(databaseConfig, false, _failures);
}
}
EODatabaseConfig activeDatabaseConfig = null;
String activeDatabaseConfigName = entityModelerMap.getString("activeDatabaseConfigName", false);
if (activeDatabaseConfigName != null) {
activeDatabaseConfig = getDatabaseConfigNamed(activeDatabaseConfigName);
}
String adaptorName = modelMap.getString("adaptorName", true);
// If there is a connection dictionary, then look for a database config
// that is equivalent ...
Map<Object, Object> connectionDictionary = modelMap.getMap("connectionDictionary", true);
if (connectionDictionary != null && !connectionDictionary.isEmpty()) {
EODatabaseConfig tempConnectionDictionaryDatabaseConfig = _createDatabaseConfig(adaptorName, connectionDictionary);
EODatabaseConfig connectionDictionaryDatabaseConfig = null;
Iterator<EODatabaseConfig> databaseConfigsIter = myDatabaseConfigs.iterator();
while (connectionDictionaryDatabaseConfig == null && databaseConfigsIter.hasNext()) {
EODatabaseConfig databaseConfig = databaseConfigsIter.next();
if (tempConnectionDictionaryDatabaseConfig.isEquivalent(databaseConfig, false)) {
connectionDictionaryDatabaseConfig = databaseConfig;
}
}
// if one isn't found, then make a new database config based off the
// connection dictionary
if (connectionDictionaryDatabaseConfig == null && canSave()) {
connectionDictionaryDatabaseConfig = tempConnectionDictionaryDatabaseConfig;
addDatabaseConfig(connectionDictionaryDatabaseConfig, false, _failures);
//_failures.add(new EOModelVerificationFailure(this, this, "Creating default database config for model '" + getName() + "'.", true, null));
}
// if the identified active database config isn't the connection
// dictionary config, then change the active config to the connection dictionary config
if (activeDatabaseConfig != connectionDictionaryDatabaseConfig) {
activeDatabaseConfig = connectionDictionaryDatabaseConfig;
}
}
// If after all this, we still have no database configs, and you have an empty connection dictionary,
// then make a new blank database config ... If you have a NULL connection dictionary, then we're
// going to assume you did that on purpose.
if (myDatabaseConfigs.isEmpty() && canSave() && connectionDictionary != null) {
// If you didn't specify an adaptor name, let's just make it JDBC
if (adaptorName == null) {
adaptorName = EODatabaseConfig.JDBC_ADAPTOR_NAME;
}
addDatabaseConfig(_createDatabaseConfig(adaptorName, null), false, _failures);
}
// try to always have at least one active database config
if (activeDatabaseConfig == null && !myDatabaseConfigs.isEmpty()) {
activeDatabaseConfig = myDatabaseConfigs.iterator().next();
}
if (activeDatabaseConfig != null) {
if (ComparisonUtils.equals(activeDatabaseConfig.getName(), activeDatabaseConfigName)) {
myActiveDatabaseConfig = activeDatabaseConfig;
} else {
setActiveDatabaseConfig(activeDatabaseConfig, false);
}
}
_lastModified = new EOLastModified(indexURL);
}
public EOModelMap toMap() {
EOModelMap modelMap = myModelMap.cloneModelMap();
modelMap.setString("EOModelVersion", myVersion, true);
String adaptorName = EODatabaseConfig.JDBC_ADAPTOR_NAME;
Map connectionDictionary = null;
if (myActiveDatabaseConfig != null) {
connectionDictionary = myActiveDatabaseConfig.getConnectionDictionary();
adaptorName = myActiveDatabaseConfig.getAdaptorName();
}
modelMap.put("connectionDictionary", connectionDictionary);
modelMap.setString("adaptorName", adaptorName, true);
Set<Map> entities = new PropertyListSet<Map>(EOModelMap.asArray(myModelMap.get("entities")));
Set<String> entitiesWithSharedObjects = new PropertyListSet<String>(EOModelMap.asArray(myModelMap.get("entitiesWithSharedObjects")));
for (EOEntity entity : myEntities) {
EOModelMap entityMap = new EOModelMap();
entityMap.setString("className", entity.getClassName(), true);
EOEntity parent = entity.getParent();
String parentName = (parent == null) ? null : parent.getName();
entityMap.setString("parent", parentName, true);
entityMap.setString("name", entity.getName(), true);
entities.add(entityMap);
if (entity.hasSharedObjects()) {
entitiesWithSharedObjects.add(entity.getName());
}
}
modelMap.setSet("entities", entities, true);
modelMap.setSet("entitiesWithSharedObjects", entitiesWithSharedObjects, true);
Map<Object, Object> internalInfoMap = modelMap.getMap("internalInfo");
if (internalInfoMap == null) {
internalInfoMap = new HashMap<Object, Object>();
}
if (myDeletedEntityNamesInObjectStore != null && !myDeletedEntityNamesInObjectStore.isEmpty()) {
internalInfoMap.put("_deletedEntityNamesInObjectStore", myDeletedEntityNamesInObjectStore);
} else {
internalInfoMap.remove("_deletedEntityNamesInObjectStore");
}
modelMap.setMap("internalInfo", internalInfoMap, true);
Set<String> storedProcedures = new PropertyListSet<String>(EOModelMap.asArray(myModelMap.get("storedProcedures")));
for (EOStoredProcedure storedProcedure : myStoredProcedures) {
storedProcedures.add(storedProcedure.getName());
}
modelMap.setSet("storedProcedures", storedProcedures, true);
EOModelMap entityModelerMap = getEntityModelerMap(true);
boolean canConvertDatabaseConfigsToSingleConnectionDictionary = canConvertDatabaseConfigsToSingleConnectionDictionary();
if (canConvertDatabaseConfigsToSingleConnectionDictionary) {
entityModelerMap.remove("databaseConfigs");
entityModelerMap.remove("activeDatabaseConfigName");
}
else {
Map<String, Map> databaseConfigs = new PropertyListMap<String, Map>();
for (EODatabaseConfig databaseConfig : myDatabaseConfigs) {
databaseConfigs.put(databaseConfig.getName(), databaseConfig.toMap());
}
entityModelerMap.setMap("databaseConfigs", databaseConfigs, true);
if (myActiveDatabaseConfig == null || databaseConfigs.get(myActiveDatabaseConfig.getName()) == null) {
entityModelerMap.remove("activeDatabaseConfigName");
} else {
entityModelerMap.put("activeDatabaseConfigName", myActiveDatabaseConfig.getName());
}
}
NamingConvention.toMap(_entityNamingConvention, "entityNamingConvention", entityModelerMap);
NamingConvention.toMap(_attributeNamingConvention, "attributeNamingConvention", entityModelerMap);
entityModelerMap.setBoolean("reverseEngineered", Boolean.valueOf(_reverseEngineered), EOModelMap.YNOptionalDefaultNo);
writeUserInfo(modelMap);
return modelMap;
}
/**
* Returns the .eomodeld for the given folder. If this is an .eomodeld
* folder, it returns the folder you pass in. Otherwise, it creates a child
* with this model's name.
*
* @param folder
* the folder to write to
* @return the corresponding .eomodeld folder
*/
public File _eomodeldFolderForFolder(File folder) {
File modelFolder;
if (folder.getName().endsWith(".eomodeld")) {
modelFolder = folder;
} else {
modelFolder = new File(folder, myName + ".eomodeld");
}
return modelFolder;
}
/**
* Returns true if you are able to write this model to the folder it was
* loaded from.
*
* @return true if you are able to save this model
* @throws MalformedURLException
* if the index URL is invalid
*/
public boolean canSave() throws MalformedURLException {
boolean canSave;
URL indexURL = getIndexURL();
if (indexURL == null || indexURL.toExternalForm().startsWith("jar:")) {
canSave = false;
} else {
File indexFile = URLUtils.cheatAndTurnIntoFile(indexURL);
File modelFolder = indexFile.getParentFile();
canSave = canSaveToFolder(modelFolder);
}
return canSave;
}
/**
* Returns true if you are able to write this model to the given folder.
*
* @param parentFolder
* the folder to write the model into
* @return true if you are able to write to the folder
*/
public boolean canSaveToFolder(File parentFolder) {
boolean canSave;
File modelFolder = _eomodeldFolderForFolder(parentFolder);
if (modelFolder.exists()) {
if (modelFolder.isFile()) {
canSave = false;
} else {
canSave = modelFolder.canWrite();
}
} else {
canSave = modelFolder.getParentFile().canWrite();
}
return canSave;
}
/**
* Saves this model to the same folder it was loaded from.
*
* @return the .eomodeld folder
* @throws IOException
* if the model could not be saved
* @throws PropertyListParserException
*/
public File save() throws IOException, PropertyListParserException {
URL indexURL = getIndexURL();
if (indexURL == null) {
throw new IOException("This model has no index file URL.");
}
File indexFile = URLUtils.cheatAndTurnIntoFile(indexURL);
File modelFolder = indexFile.getParentFile();
return saveToFolder(modelFolder.getParentFile());
}
public File saveToFolder(File parentFolder) throws IOException, PropertyListParserException {
firePropertyChange(EOModel.MODEL_SAVING, Boolean.FALSE, Boolean.TRUE);
try {
File modelFolder = _eomodeldFolderForFolder(parentFolder);
if (!modelFolder.exists()) {
if (!modelFolder.mkdirs()) {
throw new IOException("Failed to create folder '" + modelFolder + "'.");
}
}
myModelURL = modelFolder.toURL();
File indexFile = new File(modelFolder, "index.eomodeld");
EOModelMap modelMap = toMap();
WOLPropertyListSerialization.propertyListToFile("Entity Modeler v" + EOModel.CURRENT_VERSION, indexFile, modelMap);
if (myDeletedEntityNames != null) {
for (String entityName : myDeletedEntityNames) {
if (getEntityNamed(entityName) == null) {
File entityFile = new File(modelFolder, entityName + ".plist");
if (entityFile.exists()) {
entityFile.delete();
}
File fspecFile = new File(modelFolder, entityName + ".fspec");
if (fspecFile.exists()) {
fspecFile.delete();
}
}
}
}
for (EOEntity entity : myEntities) {
if (entity.isEntityDirty()) {
String entityName = entity.getName();
File entityFile = new File(modelFolder, entityName + ".plist");
File fspecFile = new File(modelFolder, entityName + ".fspec");
entity.saveToFile(entityFile, fspecFile);
}
}
if (myDeletedStoredProcedureNames != null) {
for (String storedProcedureName : myDeletedStoredProcedureNames) {
if (getStoredProcedureNamed(storedProcedureName) == null) {
File storedProcedureFile = new File(modelFolder, storedProcedureName + ".storedProcedure");
if (storedProcedureFile.exists()) {
storedProcedureFile.delete();
}
}
}
}
for (EOStoredProcedure storedProcedure : myStoredProcedures) {
if (storedProcedure.isStoredProcedureDirty()) {
String storedProcedureName = storedProcedure.getName();
File storedProcedureFile = new File(modelFolder, storedProcedureName + ".storedProcedure");
storedProcedure.saveToFile(storedProcedureFile);
}
}
setDirty(false);
_lastModified = new EOLastModified(indexFile);
return modelFolder;
}
finally {
firePropertyChange(EOModel.MODEL_SAVING, Boolean.TRUE, Boolean.FALSE);
}
}
public void resolve(Set<EOModelVerificationFailure> _failures) {
for (EOEntity entity : myEntities) {
entity.resolve(_failures);
}
}
public void resolveFlattened(Set<EOModelVerificationFailure> _failures) {
for (EOEntity entity : myEntities) {
entity.resolveFlattened(_failures);
}
}
public void verify(Set<EOModelVerificationFailure> _failures) {
VerificationContext verificationContext;
EOModelGroup modelGroup = getModelGroup();
if (modelGroup == null) {
verificationContext = new VerificationContext(this);
} else {
verificationContext = new VerificationContext(modelGroup);
}
verify(_failures, verificationContext);
}
public void verify(Set<EOModelVerificationFailure> _failures, VerificationContext verificationContext) {
// TODO
for (EOEntity entity : myEntities) {
entity.verify(_failures, verificationContext);
}
}
public String getFullyQualifiedName() {
return myName == null ? "Unknown Model '" + getModelURL() + "'" : myName;
}
@Override
public EOModel _cloneModelObject() {
throw new IllegalStateException("Not implemented");
}
@Override
public Class<EOModelGroup> _getModelParentType() {
return EOModelGroup.class;
}
@Override
public EOModelGroup _getModelParent() {
return getModelGroup();
}
@Override
public void _addToModelParent(EOModelGroup modelParent, boolean findUniqueName, Set<EOModelVerificationFailure> failures) throws EOModelException {
if (findUniqueName) {
throw new IllegalArgumentException("Unable to unique model names.");
}
modelParent.addModel(this, failures);
}
@Override
public void _removeFromModelParent(Set<EOModelVerificationFailure> failures) {
getModelGroup().removeModel(this, failures);
}
public ModelEvents getModelEvents() {
return _modelEvents;
}
public String toString() {
return "[EOModel: name = " + myName + "; entities = " + myEntities + "]";
}
/** Begin Prototypes * */
public synchronized void clearCachedPrototypes(Set<EOModelVerificationFailure> _failures, boolean _reload) {
myPrototypeAttributeCache = null;
for (EOEntity entity : myEntities) {
entity.clearCachedPrototypes(_failures, _reload);
}
}
public synchronized Set<String> getPrototypeAttributeNames() {
Set<String> prototypeAttributeNames = new PropertyListSet<String>();
for (EOAttribute attribute : getPrototypeAttributes()) {
prototypeAttributeNames.add(attribute.getName());
}
return prototypeAttributeNames;
}
public String _getDefaultPrototypeEntityName(String prefix, String name) {
return "EO" + (prefix != null ? prefix : "") + (name != null ? name : "") + "Prototypes";
}
public String getAdaptorName() {
String adaptorName = EODatabaseConfig.JDBC_ADAPTOR_NAME;
if (myActiveDatabaseConfig != null) {
adaptorName = myActiveDatabaseConfig.getAdaptorName();
}
return adaptorName;
}
public String _getAdaptorPrototypeEntityName(String prefix, String adaptorName, String name) {
String adaptorPrototypeEntityName = null;
if (adaptorName != null) {
adaptorPrototypeEntityName = "EO" + adaptorName + (prefix != null ? prefix : "") + (name != null ? name : "") + "Prototypes";
}
return adaptorPrototypeEntityName;
}
public String _getDriverPrototypeEntityName(String prefix, Map _connectionDictionary, String name) {
String driverPrototypeEntityName = null;
String adaptorName = getAdaptorName();
// MS: Hardcoded JDBC reference hack ...
if ("JDBC".equals(adaptorName)) {
if (_connectionDictionary != null) {
String pluginName = (String) _connectionDictionary.get("plugin");
if (pluginName == null || pluginName.length() == 0) {
String jdbcUrl = (String) _connectionDictionary.get("URL");
if (jdbcUrl != null && jdbcUrl.length() > 0) {
int firstColon = jdbcUrl.indexOf(':');
int secondColon = jdbcUrl.indexOf(':', firstColon + 1);
if (firstColon != -1 && secondColon != -1) {
pluginName = jdbcUrl.substring(firstColon + 1, secondColon);
}
}
}
if (pluginName != null) {
driverPrototypeEntityName = "EOJDBC" + pluginName + (prefix != null ? prefix : "") + (name != null ? name : "") + "Prototypes";
}
}
}
return driverPrototypeEntityName;
}
public EOEntity _getPreferredPrototypeEntity(String adaptorName, Map connectionDictionary) {
EOEntity preferredPrototypEntity = _getPreferredPrototypeEntity("Custom", adaptorName, null, connectionDictionary);
if (preferredPrototypEntity == null) {
preferredPrototypEntity = _getPreferredPrototypeEntity(null, adaptorName, getName(), connectionDictionary);
if (preferredPrototypEntity == null) {
preferredPrototypEntity = _getPreferredPrototypeEntity(null, adaptorName, null, connectionDictionary);
}
}
return preferredPrototypEntity;
}
public EOEntity _getPreferredPrototypeEntity(String prefix, String adaptorName, String modelName, Map connectionDictionary) {
EOEntity prototypeEntity = null;
String driverPrototypeEntityName = _getDriverPrototypeEntityName(prefix, connectionDictionary, modelName);
if (driverPrototypeEntityName != null && myModelGroup != null) {
prototypeEntity = myModelGroup.getEntityNamed(driverPrototypeEntityName);
}
if (prototypeEntity == null) {
String adaptorPrototypeEntityName = _getAdaptorPrototypeEntityName(prefix, adaptorName, modelName);
if (adaptorPrototypeEntityName != null && myModelGroup != null) {
prototypeEntity = myModelGroup.getEntityNamed(adaptorPrototypeEntityName);
}
}
if (prototypeEntity == null && myModelGroup != null) {
String defaultPrototypeEntityName = _getDefaultPrototypeEntityName(prefix, modelName);
prototypeEntity = myModelGroup.getEntityNamed(defaultPrototypeEntityName);
}
return prototypeEntity;
}
public synchronized Set<EOAttribute> getPrototypeAttributes() {
if (myPrototypeAttributeCache == null) {
Map<String, EOAttribute> prototypeAttributeCache = new HashMap<String, EOAttribute>();
Map connectionDictionary = null;
EODatabaseConfig activeDatabaseConfig = getActiveDatabaseConfig();
if (activeDatabaseConfig != null) {
connectionDictionary = activeDatabaseConfig.getConnectionDictionary();
}
addPrototypeAttributes(_getDefaultPrototypeEntityName(null, null), prototypeAttributeCache);
addPrototypeAttributes(_getAdaptorPrototypeEntityName(null, getAdaptorName(), null), prototypeAttributeCache);
addPrototypeAttributes(_getDriverPrototypeEntityName(null, connectionDictionary, null), prototypeAttributeCache);
addPrototypeAttributes(_getDefaultPrototypeEntityName("Custom", null), prototypeAttributeCache);
addPrototypeAttributes(_getAdaptorPrototypeEntityName("Custom", getAdaptorName(), null), prototypeAttributeCache);
addPrototypeAttributes(_getDriverPrototypeEntityName("Custom", connectionDictionary, null), prototypeAttributeCache);
addPrototypeAttributes(_getDefaultPrototypeEntityName(null, getName()), prototypeAttributeCache);
addPrototypeAttributes(_getAdaptorPrototypeEntityName(null, getAdaptorName(), getName()), prototypeAttributeCache);
addPrototypeAttributes(_getDriverPrototypeEntityName(null, connectionDictionary, getName()), prototypeAttributeCache);
if (activeDatabaseConfig != null) {
EOEntity prototypeEntity = activeDatabaseConfig.getPrototype();
if (prototypeEntity != null) {
addPrototypeAttributes(prototypeEntity.getName(), prototypeAttributeCache);
}
}
// Do we need to support "EOPrototypesToHide" entity?
myPrototypeAttributeCache = new HashSet<EOAttribute>();
myPrototypeAttributeCache.addAll(prototypeAttributeCache.values());
}
return myPrototypeAttributeCache;
}
protected void addPrototypeAttributes(String _prototypeEntityName, Map<String, EOAttribute> _prototypeAttributeCache) {
if (_prototypeEntityName != null) {
EOEntity prototypeEntity = myModelGroup.getEntityNamed(_prototypeEntityName);
if (prototypeEntity != null) {
for (EOAttribute prototypeAttribute : prototypeEntity.getAttributes()) {
_prototypeAttributeCache.put(prototypeAttribute.getName(), prototypeAttribute);
}
}
}
}
public EOAttribute getPrototypeAttributeNamed(String _name) {
EOAttribute matchingAttribute = null;
Set<EOAttribute> prototypeAttributes = getPrototypeAttributes();
Iterator<EOAttribute> attributesIter = prototypeAttributes.iterator();
while (matchingAttribute == null && attributesIter.hasNext()) {
EOAttribute attribute = attributesIter.next();
if (attribute.getName().equals(_name)) {
matchingAttribute = attribute;
}
}
return matchingAttribute;
}
/** End Prototypes * */
/*
* public static void main(String[] args) throws IOException,
* EOModelException { Set<EOModelVerificationFailure> failures = new
* LinkedHashSet<EOModelVerificationFailure>();
*
* EOModelGroup modelGroup = new EOModelGroup(); NullProgressMonitor
* progressMonitor = new NullProgressMonitor();
* modelGroup.loadModelsFromFolder(new
* File("/Library/Frameworks/ERPrototypes.framework/Resources").toURL(),
* failures, progressMonitor); modelGroup.loadModelsFromFolder(new
* File("/Users/mschrag/Documents/workspace/MDTask").toURL(), failures,
* progressMonitor); modelGroup.loadModelsFromFolder(new
* File("/Users/mschrag/Documents/workspace/MDTAccounting").toURL(),
* failures, progressMonitor); modelGroup.loadModelsFromFolder(new
* File("/Users/mschrag/Documents/workspace/MDTCMS").toURL(), failures,
* progressMonitor); modelGroup.loadModelsFromFolder(new
* File("/Users/mschrag/Documents/workspace/MDTWOExtensions").toURL(),
* failures, progressMonitor);
*
* modelGroup.resolve(failures); modelGroup.verify(failures); Iterator
* failuresIter = failures.iterator(); while (failuresIter.hasNext()) {
* EOModelVerificationFailure failure = (EOModelVerificationFailure)
* failuresIter.next(); System.out.println("EOModel.main: " + failure); }
*
* File outputPath = new File("/tmp"); System.out.println("EOModel.main:
* Saving model to " + outputPath + " ..."); EOModel mdtaskModel =
* modelGroup.getModelNamed("MDTask"); mdtaskModel.saveToFolder(outputPath);
* System.out.println("EOModel.main: Done."); }
*/
}