From: Anjo K. <an...@us...> - 2006-09-07 15:38:18
|
Update of /cvsroot/wonder/Wonder/Common/Frameworks/ERExtensions/Sources/er/extensions In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv30354/ERExtensions/Sources/er/extensions Modified Files: ERXModelGroup.java ERXJDBCAdaptor.java ERXConfigurationManager.java Log Message: using our own model classes, to finall get prototypes to work Index: ERXModelGroup.java =================================================================== RCS file: /cvsroot/wonder/Wonder/Common/Frameworks/ERExtensions/Sources/er/extensions/ERXModelGroup.java,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** ERXModelGroup.java 7 Jul 2006 18:57:08 -0000 1.13 --- ERXModelGroup.java 7 Sep 2006 15:38:14 -0000 1.14 *************** *** 10,17 **** import java.util.*; ! import org.apache.log4j.Logger; import com.webobjects.eoaccess.*; import com.webobjects.foundation.*; /** --- 10,18 ---- import java.util.*; ! import org.apache.log4j.*; import com.webobjects.eoaccess.*; import com.webobjects.foundation.*; + import com.webobjects.jdbcadaptor.*; /** *************** *** 30,33 **** --- 31,36 ---- private Hashtable cache; + protected static boolean patchModelsOnLoad = ERXProperties.booleanForKeyWithDefault("er.extensions.ERXModelGroup.patchModelsOnLoad", false); + /** * Default public constructor *************** *** 118,121 **** --- 121,271 ---- NSNotificationCenter.defaultCenter().postNotification("EOModelAddedNotification", eomodel); } + + /** + * Extends models by model-specific prototypes. You would use them by having an entity named + * <code>EOModelPrototypes</code>, <code>EOJDBCModelPrototypes</code> or + * <code>EOJDBC<PluginName>ModelPrototypes</code> in your model. These are loaded after the + * normal models, so you can override things here. Of course EOModeler knows nothing of them, + * so you may need to copy all attributes over to a <code>EOPrototypes</code> entity that is + * present only once in your model group. <br /> + * This class is used by the runtime when the property <code>er.extensions.ERXModelGroup.useExtendedPrototypes=true</code>. + * @author ak + */ + public static class Model extends EOModel { + + public Model(URL url) { + super(url); + log.info("init: " + name()); + } + + public void setModelGroup(EOModelGroup aGroup) { + super.setModelGroup(aGroup); + log.info("setModelGroup: " + name()); + if(aGroup != null) { + ERXConfigurationManager.defaultManager().resetConnectionDictionaryInModel(this); + } + } + + /** + * Utility for getting all names from an array of attributes. + * @param attributes + * @return + */ + private NSArray namesForAttributes(NSArray attributes) { + return (NSArray) attributes.valueForKey("name"); + } + + /** + * Utility for getting all the attributes off an entity. If the entity + * is null, an empty array is returned. + * @param entity + * @return + */ + private NSArray attributesFromEntity(EOEntity entity) { + NSArray result = NSArray.EmptyArray; + if(entity != null) { + result = entity.attributes(); + log.info("Attributes from " + entity.name() + ": " + result); + } + return result; + } + + /** + * Utility to add attributes to the prototype cache. As the attributes are + * chosen by name, replace already existing ones. + * @param attributes + */ + private void addAttributesToPrototypesCache(NSArray attributes) { + if(attributes.count() != 0) { + NSArray keys = namesForAttributes(attributes); + NSDictionary temp = new NSDictionary(attributes, keys); + _prototypesByName.addEntriesFromDictionary(temp); + } + } + + /** + * Create the prototype cache by walking a search order. + * + */ + private void createPrototypes() { + log.info("Creating prototypes for model: " + name() + "->" + connectionDictionary()); + synchronized (_EOGlobalModelLock) { + _prototypesByName = new NSMutableDictionary(); + NSArray adaptorPrototypes = NSArray.EmptyArray; + EOAdaptor adaptor = EOAdaptor.adaptorWithModel(this); + try { + adaptorPrototypes = adaptor.prototypeAttributes(); + } catch (Exception e) { + log.error(e, e); + } + NSArray globalAttributesFromModelGroup = attributesFromEntity(_group.entityNamed("EOPrototypes")); + NSArray globalAttributesFromModel = attributesFromEntity(entityNamed("EOModelPrototypes")); + + NSArray adaptorAttributesFromModelGroup = attributesFromEntity(_group.entityNamed("EO" + adaptorName() + "Prototypes")); + NSArray adaptorAttributesFromModel = attributesFromEntity(entityNamed("EO" + adaptorName() + "ModelPrototypes")); + + NSArray pluginAttributesFromModelGroup = NSArray.EmptyArray; + NSArray pluginAttributesFromModel = NSArray.EmptyArray; + + if(adaptor instanceof JDBCAdaptor && !name().equals("erprototypes")) { + String plugin = (String) connectionDictionary().objectForKey("plugin"); + if(plugin != null) { + pluginAttributesFromModelGroup = attributesFromEntity(_group.entityNamed("EOJDBC" + plugin + "Prototypes")); + pluginAttributesFromModel = attributesFromEntity(entityNamed("EOJDBC" + plugin + "ModelPrototypes")); + } + } + addAttributesToPrototypesCache(adaptorPrototypes); + NSArray prototypesToHide = attributesFromEntity(_group.entityNamed("EOPrototypesToHide")); + _prototypesByName.removeObjectsForKeys(namesForAttributes(prototypesToHide)); + + addAttributesToPrototypesCache(globalAttributesFromModelGroup); + addAttributesToPrototypesCache(adaptorAttributesFromModelGroup); + addAttributesToPrototypesCache(pluginAttributesFromModelGroup); + + addAttributesToPrototypesCache(globalAttributesFromModel); + addAttributesToPrototypesCache(adaptorAttributesFromModel); + addAttributesToPrototypesCache(pluginAttributesFromModel); + } + } + + /** + * Overridden to use our prototype creation method. + */ + public EOAttribute prototypeAttributeNamed(String name) { + synchronized (_EOGlobalModelLock) { + if (_prototypesByName == null) { + createPrototypes(); + } + } + return (EOAttribute) super.prototypeAttributeNamed(name); + } + + /** + * Overridden to use our prototype creation method. + */ + public NSArray availablePrototypeAttributeNames() { + synchronized(_EOGlobalModelLock) { + if(_prototypesByName == null) { + createPrototypes(); + } + } + return super.availablePrototypeAttributeNames(); + } + + } + + /** + * Overridden to use our model class in the runtime. + */ + public EOModel addModelWithPathURL(URL url) { + EOModel model = null; + if(patchModelsOnLoad) { + model = new Model(url); + } else { + model = new EOModel(url); + } + addModel(model); + return model; + } /** Index: ERXJDBCAdaptor.java =================================================================== RCS file: /cvsroot/wonder/Wonder/Common/Frameworks/ERExtensions/Sources/er/extensions/ERXJDBCAdaptor.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ERXJDBCAdaptor.java 4 Sep 2006 20:19:42 -0000 1.5 --- ERXJDBCAdaptor.java 7 Sep 2006 15:38:14 -0000 1.6 *************** *** 3,7 **** import java.sql.*; ! import org.apache.log4j.Logger; import com.webobjects.eoaccess.*; --- 3,7 ---- import java.sql.*; ! import org.apache.log4j.*; import com.webobjects.eoaccess.*; *************** *** 29,32 **** --- 29,33 ---- private static Boolean switchReadWrite = null; + private static Boolean useConnectionBroker = null; private static boolean switchReadWrite() { *************** *** 37,40 **** --- 38,53 ---- } + /** + * Returns whether the connection broker is active. + * @return + */ + public static boolean useConnectionBroker() { + if (useConnectionBroker == null) { + useConnectionBroker = ERXProperties.booleanForKeyWithDefault(USE_CONNECTION_BROKER_KEY, false) ? Boolean.FALSE : Boolean.TRUE; + } + return useConnectionBroker.booleanValue(); + } + + public static void registerJDBCAdaptor() { String className = ERXProperties.stringForKey(CLASS_NAME_KEY); *************** *** 115,129 **** public static class Context extends JDBCContext { - private boolean _useConnectionBroker; - public Context(EOAdaptor eoadaptor) { super(eoadaptor); - _useConnectionBroker = ERXProperties.booleanForKeyWithDefault(USE_CONNECTION_BROKER_KEY, false); } - private boolean useConnectionBroker() { - return _useConnectionBroker; - } - private void freeConnection() { if(useConnectionBroker()) { --- 128,135 ---- Index: ERXConfigurationManager.java =================================================================== RCS file: /cvsroot/wonder/Wonder/Common/Frameworks/ERExtensions/Sources/er/extensions/ERXConfigurationManager.java,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** ERXConfigurationManager.java 5 Sep 2006 22:59:15 -0000 1.50 --- ERXConfigurationManager.java 7 Sep 2006 15:38:14 -0000 1.51 *************** *** 10,14 **** import java.util.*; ! import org.apache.log4j.Logger; import com.webobjects.appserver.*; --- 10,14 ---- import java.util.*; ! import org.apache.log4j.*; import com.webobjects.appserver.*; *************** *** 76,90 **** * <pre> * <strong>Global:</strong> ! * dbConnectServerGLOBAL = myDatabaseServer ! * dbConnectUserGLOBAL = me ! * dbConnectPasswordGLOBAL = secret * <strong>Per Model for say model ER:</strong> ! * ER.DBServer = myDatabaseServer ! * ER.DBUser = me ! * ER.DBPassword = secret * * <strong>Openbase:</strong> same, with DBDatabase and DBHostname * ! * <strong>JDBC:</strong> same with urlGlobal, or db.url * * </pre> --- 76,92 ---- * <pre> * <strong>Global:</strong> ! * dbConnectServerGLOBAL = myDatabaseServer ! * dbConnectUserGLOBAL = me ! * dbConnectPasswordGLOBAL = secret ! * dbConnectPluginGLOBAL = Oracle * <strong>Per Model for say model ER:</strong> ! * ER.DBServer = myDatabaseServer ! * ER.DBUser = me ! * ER.DBPassword = secret ! * ER.DBPlugin = Oracle * * <strong>Openbase:</strong> same, with DBDatabase and DBHostname * ! * <strong>JDBC:</strong> same with dbConnectURLGLOBAL, or ER.DBURL * * </pre> *************** *** 166,184 **** if (! _isInitialized) { _isInitialized = true; ! NSNotificationCenter.defaultCenter().addObserver(this, ! new NSSelector("modelAddedHandler", ! ERXConstant.NotificationClassArray), ! EOModelGroup.ModelAddedNotification, ! null); ! loadOptionalConfigurationFiles(); ! } } /** ! * Sets up the system for rapid turnaround mode. It will watch the ! * changes on Properties files in application and framework bundles ! * and WebObjects.properties under the home directory. ! * Rapid turnaround mode will only be enabled if there are such ! * files available and system has WOCaching disabled. */ public void configureRapidTurnAround() { --- 168,186 ---- if (! _isInitialized) { _isInitialized = true; ! loadOptionalConfigurationFiles(); ! if(!ERXModelGroup.patchModelsOnLoad) { ! NSNotificationCenter.defaultCenter().addObserver(this, ! new NSSelector("modelAddedHandler", ERXConstant.NotificationClassArray), ! EOModelGroup.ModelAddedNotification, null); ! } ! } } /** ! * Sets up the system for rapid turnaround mode. It will watch the changes ! * on Properties files in application and framework bundles and ! * WebObjects.properties under the home directory. Rapid turnaround mode ! * will only be enabled if there are such files available and system has ! * WOCaching disabled. */ public void configureRapidTurnAround() { *************** *** 364,658 **** } /** ! * Resets the connection dictionary to the specified values that are in the defaults. ! * This method will look for defaults in the form ! * <MODELNAME>.DBServer ! * <MODELNAME>.DBUser ! * <MODELNAME>.DBPassword ! * <MODELNAME>.URL (for JDBC) ! * if the serverName and username both exists, we overwrite the connection dict ! * (password is optional). Otherwise we fall back to what's in the model. ! * * Likewise default values can be specified of the form: ! * dbConnectUserGLOBAL ! * dbConnectPasswordGLOBAL ! * dbConnectURLGLOBAL ! * @param aModel to be reset */ ! public void resetConnectionDictionaryInModel(EOModel aModel) { ! if(aModel!=null) { ! String aModelName=aModel.name(); ! log.debug("Adjusting "+aModelName); ! NSMutableDictionary newConnectionDictionary=null; ! if(aModel.adaptorName() == null) { ! log.info("Skipping model '" + aModel.name() + "', it has no adaptor name set"); ! return; ! } ! // Support for EODatabaseConfig from EntityModeler. The value of YourEOModelName.DBConfigName is ! // used to lookup the corresponding EODatabaseConfig name from user info. The connection dictionary ! // defined in the databaseConfig section completely replaces the connection dictionary in the ! // EOModel. After the initial replacement, all the additional PW model configurations are then ! // applied to the new dictionary. ! String databaseConfigName = ERXSystem.getProperty(aModelName + ".DBConfigName"); ! NSDictionary databaseConfig = null; ! if (databaseConfigName != null) { ! NSDictionary userInfo = aModel.userInfo(); ! if (userInfo != null) { NSDictionary entityModelerDictionary = (NSDictionary) userInfo.objectForKey("_EntityModeler"); if (entityModelerDictionary != null) { ! NSDictionary databaseConfigsDictionary = (NSDictionary) entityModelerDictionary.objectForKey("databaseConfigs"); ! if (databaseConfigsDictionary != null) { ! databaseConfig = (NSDictionary) databaseConfigsDictionary.objectForKey(databaseConfigName); ! if (databaseConfig != null) { ! NSDictionary connectionDictionary = (NSDictionary) databaseConfig.objectForKey("connectionDictionary"); ! aModel.setConnectionDictionary(connectionDictionary); } - } } - } } ! ! if (aModel.adaptorName().indexOf("Oracle")!=-1) { ! String serverName= ERXSystem.getProperty(aModelName + ".DBServer"); ! serverName=serverName==null ? ERXSystem.getProperty("dbConnectServerGLOBAL") : serverName; ! String userName= ERXSystem.getProperty(aModelName + ".DBUser"); ! userName= userName ==null ? ERXSystem.getProperty("dbConnectUserGLOBAL") : userName; ! String passwd= ERXSystem.getProperty(aModelName + ".DBPassword"); ! passwd= passwd ==null ? ERXSystem.getProperty("dbConnectPasswordGLOBAL") : passwd; ! if((serverName!=null) || (userName!=null) || (passwd!=null)) { ! newConnectionDictionary=new NSMutableDictionary(aModel.connectionDictionary()); ! if (serverName!=null) newConnectionDictionary.setObjectForKey(serverName,"serverId"); ! if (userName!=null) newConnectionDictionary.setObjectForKey(userName,"userName"); ! if (passwd!=null) newConnectionDictionary.setObjectForKey(passwd,"password"); ! aModel.setConnectionDictionary(newConnectionDictionary); ! } ! ! } else if (aModel.adaptorName().indexOf("Flat")!=-1) { ! String path= ERXSystem.getProperty(aModelName + ".DBPath"); ! path = path ==null ? ERXSystem.getProperty("dbConnectPathGLOBAL") : path; ! if (path!=null) { ! if (path.indexOf(" ")!=-1) { ! NSArray a=NSArray.componentsSeparatedByString(path," "); ! if (a.count()==2) { ! path = ERXFileUtilities.pathForResourceNamed((String)a.objectAtIndex(0), (String)a.objectAtIndex(1), null); ! } ! } ! } else { ! // by default we take <modelName>.db in the directory we found the model ! path=aModel.pathURL().getFile(); ! path=NSPathUtilities.stringByDeletingLastPathComponent(path); ! path=NSPathUtilities.stringByAppendingPathComponent(path,aModel.name()+".db"); ! } ! newConnectionDictionary=new NSMutableDictionary(aModel.connectionDictionary()); ! if (path!=null) newConnectionDictionary.setObjectForKey(path,"path"); ! if (operatingSystem()==WindowsOperatingSystem) ! newConnectionDictionary.setObjectForKey("\r\n","rowSeparator"); ! aModel.setConnectionDictionary(newConnectionDictionary); ! } else if (aModel.adaptorName().indexOf("OpenBase")!=-1) { ! String db= ERXSystem.getProperty(aModelName + ".DBDatabase"); ! db = db ==null ? ERXSystem.getProperty("dbConnectDatabaseGLOBAL") : db; ! String h= ERXSystem.getProperty(aModelName + ".DBHostName"); ! h = h ==null ? ERXSystem.getProperty("dbConnectHostNameGLOBAL") : h; ! if (h!=null || db!=null) { ! newConnectionDictionary=new NSMutableDictionary(aModel.connectionDictionary()); ! if (db!=null) newConnectionDictionary.setObjectForKey(db, "databaseName"); ! if (h!=null) newConnectionDictionary.setObjectForKey(h, "hostName"); ! aModel.setConnectionDictionary(newConnectionDictionary); ! } ! } else if (aModel.adaptorName().indexOf("JDBC")!=-1) { ! if (aModel.adaptorName().equals("JDBC") && ERXProperties.booleanForKeyWithDefault("er.jdbcadaptor.ERJDBCAdaptor.poolModelConnections", false)) { ! try { ! // is the JavaERJDBCAdaptor framework available? ! Class cl = Class.forName("er.jdbcadaptor.ERJDBCAdaptor"); ! // important if one compiles with jikes as jikes would eliminate the call above! ! log.debug(cl); ! aModel.setAdaptorName("ERJDBC"); ! } catch (ClassNotFoundException e1) { ! log.error("cannot use Model Connection pooling because framework JavaERJDBCAdaptor is missing. Make sure the framework is loaded by the application"); ! } ! } ! NSDictionary jdbcInfoDictionary = null; ! String url = ERXSystem.getProperty(aModelName + ".URL"); ! url = url == null ? ERXSystem.getProperty("dbConnectURLGLOBAL") : url; ! String userName= ERXSystem.getProperty(aModelName + ".DBUser"); ! userName= userName ==null ? ERXSystem.getProperty("dbConnectUserGLOBAL") : userName; ! String passwd= ERXSystem.getProperty(aModelName + ".DBPassword"); ! passwd= passwd ==null ? ERXSystem.getProperty("dbConnectPasswordGLOBAL") : passwd; ! String driver= ERXSystem.getProperty(aModelName + ".DBDriver"); ! driver= driver ==null ? ERXSystem.getProperty("dbConnectDriverGLOBAL") : driver; ! String serverName= ERXSystem.getProperty(aModelName + ".DBServer"); ! serverName=serverName==null ? ERXSystem.getProperty("dbConnectServerGLOBAL") : serverName; ! String h= ERXSystem.getProperty(aModelName + ".DBHostName"); ! h = h ==null ? ERXSystem.getProperty("dbConnectHostNameGLOBAL") : h; ! String jdbcInfo= ERXSystem.getProperty(aModelName + ".DBJDBCInfo"); ! ! // additional information used for ERXJDBCConnectionBroker ! String minConnections = ERXSystem.getProperty(aModelName + ".DBMinConnections"); ! minConnections = minConnections == null ? ERXProperties.stringForKeyWithDefault("dbMinConnectionsGLOBAL", "20") : minConnections; ! String maxConnections = ERXSystem.getProperty(aModelName + ".DBMaxConnections"); ! maxConnections = maxConnections == null ? ERXProperties.stringForKeyWithDefault("dbMaxConnectionsGLOBAL", "20") : maxConnections; ! String logPath = ERXSystem.getProperty(aModelName + ".DBLogPath"); ! logPath = logPath == null ? ERXProperties.stringForKeyWithDefault("dbLogPathGLOBAL", "/tmp/ERXJDBCConnectionBroker_@@name@@_@@WOPort@@.log") : logPath; ! String connectionRecycle = ERXSystem.getProperty(aModelName + ".DBConnectionRecycle"); ! connectionRecycle = connectionRecycle == null ? ERXProperties.stringForKeyWithDefault("dbConnectionRecycleGLOBAL", "1.0") : connectionRecycle; ! String maxCheckout = ERXSystem.getProperty(aModelName + ".DBMaxCheckout"); ! maxCheckout = maxCheckout == null ? ERXProperties.stringForKeyWithDefault("dbMaxCheckoutGLOBAL", "86400") : maxCheckout; ! String debugLevel = ERXSystem.getProperty(aModelName + ".DBDebugLevel"); ! debugLevel = debugLevel == null ? ERXProperties.stringForKeyWithDefault("dbDebugLevelGLOBAL", "1") : debugLevel; ! ! if (jdbcInfo != null && jdbcInfo.length() > 0 && jdbcInfo.charAt(0) == '^') { ! String modelName = jdbcInfo.substring(1, jdbcInfo.length()); ! EOModel modelForCopy = aModel.modelGroup().modelNamed(modelName); ! if (modelForCopy != null) { ! jdbcInfoDictionary = (NSDictionary)modelForCopy.connectionDictionary().objectForKey("jdbc2Info"); ! } else { ! log.warn("Unable to find model named \"" + modelName + "\""); ! jdbcInfo = null; ! } ! } ! jdbcInfo= jdbcInfo ==null ? ERXSystem.getProperty("dbConnectJDBCInfoGLOBAL") : jdbcInfo; ! String plugin= ERXSystem.getProperty(aModelName + ".DBPlugin"); ! plugin= plugin ==null ? ERXSystem.getProperty("dbConnectPluginGLOBAL") : plugin; ! ! // build the URL if we have a Postgresql plugin ! if ("Postgresql".equals(plugin) ! && ERXStringUtilities.stringIsNullOrEmpty(url) ! && !ERXStringUtilities.stringIsNullOrEmpty(serverName) ! && !ERXStringUtilities.stringIsNullOrEmpty(h)) { ! url = "jdbc:postgresql://"+h+"/"+serverName; ! } ! ! if (url!=null || userName!=null || passwd!=null || driver!=null || jdbcInfo!=null || plugin!=null) { ! newConnectionDictionary=new NSMutableDictionary(aModel.connectionDictionary()); ! if (url!=null) newConnectionDictionary.setObjectForKey(url, "URL"); ! if (userName!=null) newConnectionDictionary.setObjectForKey(userName,"username"); ! if (passwd!=null) newConnectionDictionary.setObjectForKey(passwd,"password"); ! if (driver!=null) newConnectionDictionary.setObjectForKey(driver,"driver"); ! if (jdbcInfoDictionary != null) { ! newConnectionDictionary.setObjectForKey(jdbcInfoDictionary, "jdbc2Info"); ! } else if (jdbcInfo!=null) { ! NSDictionary d=(NSDictionary)NSPropertyListSerialization.propertyListFromString(jdbcInfo); ! if (d!=null) ! newConnectionDictionary.setObjectForKey(d,"jdbc2Info"); ! else ! newConnectionDictionary.removeObjectForKey("jdbc2Info"); ! } ! if (plugin!=null) newConnectionDictionary.setObjectForKey(plugin,"plugin"); ! ! // set the information for ERXJDBCConnectionBroker ! newConnectionDictionary.setObjectForKey(minConnections, "minConnections"); ! newConnectionDictionary.setObjectForKey(maxConnections, "maxConnections"); ! newConnectionDictionary.setObjectForKey(logPath, "logPath"); ! newConnectionDictionary.setObjectForKey(connectionRecycle, "connectionRecycle"); ! newConnectionDictionary.setObjectForKey(maxCheckout, "maxCheckout"); ! newConnectionDictionary.setObjectForKey(debugLevel, "debugLevel"); ! ! aModel.setConnectionDictionary(newConnectionDictionary); ! } } ! boolean removeJdbc2Info = ERXProperties.booleanForKeyWithDefault(aModelName + ".removeJdbc2Info", false); ! if (removeJdbc2Info && newConnectionDictionary != null) { ! newConnectionDictionary.removeObjectForKey("jdbc2Info"); ! } ! if (newConnectionDictionary!=null && log.isDebugEnabled()) { ! if (newConnectionDictionary.objectForKey("password")!=null) ! newConnectionDictionary.setObjectForKey("<deleted for log>", "password"); ! log.debug("New Connection Dictionary for "+aModelName+": "+newConnectionDictionary); ! } ! ! ! // based on an idea from Stefan Apelt <st...@te...> ! String f = ERXSystem.getProperty(aModelName + ".EOPrototypesFile"); ! f = f ==null ? ERXSystem.getProperty("EOPrototypesFileGLOBAL") : f; ! if(f != null) { ! NSDictionary dict = (NSDictionary)NSPropertyListSerialization.propertyListFromString(ERXStringUtilities.stringFromResource(f, "", null)); ! if(dict != null) { ! if (log.isDebugEnabled()) log.debug("Adjusting prototypes from " + f); ! EOEntity proto = aModel.entityNamed("EOPrototypes"); ! if (proto == null) { ! log.warn("No prototypes found in model named \"" + aModelName + "\", although the EOPrototypesFile default was set!"); ! } else { ! aModel.removeEntity(proto); ! proto = new EOEntity(dict, aModel); ! proto.awakeWithPropertyList(dict); ! aModel.addEntity(proto); ! } } } ! String prototypeEntityName = ERXSystem.getProperty(aModelName + ".EOPrototypesEntity"); ! if (prototypeEntityName == null && databaseConfig != null) { ! prototypeEntityName = (String) databaseConfig.objectForKey("prototypeEntityName"); } ! // If you don't explicitly set a prototype name, and you don't declare a preferred databaseConfig, ! // then attempt to load Wonder-style prototypes with the name EOJDBC(driverName)Prototypes. ! if (prototypeEntityName == null) { ! if ("JDBC".equals(aModel.adaptorName())) { ! NSDictionary connectionDictionary = aModel.connectionDictionary(); ! if (connectionDictionary != null) { ! String jdbcUrl = (String) connectionDictionary.objectForKey("URL"); ! if (jdbcUrl != null) { ! String pluginName = (String) connectionDictionary.objectForKey("plugin"); ! if(pluginName == null) { ! pluginName = JDBCPlugIn.plugInNameForURL(jdbcUrl); ! if(pluginName == null) { ! int firstColon = jdbcUrl.indexOf(':'); ! int secondColon = jdbcUrl.indexOf(':', firstColon + 1); ! if (firstColon != -1 && secondColon != -1) { ! String driverName = jdbcUrl.substring(firstColon + 1, secondColon); ! String driverPrototypeEntityName = "EOJDBC" + driverName + "Prototypes"; ! // This check isn't technically necessary since it doesn't down below, but since ! // we are guessing here, I don't want themt o get a warning about the prototype not ! // being found if they aren't even using Wonder prototypes. ! if (aModel.modelGroup().entityNamed(driverPrototypeEntityName) != null) { ! prototypeEntityName = driverPrototypeEntityName; ! } ! } ! } else { ! pluginName = ERXStringUtilities.lastPropertyKeyInKeyPath(pluginName); ! pluginName = pluginName.replaceFirst("PlugIn", ""); ! } ! } ! if (pluginName != null) { ! String pluginPrototypeEntityName = "EOJDBC" + pluginName + "Prototypes"; ! // This check isn't technically necessary since it doesn't down below, but since ! // we are guessing here, I don't want themt o get a warning about the prototype not ! // being found if they aren't even using Wonder prototypes. ! if (aModel.modelGroup().entityNamed(pluginPrototypeEntityName) != null) { ! prototypeEntityName = pluginPrototypeEntityName; ! } else { ! log.error("No prototypes found for plugin: " + pluginName + ", using EOPrototypes: " + aModelName); ! } ! } ! } ! } ! } } - // global prototype setting not supported yet - //e = e ==null ? ERXSystem.getProperty("EOPrototypesEntityGLOBAL") : e; - if(prototypeEntityName != null) { - // we look for the entity globally so we can have one prototype entity - EOEntity newPrototypeEntity = aModel.modelGroup().entityNamed(prototypeEntityName); - if (newPrototypeEntity == null) { - log.warn("Prototype Entity named "+prototypeEntityName+" not found in model "+aModel.name()); - } else { - if (log.isDebugEnabled()) log.debug("Adjusting prototypes to those from entity " + prototypeEntityName); ! EOEntity proto = aModel.entityNamed("EOPrototypes"); ! if(proto != null) aModel.removeEntity(proto); ! ! aModel.removeEntity(newPrototypeEntity); ! newPrototypeEntity.setName("EOPrototypes"); ! aModel.addEntity(newPrototypeEntity); } } } ! } --- 366,702 ---- } + private String getProperty(String key, String alternateKey, String defaultValue) { + String value = ERXSystem.getProperty(key); + if(value == null) { + value = ERXSystem.getProperty(alternateKey); + } + if(value == null) { + value = defaultValue; + } + return defaultValue; + } + + private String getProperty(String key, String alternateKey) { + return getProperty(key, alternateKey, null); + } + + protected void fixOracleDictionary(EOModel model) { + String modelName = model.name(); + String serverName = getProperty(modelName + ".DBServer", "dbConnectServerGLOBAL"); + String userName = getProperty(modelName + ".DBUser", "dbConnectUserGLOBAL"); + String passwd = getProperty(modelName + ".DBPassword", "dbConnectPasswordGLOBAL"); + + NSMutableDictionary newConnectionDictionary = new NSMutableDictionary(model.connectionDictionary()); + if (serverName != null) + newConnectionDictionary.setObjectForKey(serverName, "serverId"); + if (userName != null) + newConnectionDictionary.setObjectForKey(userName, "userName"); + if (passwd != null) + newConnectionDictionary.setObjectForKey(passwd, "password"); + model.setConnectionDictionary(newConnectionDictionary); + } + + protected void fixFlatDictionary(EOModel model) { + String aModelName = model.name(); + String path = getProperty(aModelName + ".DBPath", "dbConnectPathGLOBAL"); + if (path != null) { + if (path.indexOf(" ") != -1) { + NSArray a = NSArray.componentsSeparatedByString(path, " "); + if (a.count() == 2) { + path = ERXFileUtilities.pathForResourceNamed((String) a.objectAtIndex(0), (String) a.objectAtIndex(1), null); + } + } + } else { + // by default we take <modelName>.db in the directory we + // found the model + path = model.pathURL().getFile(); + path = NSPathUtilities.stringByDeletingLastPathComponent(path); + path = NSPathUtilities.stringByAppendingPathComponent(path, model.name() + ".db"); + } + NSMutableDictionary newConnectionDictionary = new NSMutableDictionary(model.connectionDictionary()); + if (path != null) + newConnectionDictionary.setObjectForKey(path, "path"); + if (operatingSystem() == WindowsOperatingSystem) + newConnectionDictionary.setObjectForKey("\r\n", "rowSeparator"); + model.setConnectionDictionary(newConnectionDictionary); + } + + protected void fixOpenBaseDictionary(EOModel model) { + String aModelName = model.name(); + String db = getProperty(aModelName + ".DBDatabase", "dbConnectDatabaseGLOBAL"); + String h = getProperty(aModelName + ".DBHostName", "dbConnectHostNameGLOBAL"); + NSMutableDictionary newConnectionDictionary = new NSMutableDictionary(model.connectionDictionary()); + if (db != null) + newConnectionDictionary.setObjectForKey(db, "databaseName"); + if (h != null) + newConnectionDictionary.setObjectForKey(h, "hostName"); + model.setConnectionDictionary(newConnectionDictionary); + } + + protected void fixJDBCDictionary(EOModel model) { + String aModelName = model.name(); + + boolean poolConnections = ERXJDBCAdaptor.useConnectionBroker(); + + String url = getProperty(aModelName + ".URL", "dbConnectURLGLOBAL"); + String userName = getProperty(aModelName + ".DBUser", "dbConnectUserGLOBAL"); + String passwd = getProperty(aModelName + ".DBPassword", "dbConnectPasswordGLOBAL"); + String driver = getProperty(aModelName + ".DBDriver", "dbConnectDriverGLOBAL"); + String serverName = getProperty(aModelName + ".DBServer", "dbConnectServerGLOBAL"); + String h = getProperty(aModelName + ".DBHostName", "dbConnectHostNameGLOBAL"); + String jdbcInfo = getProperty(aModelName + ".DBJDBCInfo", "dbConnectJDBCInfoGLOBAL"); + + // additional information used for ERXJDBCConnectionBroker + NSMutableDictionary poolingDictionary = new NSMutableDictionary(); + if (poolConnections) { + poolingDictionary.setObjectForKey(getProperty(aModelName + ".DBMinConnections", "dbMinConnectionsGLOBAL", + "20"), "minConnections"); + poolingDictionary.setObjectForKey(getProperty(aModelName + ".DBMaxConnections", "dbMaxConnectionsGLOBAL", + "20"), "maxConnections"); + poolingDictionary.setObjectForKey(getProperty(aModelName + ".DBLogPath", "dbLogPathGLOBAL", + "/tmp/ERXJDBCConnectionBroker_@@name@@_@@WOPort@@.log"), "logPath"); + poolingDictionary.setObjectForKey(getProperty(aModelName + ".DBConnectionRecycle", "dbConnectionRecycleGLOBAL", + "1.0"), "connectionRecycle"); + poolingDictionary.setObjectForKey(getProperty(aModelName + ".DBMaxCheckout", "dbMaxCheckoutGLOBAL", + "86400"), "maxCheckout"); + poolingDictionary.setObjectForKey(getProperty(aModelName + ".DBDebugLevel", "dbDebugLevelGLOBAL", + "1"), "debugLevel"); + } + + NSDictionary jdbcInfoDictionary = null; + if (jdbcInfo != null && jdbcInfo.length() > 0 && jdbcInfo.charAt(0) == '^') { + String modelName = jdbcInfo.substring(1, jdbcInfo.length()); + EOModel modelForCopy = model.modelGroup().modelNamed(modelName); + if (modelForCopy != null && modelForCopy != model) { + jdbcInfoDictionary = (NSDictionary) modelForCopy.connectionDictionary().objectForKey("jdbc2Info"); + } else { + log.warn("Unable to find model named \"" + modelName + "\""); + jdbcInfo = null; + } + } + + String plugin = getProperty(aModelName + ".DBPlugin", "dbConnectPluginGLOBAL"); + + // build the URL if we have a Postgresql plugin + if ("Postgresql".equals(plugin) && ERXStringUtilities.stringIsNullOrEmpty(url) + && !ERXStringUtilities.stringIsNullOrEmpty(serverName) && !ERXStringUtilities.stringIsNullOrEmpty(h)) { + url = "jdbc:postgresql://" + h + "/" + serverName; + } + + NSMutableDictionary newConnectionDictionary = new NSMutableDictionary(model.connectionDictionary()); + if (url != null) + newConnectionDictionary.setObjectForKey(url, "URL"); + if (userName != null) + newConnectionDictionary.setObjectForKey(userName, "username"); + if (passwd != null) + newConnectionDictionary.setObjectForKey(passwd, "password"); + if (driver != null) + newConnectionDictionary.setObjectForKey(driver, "driver"); + if (jdbcInfoDictionary != null) { + newConnectionDictionary.setObjectForKey(jdbcInfoDictionary, "jdbc2Info"); + } else if (jdbcInfo != null) { + NSDictionary d = (NSDictionary) NSPropertyListSerialization.propertyListFromString(jdbcInfo); + if (d != null) + newConnectionDictionary.setObjectForKey(d, "jdbc2Info"); + else + newConnectionDictionary.removeObjectForKey("jdbc2Info"); + } + if (plugin != null) + newConnectionDictionary.setObjectForKey(plugin, "plugin"); + + // set the information for ERXJDBCConnectionBroker + newConnectionDictionary.addEntriesFromDictionary(poolingDictionary); + + boolean removeJdbc2Info = ERXProperties.booleanForKeyWithDefault(aModelName + ".removeJdbc2Info", false); + if (removeJdbc2Info) { + newConnectionDictionary.removeObjectForKey("jdbc2Info"); + } + + model.setConnectionDictionary(newConnectionDictionary); + } + /** ! * Resets the connection dictionary to the specified values that are in the ! * defaults. This method will look for defaults in the form: ! * ! * <pre><code> ! * <MODELNAME>.DBServer ! * <MODELNAME>.DBUser ! * <MODELNAME>.DBPassword ! * <MODELNAME>.URL (for JDBC) ! * </code></pre> ! * ! * if the serverName and username both exists, we overwrite the connection ! * dict (password is optional). Otherwise we fall back to what's in the ! * model. ! * * Likewise default values can be specified of the form: ! * ! * <pre><code> ! * dbConnectUserGLOBAL ! * dbConnectPasswordGLOBAL ! * dbConnectURLGLOBAL ! * </code></pre> ! * ! * @param model ! * to be reset */ ! public void resetConnectionDictionaryInModel(EOModel model) { ! if(model == null) { ! throw new IllegalArgumentException("Model can't be null"); ! } ! String modelName=model.name(); ! log.debug("Adjusting "+modelName); ! NSDictionary old = model.connectionDictionary(); ! if(model.adaptorName() == null) { ! log.info("Skipping model '" + modelName + "', it has no adaptor name set"); ! return; ! } ! ! // Support for EODatabaseConfig from EntityModeler. The value of YourEOModelName.DBConfigName is ! // used to lookup the corresponding EODatabaseConfig name from user info. The connection dictionary ! // defined in the databaseConfig section completely replaces the connection dictionary in the ! // EOModel. After the initial replacement, all the additional PW model configurations are then ! // applied to the new dictionary. ! String databaseConfigName = getProperty(modelName + ".DBConfigName", "dbConfigNameGLOBAL"); ! NSDictionary databaseConfig = null; ! if (databaseConfigName != null) { ! NSDictionary userInfo = model.userInfo(); ! if (userInfo != null) { NSDictionary entityModelerDictionary = (NSDictionary) userInfo.objectForKey("_EntityModeler"); if (entityModelerDictionary != null) { ! NSDictionary databaseConfigsDictionary = (NSDictionary) entityModelerDictionary.objectForKey("databaseConfigs"); ! if (databaseConfigsDictionary != null) { ! databaseConfig = (NSDictionary) databaseConfigsDictionary.objectForKey(databaseConfigName); ! if (databaseConfig != null) { ! NSDictionary connectionDictionary = (NSDictionary) databaseConfig.objectForKey("connectionDictionary"); ! model.setConnectionDictionary(connectionDictionary); ! } } } } ! } ! if (model.adaptorName().indexOf("Oracle") != -1) { ! fixOracleDictionary(model); ! } else if (model.adaptorName().indexOf("Flat") != -1) { ! fixFlatDictionary(model); ! } else if (model.adaptorName().indexOf("OpenBase")!=-1) { ! fixOpenBaseDictionary(model); ! } else if (model.adaptorName().indexOf("JDBC")!=-1) { ! fixJDBCDictionary(model); ! } ! if (log.isDebugEnabled() && !old.equals(model.connectionDictionary())) { ! NSMutableDictionary dict = model.connectionDictionary().mutableClone(); ! if (dict.objectForKey("password") != null) { ! dict.setObjectForKey("<deleted for log>", "password"); ! log.debug("New Connection Dictionary for " + modelName + ": " + dict); } + } ! fixPrototypes(model, databaseConfig); ! } ! ! private void fixPrototypes(EOModel model, NSDictionary databaseConfig) { ! String modelName = model.name(); ! // based on an idea from Stefan Apelt <st...@te...> ! String f = getProperty(modelName + ".EOPrototypesFile", "EOPrototypesFileGLOBAL"); ! if (f != null) { ! NSDictionary dict = (NSDictionary) NSPropertyListSerialization ! .propertyListFromString(ERXStringUtilities.stringFromResource(f, "", null)); ! if (dict != null) { ! if (log.isDebugEnabled()) ! log.debug("Adjusting prototypes from " + f); ! EOEntity proto = model.entityNamed("EOPrototypes"); ! if (proto == null) { ! log.warn("No prototypes found in model named \"" + modelName ! + "\", although the EOPrototypesFile default was set!"); ! } else { ! model.removeEntity(proto); ! proto = new EOEntity(dict, model); ! proto.awakeWithPropertyList(dict); ! model.addEntity(proto); } } ! } ! ! String prototypeEntityName = ERXSystem.getProperty(modelName + ".EOPrototypesEntity"); ! if (prototypeEntityName == null && databaseConfig != null) { ! prototypeEntityName = (String) databaseConfig.objectForKey("prototypeEntityName"); ! } ! ! if(prototypeEntityName == null) { ! String pluginName = guessPluginName(model); ! if (pluginName != null) { ! String pluginPrototypeEntityName = "EOJDBC" + pluginName + "Prototypes"; ! // This check isn't technically necessary since ! // it doesn't down below, but since ! // we are guessing here, I don't want themt o ! // get a warning about the prototype not ! // being found if they aren't even using Wonder ! // prototypes. ! if (model.modelGroup().entityNamed(pluginPrototypeEntityName) != null) { ! prototypeEntityName = pluginPrototypeEntityName; ! } } + } ! // global prototype setting not supported yet ! // e = e ==null ? ERXSystem.getProperty("EOPrototypesEntityGLOBAL") ! // : e; ! if (prototypeEntityName != null) { ! // we look for the entity globally so we can have one prototype ! // entity ! EOEntity newPrototypeEntity = model.modelGroup().entityNamed(prototypeEntityName); ! if (newPrototypeEntity == null) { ! log.warn("Prototype Entity named " + prototypeEntityName + " not found in model " + model.name()); ! } else { ! if (log.isDebugEnabled()) ! log.debug("Adjusting prototypes to those from entity " + prototypeEntityName); ! ! EOEntity proto = model.entityNamed("EOPrototypes"); ! if (proto != null) ! model.removeEntity(proto); ! ! model.removeEntity(newPrototypeEntity); ! newPrototypeEntity.setName("EOPrototypes"); ! model.addEntity(newPrototypeEntity); } + } + } ! private String guessPluginName(EOModel model) { ! String pluginName = null; ! // If you don't explicitly set a prototype name, and you don't ! // declare a preferred databaseConfig, ! // then attempt to load Wonder-style prototypes with the name ! // EOJDBC(driverName)Prototypes. ! if ("JDBC".equals(model.adaptorName())) { ! NSDictionary connectionDictionary = model.connectionDictionary(); ! if (connectionDictionary != null) { ! String jdbcUrl = (String) connectionDictionary.objectForKey("URL"); ! if (jdbcUrl != null) { ! pluginName = (String) connectionDictionary.objectForKey("plugin"); ! if (pluginName == null) { ! pluginName = JDBCPlugIn.plugInNameForURL(jdbcUrl); ! if (pluginName == null) { ! int firstColon = jdbcUrl.indexOf(':'); ! int secondColon = jdbcUrl.indexOf(':', firstColon + 1); ! if (firstColon != -1 && secondColon != -1) { ! pluginName = jdbcUrl.substring(firstColon + 1, secondColon); ! } ! } else { ! pluginName = ERXStringUtilities.lastPropertyKeyInKeyPath(pluginName); ! pluginName = pluginName.replaceFirst("PlugIn", ""); ! } ! } } } } ! return pluginName; } |