diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.classpath b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.classpath
new file mode 100644
index 00000000000..b3c4139fc5b
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.classpath
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.gitignore b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.gitignore
new file mode 100644
index 00000000000..fcc7e7a559b
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.gitignore
@@ -0,0 +1,6 @@
+target
+bin
+build
+*.xcodeproj
+*.pbxproj
+ant.*
\ No newline at end of file
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.project b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.project
new file mode 100644
index 00000000000..264c3e865b9
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.project
@@ -0,0 +1,23 @@
+
+
+ OpenBaseWOPKPlugIn
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.objectstyle.wolips.incrementalbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.objectstyle.wolips.incrementalframeworknature
+
+
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Resources/Properties b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Resources/Properties
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InQualifier.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InQualifier.java
new file mode 100644
index 00000000000..755ede30502
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InQualifier.java
@@ -0,0 +1,301 @@
+package com.openbase.webobjects.qualifiers;
+//
+// InQualifier.java
+//
+// Much thanks to the Wonder guys and Pierre Bernard for their helpful examples
+//
+// The in qualifier allows qualification on an attribute that is contained in a list of values. This qualifier
+// supports both in-memory and sql based qualification.
+//
+// The SQL generated is of the form: "VALUE IN (XX, YY, ZZ)"
+//
+// Created by Alex Cone on 12/16/05.
+// Copyright (c) 2005 __MyCompanyName__. All rights reserved.
+//
+
+import com.webobjects.foundation.*;
+import com.webobjects.eoaccess.*;
+import com.webobjects.eocontrol.*;
+import java.util.*;
+import org.apache.log4j.*;
+
+public class InQualifier extends EOKeyValueQualifier implements EOQualifierEvaluation, Cloneable {
+ protected static Logger LOGGER = Logger.getLogger(InQualifier.class.getName());
+
+ private static final String InKeyword = " IN ";
+
+ private String _key = null;
+ private NSArray _values = null;
+
+ /** register SQL generation support for the qualifier */
+ static {
+ EOQualifierSQLGeneration.Support.setSupportForClass(new InQualifierSQLGenerationSupport(), InQualifier.class);
+ }
+
+ public static String allButLastPathComponent(String path) {
+ int i = path.lastIndexOf(NSKeyValueCodingAdditions.KeyPathSeparator);
+ return (i < 0) ? null : path.substring(0, i);
+ }
+
+ public static String lastPathComponent(String path) {
+ int i = path.lastIndexOf(NSKeyValueCodingAdditions.KeyPathSeparator);
+ return (i < 0) ? path : path.substring(i + 1);
+ }
+
+ public InQualifier(String aKey, NSArray values) {
+ // Just to make EOKeyValueQualifier happy
+ super(aKey, EOQualifier.QualifierOperatorEqual, values);
+ this.setKey(aKey);
+ this.setValues(values);
+ }
+
+ public String key() {
+ return _key;
+ }
+
+ public void setKey(String aValue) {
+ _key = aValue;
+ }
+
+ public NSArray values() {
+ return _values;
+ }
+
+ public void setValues(NSArray anArray) {
+ _values = anArray;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("(");
+ buffer.append(key());
+ buffer.append(InKeyword);
+ buffer.append("(");
+
+ Enumeration e = values().objectEnumerator();
+ while (e.hasMoreElements()) {
+ Object object = e.nextElement();
+
+ if (object == NSKeyValueCoding.NullValue) {
+ buffer.append("null");
+ } else if (object instanceof Number) {
+ buffer.append(object);
+ } else if (object instanceof EOQualifierVariable) {
+ buffer.append("$");
+ buffer.append(((EOQualifierVariable) object).key());
+ } else {
+ buffer.append("'");
+ buffer.append(object);
+ buffer.append("'");
+ }
+ if (e.hasMoreElements()) {
+ buffer.append(", ");
+ }
+ }
+ buffer.append("))");
+ return buffer.toString();
+ }
+
+ public void addQualifierKeysToSet(NSMutableSet aSet) {
+ if (aSet != null) {
+ String aKey = this.key();
+ if (aKey != null) {
+ aSet.addObject(aKey);
+ }
+ }
+ }
+
+ public boolean evaluateWithObject(Object object) {
+ Object value = NSKeyValueCodingAdditions.Utility.valueForKeyPath(object, key());
+ if (value == null) {
+ value = NSKeyValueCoding.NullValue;
+ }
+ return values().containsObject(value);
+ }
+
+ // we don't do bindings
+ public EOQualifier qualifierWithBindings(NSDictionary someBindings, boolean requiresAll) {
+ return (EOQualifier) this.clone();
+ }
+ // we don't do validation
+ public void validateKeysWithRootClassDescription(EOClassDescription aClassDescription) {
+ super.validateKeysWithRootClassDescription(aClassDescription);
+ }
+
+
+ public static class InQualifierSQLGenerationSupport extends EOQualifierSQLGeneration.Support {
+
+ public InQualifierSQLGenerationSupport() {
+ super();
+ }
+
+ public String sqlStringForSQLExpression(EOQualifier eoqualifier, EOSQLExpression aSQLExpression) {
+ String sqlString = null;
+ if ((aSQLExpression != null) && (aSQLExpression.entity() != null)) {
+ InQualifier inQualifier = (InQualifier)eoqualifier;
+ EOEntity anEntity = aSQLExpression.entity();
+ String aKey = inQualifier.key();
+ NSArray aValuesArray = inQualifier.values();
+
+ if ((aKey != null) && (aValuesArray != null) && (aValuesArray.count() > 0)) {
+ StringBuffer sb = new StringBuffer();
+ EOAttribute keyAttr = attributeForPath(anEntity, aKey);
+ String attributeString = aSQLExpression.sqlStringForAttribute(keyAttr);
+ sb.append(aSQLExpression.formatSQLString(attributeString, keyAttr.readFormat()));
+ sb.append(InQualifier.InKeyword);
+ sb.append("(");
+
+ for (int i = 0; i < aValuesArray.count(); i++ ) {
+ EOKeyValueQualifier containsQualifier = new EOKeyValueQualifier(aKey, EOQualifier.QualifierOperatorContains,
+ aValuesArray.objectAtIndex(i));
+ containsQualifier = (EOKeyValueQualifier) anEntity.schemaBasedQualifier(containsQualifier);
+ if ( i > 0 ) {
+ sb.append(", ");
+ }
+ sb.append(aSQLExpression.sqlStringForValue(containsQualifier.value(), containsQualifier.key()));
+ }
+ sb.append(")");
+ sqlString = sb.toString();
+ }
+ }
+ return sqlString;
+ }
+
+ public EOQualifier schemaBasedQualifierWithRootEntity(EOQualifier qualifier, EOEntity entity) {
+ InQualifier inQualifier = (InQualifier) qualifier;
+ String keyPath = inQualifier.key();
+ EORelationship relationship = relationshipForPath(entity, keyPath);
+
+ if (relationship != null) {
+ if (relationship.isFlattened()) {
+ relationship = (EORelationship) relationship.componentRelationships().lastObject();
+ }
+ // just handle single key joins for now
+ EOJoin join = (EOJoin)relationship.joins().objectAtIndex(0);
+ String destAttributeName = join.destinationAttribute().name();
+ String optimizedPath = optimizeQualifierKeyPath(entity, keyPath, destAttributeName);
+
+ NSMutableSet newValues = new NSMutableSet(inQualifier.values().count());
+ Enumeration values = inQualifier.values().objectEnumerator();
+
+ while (values.hasMoreElements()) {
+ Object value = values.nextElement();
+
+ if (value == NSKeyValueCoding.NullValue || (value instanceof EOQualifierVariable)) {
+ newValues.addObject(value);
+ } else {
+ EOEnterpriseObject enterpriseObject = (EOEnterpriseObject) value;
+ EOObjectStoreCoordinator objectStoreCoordinator =
+ (EOObjectStoreCoordinator) enterpriseObject.editingContext().rootObjectStore();
+ NSDictionary destValues =
+ objectStoreCoordinator.valuesForKeys(new NSArray(destAttributeName), enterpriseObject);
+ Object destVal = destValues.objectForKey(destAttributeName);
+ newValues.addObject((destVal != null ? destVal: NSKeyValueCoding.NullValue));
+ }
+ }
+ return nullValueAwareQualifier(new InQualifier(optimizedPath, newValues.allObjects()));
+ } else {
+ return nullValueAwareQualifier(inQualifier);
+ }
+ }
+
+ public EOQualifier qualifierMigratedFromEntityRelationshipPath(EOQualifier eoqualifier, EOEntity eoentity, String s) {
+ // the key migration is the same as for EOKeyValueQualifier
+ InQualifier inQualifier=(InQualifier)eoqualifier;
+ return new InQualifier(_translateKeyAcrossRelationshipPath(inQualifier.key(), s, eoentity), inQualifier.values());
+ }
+
+ // Protected instance methods
+ protected EOQualifier nullValueAwareQualifier(InQualifier inQualifier) {
+ if (inQualifier.values().containsObject(NSKeyValueCoding.NullValue)) {
+ EOQualifier nullQual = new EOKeyValueQualifier(inQualifier.key(), EOQualifier.QualifierOperatorEqual, NSKeyValueCoding.NullValue);
+ NSSet aSet = new NSSet(inQualifier.values());
+ NSSet noNullSet = aSet.setBySubtractingSet(new NSSet(NSKeyValueCoding.NullValue));
+ EOQualifier noNullQual = new InQualifier(inQualifier.key(), noNullSet.allObjects());
+ return new EOOrQualifier(new NSArray(new Object[] { nullQual, noNullQual }));
+ } else {
+ return inQualifier;
+ }
+ }
+
+ protected EOAttribute attributeForPath(EOEntity entity, String keyPath) {
+ if (keyPath != null) {
+ StringTokenizer tokenizer = new StringTokenizer(keyPath, NSKeyValueCodingAdditions.KeyPathSeparator);
+ EORelationship relationship = null;
+ while (tokenizer.hasMoreElements()) {
+ String key = tokenizer.nextToken();
+ if (tokenizer.hasMoreElements()) {
+ relationship = entity.anyRelationshipNamed(key);
+ } else {
+ EOAttribute attribute = entity.anyAttributeNamed(key);
+ if (attribute == null) {
+ relationship = entity.anyRelationshipNamed(key);
+ if (relationship != null) {
+ if (relationship.isFlattened()) {
+ relationship = (EORelationship) relationship.componentRelationships().lastObject();
+ }
+ // just handle single key joins for now
+ EOJoin join = (EOJoin)relationship.joins().objectAtIndex(0);
+ return join.sourceAttribute();
+ }
+ }
+ }
+ if (relationship != null) {
+ entity = relationship.destinationEntity();
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+ return null;
+ }
+
+ protected EORelationship relationshipForPath(EOEntity entity, String keyPath) {
+ if (keyPath != null) {
+ StringTokenizer tokenizer = new StringTokenizer(keyPath, NSKeyValueCodingAdditions.KeyPathSeparator);
+ EORelationship relationship = null;
+ while (tokenizer.hasMoreElements()) {
+ String key = tokenizer.nextToken();
+ relationship = entity.anyRelationshipNamed(key);
+ if (relationship != null) {
+ entity = relationship.destinationEntity();
+ } else {
+ return null;
+ }
+ }
+ return relationship;
+ }
+ return null;
+ }
+
+ protected String optimizeQualifierKeyPath(EOEntity entity, String keyPath, String attributeName) {
+ if ((keyPath == null) || (keyPath.length() == 0)) {
+ return attributeName;
+ } else {
+ EORelationship relationship = (entity == null) ? null : relationshipForPath(entity, keyPath);
+ if (relationship != null) {
+ NSArray joins = relationship.joins();
+ int joinCount = (joins == null) ? 0 : joins.count();
+ for (int i = joinCount - 1; i >= 0; i--) {
+ EOJoin join = (EOJoin) joins.objectAtIndex(i);
+ if (join.destinationAttribute().name().equals(attributeName)) {
+ String newPath = allButLastPathComponent(keyPath);
+ String newAttributeName = join.sourceAttribute().name();
+ return optimizeQualifierKeyPath(entity, newPath, newAttributeName);
+ }
+ }
+ }
+ return (keyPath + NSKeyValueCodingAdditions.KeyPathSeparator + attributeName);
+ }
+ }
+
+ }
+
+ // cloning support
+ public Object clone() {
+ return new InQualifier(this.key(), this.values());
+ }
+
+}
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InSubqueryQualifier.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InSubqueryQualifier.java
new file mode 100644
index 00000000000..03ffc57199e
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InSubqueryQualifier.java
@@ -0,0 +1,279 @@
+package com.openbase.webobjects.qualifiers;
+//
+// InSubqueryQualifier.java
+//
+// Much thanks to the Wonder guys and Pierre Bernard for their helpful examples
+//
+// Created by Alex Cone on 12/18/05.
+// Copyright (c) 2005 __MyCompanyName__. All rights reserved.
+//
+
+import com.webobjects.foundation.*;
+import com.webobjects.eoaccess.*;
+import com.webobjects.eocontrol.*;
+
+import java.util.*;
+import java.lang.reflect.*;
+
+import org.apache.log4j.*;
+
+public class InSubqueryQualifier extends EOQualifier implements EOQualifierEvaluation, Cloneable {
+ protected static Logger LOGGER = Logger.getLogger(InQualifier.class.getName());
+
+ private static final String InKeyword = " IN ";
+
+ /** Path to an attribute or relationship of the qualified entity
+ */
+ protected String _key;
+
+ /** Name of the entity from which to get values to match against
+ */
+ protected String _entityName;
+
+ /** Name of the attribute in the destination entity to match against
+ */
+ protected String _attributePath;
+
+ /** Qualifier to limit the list of acceptable values
+ */
+ protected EOQualifier _subQualifier;
+
+ /** register SQL generation support for the qualifier */
+ static {
+ EOQualifierSQLGeneration.Support.setSupportForClass(new InSubqueryQualifierSQLGenerationSupport(), InSubqueryQualifier.class);
+ }
+
+ /** Constructor for queries off an attribute.
+ *
+ * @param key key path to an attribute of the qualified entity
+ * @param entityName name of the entity from which to get values to match against
+ * @param attributePath name of the attribute in the destination entity to match against
+ * @param subQualifier qualifier to limit the list of acceptable values
+ */
+ public InSubqueryQualifier(String key, String entityName, String attributePath, EOQualifier subQualifier) {
+ if ((key == null) || (entityName == null) || (attributePath == null)) {
+ throw new IllegalArgumentException("Arguments key, entityName and attributePath may not be null");
+ }
+ this.setKey(key);
+ this.setEntityName(entityName);
+ this.setAttributePath(attributePath);
+ this.setSubQualifier(subQualifier);
+ }
+
+ /** Constructor for queries off a relationship
+ *
+ * @param key key path to a relationship of the qualified entity
+ * @param subQualifier qualifier to limit the list of acceptable values
+ */
+ public InSubqueryQualifier(String key, EOQualifier subQualifier) {
+ if (key == null) {
+ throw new IllegalArgumentException("Argument key may not be null");
+ }
+ this.setKey(key);
+ this.setSubQualifier(subQualifier);
+ }
+
+ public String key() {
+ return _key;
+ }
+
+ public void setKey(String aValue) {
+ _key = aValue;
+ }
+
+ public String entityName() {
+ return _entityName;
+ }
+
+ public void setEntityName(String aValue) {
+ _entityName = aValue;
+ }
+
+ public String attributePath() {
+ return _attributePath;
+ }
+
+ public void setAttributePath(String aValue) {
+ _attributePath = aValue;
+ }
+
+ public EOQualifier subQualifier() {
+ return _subQualifier;
+ }
+
+ public void setSubQualifier(EOQualifier aValue) {
+ _subQualifier = aValue;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("(");
+ buffer.append(key());
+ buffer.append(InKeyword);
+ buffer.append("(");
+ buffer.append(" SELECT ");
+ buffer.append((attributePath() != null) ? attributePath() : "*");
+
+ if (entityName() != null) {
+ buffer.append(" FROM ");
+ buffer.append(entityName());
+ }
+ if (subQualifier() != null) {
+ buffer.append(" WHERE ");
+ buffer.append(subQualifier().toString());
+ }
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+ public void addQualifierKeysToSet(NSMutableSet keySet) {
+ keySet.addObject(key());
+ if (subQualifier() != null) {
+ NSMutableSet subKeySet = new NSMutableSet();
+ subQualifier().addQualifierKeysToSet(subKeySet);
+ if (entityName() == null) {
+ Enumeration subKeys = subKeySet.objectEnumerator();
+ String prefix = key() + NSKeyValueCodingAdditions.KeyPathSeparator;
+ while (subKeys.hasMoreElements()) {
+ keySet.addObject(prefix + subKeys.nextElement());
+ }
+ } else {
+ keySet.addObjectsFromArray(subKeySet.allObjects());
+ }
+ }
+ }
+
+ // we don't do bindings yet
+ public EOQualifier qualifierWithBindings(NSDictionary someBindings, boolean requiresAll) {
+ return (EOQualifier) this.clone();
+ }
+ // we don't do validation
+ public void validateKeysWithRootClassDescription(EOClassDescription aClassDescription) {
+ }
+
+ public Object clone() {
+ return new InSubqueryQualifier(key(), entityName(), attributePath(), subQualifier());
+ }
+
+ public static class InSubqueryQualifierSQLGenerationSupport extends EOQualifierSQLGeneration.Support {
+
+ public InSubqueryQualifierSQLGenerationSupport() {
+ super();
+ }
+
+ public String sqlStringForSQLExpression(EOQualifier eoqualifier, EOSQLExpression aSQLExpression) {
+ String sqlString = null;
+ if ((aSQLExpression != null) && (aSQLExpression.entity() != null)) {
+ InSubqueryQualifier isQualifier = (InSubqueryQualifier)eoqualifier;
+ EOEntity anEntity = aSQLExpression.entity();
+ String aKey = isQualifier.key();
+
+ StringBuffer sb = new StringBuffer();
+ String attributeString = aSQLExpression.sqlStringForAttributeNamed(aKey);
+ sb.append(aSQLExpression.formatSQLString(attributeString, attributeForPath(anEntity, aKey).readFormat()));
+ sb.append(InSubqueryQualifier.InKeyword);
+ sb.append("(");
+
+ EOEntity subEntity = anEntity.model().modelGroup().entityNamed(isQualifier.entityName());
+
+ EODatabaseContext context = EODatabaseContext.registeredDatabaseContextForModel(subEntity.model(),
+ EOObjectStoreCoordinator.defaultCoordinator());
+ EOSQLExpressionFactory factory = context.database().adaptor().expressionFactory();
+ EOSQLExpression subExpression = factory.expressionForEntity(subEntity);
+
+ // EOSQLExpression subExpression = expressionForEntity(subEntity);
+ EOFetchSpecification subFetch = new EOFetchSpecification(subEntity.name(), isQualifier.subQualifier(), null);
+ String attributePath = isQualifier.attributePath();
+ NSArray subAttributes;
+ if (attributePath != null) {
+ subAttributes = new NSArray(attributeForPath(subEntity, attributePath));
+ } else {
+ subAttributes = subEntity.primaryKeyAttributes();
+ }
+
+ StringBuffer subBuffer = new StringBuffer();
+
+ subExpression.aliasesByRelationshipPath().setObjectForKey("t1", "");
+ subExpression.setUseAliases(true);
+ subExpression.prepareSelectExpressionWithAttributes(subAttributes, false, subFetch);
+
+ subBuffer.append("SELECT ");
+ subBuffer.append(subExpression.listString());
+ subBuffer.append(" FROM ");
+ subBuffer.append(subExpression.tableListWithRootEntity(subEntity));
+
+ boolean hasWhereClause = ((subExpression.whereClauseString() != null) &&
+ (subExpression.whereClauseString().length() > 0));
+ if (hasWhereClause) {
+ subBuffer.append(" WHERE ");
+ subBuffer.append(subExpression.whereClauseString());
+ }
+ if ((subExpression.joinClauseString() != null)
+ && (subExpression.joinClauseString().length() > 0)) {
+ if (hasWhereClause) {
+ subBuffer.append(" AND ");
+ }
+ subBuffer.append(subExpression.joinClauseString());
+ }
+ String subquerySqlString = subBuffer.toString();
+ sb.append(subquerySqlString.replaceAll("t0.", "t1."));
+ sb.append(")");
+ sqlString = sb.toString();
+
+ Enumeration bindVariables = subExpression.bindVariableDictionaries().objectEnumerator();
+ while (bindVariables.hasMoreElements()) {
+ aSQLExpression.addBindVariableDictionary((NSDictionary) bindVariables.nextElement());
+ }
+
+ }
+ return sqlString;
+ }
+
+ public EOQualifier schemaBasedQualifierWithRootEntity(EOQualifier qualifier, EOEntity entity) {
+ return qualifier;
+ }
+
+ public EOQualifier qualifierMigratedFromEntityRelationshipPath(EOQualifier eoqualifier, EOEntity eoentity, String s) {
+ // the key migration is the same as for EOKeyValueQualifier
+ InSubqueryQualifier isQualifier=(InSubqueryQualifier)eoqualifier;
+ return new InSubqueryQualifier(_translateKeyAcrossRelationshipPath(isQualifier.key(), s, eoentity),
+ isQualifier.entityName(), isQualifier.attributePath(), isQualifier.subQualifier() );
+ }
+
+
+ // Protected instance methods
+ protected EOAttribute attributeForPath(EOEntity entity, String keyPath) {
+ if (keyPath != null) {
+ StringTokenizer tokenizer = new StringTokenizer(keyPath, NSKeyValueCodingAdditions.KeyPathSeparator);
+ EORelationship relationship = null;
+ while (tokenizer.hasMoreElements()) {
+ String key = tokenizer.nextToken();
+ if (tokenizer.hasMoreElements()) {
+ relationship = entity.anyRelationshipNamed(key);
+ } else {
+ return entity.anyAttributeNamed(key);
+ }
+ if (relationship != null) {
+ entity = relationship.destinationEntity();
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+ return null;
+ }
+
+ protected EOSQLExpression expressionForEntity(EOEntity entity) {
+ try {
+ Class expressionClass = ((EOAdaptor)EOAdaptor.adaptorWithModel(entity.model())).expressionClass();
+ Constructor constructor = expressionClass.getConstructor(new Class[] { EOEntity.class });
+ EOSQLExpression expression = (EOSQLExpression)constructor.newInstance(new Object[] { entity });
+ return expression;
+ } catch (Exception exception) {
+ throw new NSForwardException(exception);
+ }
+ }
+
+ }
+}
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/EROpenBasePlugIn.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/EROpenBasePlugIn.java
new file mode 100644
index 00000000000..6d37e90ef12
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/EROpenBasePlugIn.java
@@ -0,0 +1,9 @@
+package com.webobjects.jdbcadaptor;
+
+public class EROpenBasePlugIn extends _OpenBasePlugIn {
+
+ public EROpenBasePlugIn(JDBCAdaptor adaptor) {
+ super(adaptor);
+ }
+
+}
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/OpenBasePKPlugIn.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/OpenBasePKPlugIn.java
new file mode 100644
index 00000000000..b3c053c99fe
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/OpenBasePKPlugIn.java
@@ -0,0 +1,87 @@
+package com.webobjects.jdbcadaptor;
+
+import com.webobjects.eoaccess.*;
+import com.webobjects.jdbcadaptor.*;
+import com.webobjects.foundation.*;
+
+
+
+public class OpenBasePKPlugIn extends _OpenBasePlugIn{
+
+ public OpenBasePKPlugIn(JDBCAdaptor adaptor){
+ super(adaptor);
+ //System.out.println("In OpenBasePKPlugIn constructor...: ");
+ }
+
+ public NSArray newPrimaryKeys(int count, EOEntity entity, JDBCChannel adaptorChannel){
+// System.out.println("newPrimaryKeys called with: Count -> " + count + " EOEntity -> " + entity);
+ NSMutableArray result = new NSMutableArray();
+ if(count > 0){
+ // Make sure the chonnel is open
+ if ( !adaptorChannel.isOpen() ) {
+ adaptorChannel.openChannel();
+ }
+ // Get the external table name
+ String tableName = entity.externalName();
+ // Get the primary key attributes
+ NSArray primaryKeyAttributeNamesArray = entity.primaryKeyAttributes();
+
+ // If NEWID isn't appropriate, fall back to the super class's implementation
+ if (primaryKeyAttributeNamesArray.count() != 1) {
+ return super.newPrimaryKeys(count, entity, adaptorChannel);
+ }
+
+ EOAttribute column = (EOAttribute)primaryKeyAttributeNamesArray.objectAtIndex(0);
+ String attributeName = column.name(); // the EOF name
+ // Get the external primarey key name
+ String columnName = column.columnName(); // the database name
+
+
+ NSMutableDictionary row;
+ // Loop to get count new PKs
+ while(0 < count) {
+ // Create the SQL query to get a new PK
+ String newidSQL;
+
+ if (count > 100) {
+ newidSQL = "NEWID FOR " + tableName + " " + columnName + " 100 ";
+ } else {
+ newidSQL = "NEWID FOR " + tableName + " " + columnName + " " + count;
+ }
+
+ adaptorChannel.evaluateExpression(adaptorChannel.adaptorContext().adaptor().expressionFactory().expressionForString(newidSQL));
+ adaptorChannel.setAttributesToFetch(adaptorChannel.describeResults());
+ // if success do this....
+ while ( (row = adaptorChannel.fetchRow()) != null ) {
+ Object newPK = row.objectForKey(columnName.toUpperCase());
+ result.addObject(new NSDictionary(newPK, attributeName));
+ count = count - 1;
+ }
+ // otherwise, if there is an SQL error, break out of the loop
+ }
+ if (count!=0) {
+ //create a global variable to hold the unique key
+ String varName = "unique_" + tableName + "_" + columnName;
+ String newidSQL = "INCREMENT " + varName;
+
+ while(0 < count) {
+ adaptorChannel.evaluateExpression(adaptorChannel.adaptorContext().adaptor().expressionFactory().expressionForString(newidSQL));
+ adaptorChannel.setAttributesToFetch(adaptorChannel.describeResults());
+
+ if ( (row = adaptorChannel.fetchRow()) != null ) {
+ Object newPK = row.objectForKey(columnName.toUpperCase());
+ result.addObject(new NSDictionary(newPK, attributeName));
+ count = count - 1;
+ } else {
+ String createSQL = "DECLARE GLOBAL " + varName + " AS INTEGER INITIALIZE 1 SILENT ";
+ String messageSQL = "ALERT WARNING 'WO PK Generation: Initialize global variable " + varName + " with seed value at system startup.";
+ adaptorChannel.evaluateExpression(adaptorChannel.adaptorContext().adaptor().expressionFactory().expressionForString(createSQL));
+ adaptorChannel.evaluateExpression(adaptorChannel.adaptorContext().adaptor().expressionFactory().expressionForString(messageSQL));
+ }
+ // we need to do some error checking here so if it fails the second time through it does not continue to try creating the global variable.
+ }
+ }
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/_OpenBasePlugIn.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/_OpenBasePlugIn.java
new file mode 100644
index 00000000000..d62b31a7964
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/_OpenBasePlugIn.java
@@ -0,0 +1,516 @@
+//
+// OpenBasePlugIn.java
+//
+// Copyright 2004 OpenBase International Ltd. All rights reserved.
+//
+package com.webobjects.jdbcadaptor;
+
+import com.webobjects.eoaccess.EOAdaptor;
+import com.webobjects.eoaccess.EOAttribute;
+import com.webobjects.eoaccess.EOQualifierSQLGeneration;
+import com.webobjects.eoaccess.EORelationship;
+import com.webobjects.eoaccess.EOSQLExpression;
+import com.webobjects.eoaccess.EOEntity;
+import com.webobjects.eoaccess.synchronization.EOSchemaGeneration;
+import com.webobjects.eoaccess.synchronization.EOSchemaGenerationOptions;
+import com.webobjects.eoaccess.synchronization.EOSchemaSynchronization;
+import com.webobjects.eoaccess.synchronization.EOSchemaSynchronizationColumnChanges;
+import com.webobjects.eoaccess.synchronization.EOSchemaSynchronizationFactory;
+import com.webobjects.eoaccess.synchronization.EOSchemaSynchronizationModelChanges;
+import com.webobjects.eocontrol.*;
+import com.webobjects.foundation.*;
+
+import java.util.*;
+import java.sql.*;
+
+public class _OpenBasePlugIn extends JDBCPlugIn {
+
+ public static class OpenBaseExpression extends JDBCExpression {
+
+ /**
+ * Fetch spec limit ivar
+ */
+ private int _fetchLimit;
+
+ public OpenBaseExpression(EOEntity entity) {
+ super(entity);
+ _rtrimFunctionName = null;
+ }
+
+ public char sqlEscapeChar() {
+ return '\0';
+ }
+
+ public String sqlStringForCaseInsensitiveLike(String valueString, String keyString) {
+ return _NSStringUtilities.concat( keyString, " LIKE ", valueString);
+ }
+
+ public String assembleSelectStatementWithAttributes(NSArray attributes, boolean lock, EOQualifier qualifier, NSArray fetchOrder, String selectString, String columnList, String tableList, String whereClause, String joinClause, String orderByClause, String lockClause) {
+ StringBuffer statement = new StringBuffer(2048);
+ statement.append(selectString);
+ statement.append(columnList);
+ statement.append(" FROM ");
+ statement.append(tableList);
+ if(lockClause != null && lockClause.length() != 0) {
+ statement.append(" ");
+ statement.append(lockClause);
+ }
+ if(whereClause != null && whereClause.length() != 0) {
+ statement.append(" WHERE ");
+ statement.append(whereClause);
+ }
+ if(joinClause != null && joinClause.length() != 0) {
+ if(whereClause != null && whereClause.length() != 0)
+ statement.append(" AND ");
+ else
+ statement.append(" WHERE ");
+ statement.append(joinClause);
+ }
+ if(orderByClause != null && orderByClause.length() != 0) {
+ statement.append(" ORDER BY ");
+ statement.append(orderByClause);
+ }
+ if (_fetchLimit != 0) {
+ statement.append(" RETURN RESULTS ");
+ statement.append(_fetchLimit);
+ }
+ return statement.toString();
+ }
+
+ public String assembleJoinClause(String leftName, String rightName, int semantic) {
+ switch(semantic) {
+ case EORelationship.FullOuterJoin: // '\001'
+ throw new JDBCAdaptorException("OpenBase does not support full outer joins: unable to join " + leftName + " and " + rightName, null);
+
+ case EORelationship.LeftOuterJoin: // '\002'
+ return leftName + " * " + rightName;
+
+ case EORelationship.RightOuterJoin: // '\003'
+ throw new JDBCAdaptorException("OpenBase does not support right outer joins: unable to join " + leftName + " and " + rightName, null);
+ }
+ return super.assembleJoinClause(leftName, rightName, semantic);
+ }
+
+ public void prepareSelectExpressionWithAttributes(NSArray nsarray, boolean flag, EOFetchSpecification eofetchspecification) {
+ if(!eofetchspecification.promptsAfterFetchLimit()) {
+ _fetchLimit = eofetchspecification.fetchLimit();
+ }
+ super.prepareSelectExpressionWithAttributes(nsarray, flag, eofetchspecification);
+ }
+
+ // -------------------------
+ // CREATE INSERT STATEMENT
+ // -------------------------
+
+ public void prepareInsertExpressionWithRow(NSDictionary row) {
+ EOAttribute attribute;
+ Object value;
+ for(Enumeration enumeration = row.keyEnumerator(); enumeration.hasMoreElements(); this.addInsertListAttribute(attribute, value)) {
+ String attributeName = (String)enumeration.nextElement();
+ attribute = this.entity().anyAttributeNamed(attributeName);
+ if(attribute == null)
+ throw new IllegalStateException("prepareInsertExpressionWithRow: row argument contains key '" + attributeName + "' which does not have corresponding attribute on entity '" + this.entity().name() + "'");
+ value = row.objectForKey(attributeName);
+ }
+
+ String tableList = tableListWithRootEntity(_rootEntityForExpression());
+ _statement = this.assembleInsertStatementWithRow(row, tableList, new String(_listString), new String(_valueListString));
+ }
+
+ // [PJYF Nov 5 2004]
+ // This is major Hack to generate a diffenrent bind dictionary for update and insert form the one for select and delete
+ public String assembleInsertStatementWithRow(NSDictionary row, String tableList, String columnList, String valueList) {
+ if(columnList != null)
+ return _NSStringUtilities.concat("INSERT INTO ", tableList, "(", columnList, ")", " VALUES ", "(", valueList, ")");
+ else
+ return _NSStringUtilities.concat("INSERT INTO ", tableList, " VALUES ", "(", valueList, ")");
+ }
+
+ // [PJYF Nov 5 2004]
+ // This is major Hack to generate a diffenrent bind dictionary for update and insert form the one for select and delete
+ public void addInsertListAttribute(EOAttribute attribute, Object value) {
+ this.appendItemToListString(this.sqlStringForAttribute(attribute), this._listString());
+ String attributeValue = this.sqlStringForForInsertOrUpdateValue(value, attribute.name());
+ attributeValue = this.formatSQLString(attributeValue, attribute.writeFormat());
+ this.appendItemToListString(attributeValue, _valueList());
+ }
+
+ // -------------------------
+ // CREATE UPDATE STATEMENT
+ // -------------------------
+
+ public void prepareUpdateExpressionWithRow(NSDictionary row, EOQualifier qualifier) {
+ EOAttribute attribute;
+ Object value;
+ for(Enumeration enumeration = row.keyEnumerator(); enumeration.hasMoreElements(); addUpdateListAttribute(attribute, value)) {
+ String attributeName = (String)enumeration.nextElement();
+ attribute = this.entity().anyAttributeNamed(attributeName);
+ if(attribute == null)
+ throw new IllegalStateException("prepareUpdateExpressionWithRow: row argument contains key '" + attributeName + "' which does not have corresponding attribute on entity '" + this.entity().name() + "'");
+ value = row.objectForKey(attributeName);
+ }
+
+ _whereClauseString = EOQualifierSQLGeneration.Support._sqlStringForSQLExpression(qualifier, this);
+ String tableList = tableListWithRootEntity(_rootEntityForExpression());
+ _statement = assembleUpdateStatementWithRow(row, qualifier, tableList, new String(_listString), _whereClauseString);
+ }
+
+ public String assembleUpdateStatementWithRow(NSDictionary row, EOQualifier qualifier, String tableList, String updateList, String whereClause) {
+ return _NSStringUtilities.concat("UPDATE ", tableList, " SET ", updateList, " WHERE ", whereClause);
+ }
+
+ // [PJYF Nov 5 2004]
+ // This is major Hack to generate a diffenrent bind dictionary for update and insert form the one for select and delete
+ public void addUpdateListAttribute(EOAttribute attribute, Object value) {
+ String attributeName = this.sqlStringForAttribute(attribute);
+ String attributeValue = this.sqlStringForForInsertOrUpdateValue(value, attribute.name());
+ attributeValue = this.formatSQLString(attributeValue, attribute.writeFormat());
+ this.appendItemToListString(_NSStringUtilities.concat(attributeName, " = ", attributeValue), this._listString());
+ }
+
+ // [PJYF Nov 5 2004]
+ // This is major Hack to generate a diffenrent bind dictionary for update and insert form the one for select and delete
+ public String sqlStringForForInsertOrUpdateValue(Object value, String keyPath) {
+ EOAttribute attribute = this.entity()._attributeForPath(keyPath);
+ if(value != NSKeyValueCoding.NullValue && (useBindVariables() && this.shouldUseBindVariableForAttribute(attribute) || this.mustUseBindVariableForAttribute(attribute))) {
+ NSMutableDictionary bindVariableDictionary = this.bindVariableDictionaryForAttribute(attribute, value);
+ this.addBindVariableDictionary(bindVariableDictionary);
+ return (String)bindVariableDictionary.objectForKey(BindVariablePlaceHolderKey);
+ } else {
+ return this.formatValueForAttribute(value, attribute);
+ }
+ }
+
+ // [PJYF Nov 5 2004]
+ // We need to prepend the question mark with a type attribute to get the jdbc driver to do the right thing.
+ // @ (Object) T (Text) or B (Binary)
+ public NSMutableDictionary bindVariableDictionaryForInsertOrUpdateAttribute(EOAttribute attribute, Object value) {
+ String prepend = "";
+ String externalType = ( attribute.externalType() != null ? attribute.externalType().toLowerCase() : "");
+ if ( "binary".equals(externalType) ) {
+ prepend = "B";
+ } else if ( "text".equals(externalType) ) {
+ prepend = "T";
+ } else if ( "object".equals(externalType) ) {
+ prepend = "@";
+ }
+ return new NSMutableDictionary(new Object[] { attribute.name(), prepend + "?", attribute, value }, new Object[] { BindVariableNameKey, BindVariablePlaceHolderKey, BindVariableAttributeKey, BindVariableValueKey });
+ }
+
+ // [PJYF Oct 19 2004]
+ // We need to prepend the question mark with a type attribute to get the jdbc driver to do the right thing.
+ // only for B (Binary)
+ public NSMutableDictionary bindVariableDictionaryForAttribute(EOAttribute attribute, Object value) {
+ String prepend = "";
+ String externalType = ( attribute.externalType() != null ? attribute.externalType().toLowerCase() : "");
+ if ( "binary".equals(externalType) ) {
+ prepend = "B";
+ }
+ return new NSMutableDictionary(new Object[] { attribute.name(), prepend + "?", attribute, value }, new Object[] { BindVariableNameKey, BindVariablePlaceHolderKey, BindVariableAttributeKey, BindVariableValueKey });
+ }
+ }
+
+ public static class OpenBaseSynchronizationFactory extends EOSchemaSynchronizationFactory implements EOSchemaGeneration {
+
+ public OpenBaseSynchronizationFactory(EOAdaptor adaptor) {
+ super(adaptor);
+ }
+
+ public NSArray dropPrimaryKeySupportStatementsForEntityGroups(NSArray entityGroups) {
+ return new NSArray(this._expressionForString("DROP TABLE " + ((JDBCAdaptor)this.adaptor()).plugIn().primaryKeyTableName() ));
+ }
+
+ public NSArray foreignKeyConstraintStatementsForRelationship(EORelationship relationship) {
+ System.err.println("trying to run this but we're returning an empty array");
+ return NSArray.EmptyArray;
+ }
+
+ public NSArray primaryKeySupportStatementsForEntityGroups(NSArray entityGroups) {
+ String primaryKeyTableName = ((JDBCAdaptor)this.adaptor()).plugIn().primaryKeyTableName();
+ NSMutableArray primaryKeyExpressions = new NSMutableArray();
+ primaryKeyExpressions.addObject(this._expressionForString("CREATE TABLE " + primaryKeyTableName + " (NAME char(40), PK long)"));
+ primaryKeyExpressions.addObject(this._expressionForString("ALTER TABLE " + primaryKeyTableName + " ADD PRIMARY KEY (NAME)"));
+ primaryKeyExpressions.addObject(this._expressionForString("CREATE UNIQUE INDEX " + primaryKeyTableName + " NAME"));
+ return primaryKeyExpressions.immutableClone();
+ }
+
+ public String _alterPhraseCoercingColumnsWithNames(NSArray columnNames, NSDictionary updates, NSArray entityGroup, EOSchemaGenerationOptions options) {
+ return this._alterPhraseInsertingColumnsWithNames(columnNames, entityGroup, options);
+ }
+
+ public String _alterPhraseDeletingColumnsWithNames(NSArray columnNames, NSArray entityGroup, EOSchemaGenerationOptions options) {
+ StringBuffer phrase = new StringBuffer();
+ int j = columnNames.count();
+ for(int i = 0; i < j; i++) {
+ phrase.append("" + (i == 0 ? "" : this._alterPhraseJoinString()) + "remove column " + columnNames.objectAtIndex(i));
+ }
+ return phrase.toString();
+ }
+
+ public String _alterPhraseInsertionClausePrefixAtIndex(int columnIndex) {
+ return "add column";
+ }
+
+ public String _alterPhraseJoinString() {
+ return " ";
+ }
+
+ /*
+ * [PJYF Oct 19 2004]
+ * This is a bad hack to get WO to create indes for external keys.
+ * We use the primary key constrain generation to create our indexes.
+ * But we need to be carefull not to overwrite previous constrains
+ *
+ */
+ protected boolean isSinglePrimaryKeyAttribute(EOAttribute attribute) {
+ if (attribute == null) return false;
+ EOEntity entity = (EOEntity)attribute.entity();
+ if ( (entity == null) || entity.isAbstractEntity() || (entity.externalName() == null) ) return false;
+ NSArray primaryKeyAttributes = entity.primaryKeyAttributes();
+ if (primaryKeyAttributes.count() != 1) return false;
+ return attribute.name().equals(((EOAttribute)primaryKeyAttributes.lastObject()).name());
+ }
+
+ public NSArray primaryKeyConstraintStatementsForEntityGroup(NSArray entityGroup) {
+ if(entityGroup == null) return NSArray.EmptyArray;
+
+ NSMutableDictionary columnNameDictionary = new NSMutableDictionary();
+ NSMutableArray primaryKeyConstraintExpressions = new NSMutableArray();
+
+ for (Enumeration enumerator = entityGroup.objectEnumerator(); enumerator.hasMoreElements(); ) {
+ EOEntity entity = (EOEntity)enumerator.nextElement();
+ String tableName = entity.externalName();
+ NSArray primaryKeyAttributes = entity.primaryKeyAttributes();
+ boolean singlePrimaryKey = primaryKeyAttributes.count() == 1;
+ if( (tableName != null) && ( ! "".equals(tableName) ) && (primaryKeyAttributes.count() > 0) ) {
+ NSArray expressions = super.primaryKeyConstraintStatementsForEntityGroup(entityGroup);
+ if( (expressions != null) && (expressions.count() > 0) ) primaryKeyConstraintExpressions.addObjectsFromArray(expressions);
+ for (Enumeration attributeEnumerator = primaryKeyAttributes.objectEnumerator(); attributeEnumerator.hasMoreElements(); ) {
+ String columnName = ((EOAttribute)attributeEnumerator.nextElement()).columnName();
+ columnNameDictionary.setObjectForKey(columnName, entity.externalName() + "." + columnName);
+ EOSQLExpression expression = this._expressionForString("create " + ( singlePrimaryKey ? "unique" : "" ) + " index " + entity.externalName() + " " + columnName);
+ if(expression != null) primaryKeyConstraintExpressions.addObject( expression );
+ }
+ }
+ }
+
+ for (Enumeration enumerator = entityGroup.objectEnumerator(); enumerator.hasMoreElements(); ) {
+ EOEntity entity = (EOEntity)enumerator.nextElement();
+ String tableName = entity.externalName();
+ if( (tableName != null) && ( ! "".equals(tableName) ) ) {
+ for (Enumeration relationshipEnumerator = entity.relationships().objectEnumerator(); relationshipEnumerator.hasMoreElements(); ) {
+ EORelationship relationship = (EORelationship)relationshipEnumerator.nextElement();
+ if( ! relationship.isFlattened() ) {
+ NSArray destinationAttributes = relationship.destinationAttributes();
+
+ // First exclude all the destination entity primary keys
+ for (Enumeration attributeEnumerator = relationship.destinationEntity().primaryKeyAttributes().objectEnumerator(); attributeEnumerator.hasMoreElements(); ) {
+ EOAttribute attribute = (EOAttribute)attributeEnumerator.nextElement();
+ columnNameDictionary.setObjectForKey(attribute.columnName(), relationship.destinationEntity().externalName() + "." + attribute.columnName());
+ }
+ // Then deal with our end of things
+ for (Enumeration attributeEnumerator = relationship.sourceAttributes().objectEnumerator(); attributeEnumerator.hasMoreElements(); ) {
+ EOAttribute attribute = (EOAttribute)attributeEnumerator.nextElement();
+ if( (! this.isSinglePrimaryKeyAttribute(attribute)) && (columnNameDictionary.objectForKey(tableName + "." + attribute.columnName()) != null) ) {
+ columnNameDictionary.setObjectForKey(attribute.columnName(), tableName + "." + attribute.columnName());
+ EOSQLExpression expression = this._expressionForString("create index " + tableName + " " + attribute.columnName());
+ if(expression != null) primaryKeyConstraintExpressions.addObject( expression );
+ }
+ }
+ // Then deal with the other side
+ if(entity.model() == relationship.destinationEntity().model()) {
+ for (Enumeration attributeEnumerator = relationship.destinationAttributes().objectEnumerator(); attributeEnumerator.hasMoreElements(); ) {
+ EOAttribute attribute = (EOAttribute)attributeEnumerator.nextElement();
+ String destinationTableName = relationship.destinationEntity().externalName();
+ if( (destinationTableName != null) && ( ! "".equals(destinationTableName) ) ) {
+ if( (! this.isSinglePrimaryKeyAttribute(attribute)) && (columnNameDictionary.objectForKey(destinationTableName + "." + attribute.columnName()) != null) ) {
+ columnNameDictionary.setObjectForKey(attribute.columnName(), destinationTableName + "." + attribute.columnName());
+ EOSQLExpression expression = this._expressionForString("create index " + destinationTableName + " " + attribute.columnName());
+ if(expression != null) primaryKeyConstraintExpressions.addObject( expression );
+ }
+ if( (! relationship.isCompound() ) && (relationship.sourceAttributes().count() == 1) && (relationship.destinationAttributes().count() == 1) ) {
+ String semantics;
+ switch(relationship.joinSemantic()) {
+ case EORelationship.FullOuterJoin: // '\001'
+ case EORelationship.LeftOuterJoin: // '\002'
+ case EORelationship.RightOuterJoin: // '\003'
+ semantics = "*";
+ break;
+
+ default:
+ semantics = "=";
+ break;
+ }
+ String sourceColumn = ((EOAttribute)relationship.sourceAttributes().objectAtIndex(0)).columnName();
+ String destinationColumn = ((EOAttribute)relationship.destinationAttributes().objectAtIndex(0)).columnName();
+ EOSQLExpression expression = this._expressionForString("delete from _SYS_RELATIONSHIP where relationshipName = '" + relationship.name() + "' and source_table = '" + tableName + "' ");
+ if(expression != null) primaryKeyConstraintExpressions.addObject( expression );
+ expression = this._expressionForString("insert into _SYS_RELATIONSHIP (relationshipName, source_table, source_column, dest_table, dest_column, operator, one_to_many) values ('" + relationship.name() + "','" + tableName + "','" + sourceColumn + "','" + destinationTableName + "','" + destinationColumn + "','" + semantics + "'," + (relationship.isToMany() ? 1 : 0) + ")");
+ if(expression != null) primaryKeyConstraintExpressions.addObject( expression );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return primaryKeyConstraintExpressions.immutableClone();
+ }
+
+ public boolean isColumnTypeEquivalentToColumnType(EOSchemaSynchronization.ColumnTypes candidate, EOSchemaSynchronization.ColumnTypes columnType, EOSchemaGenerationOptions options) {
+ return candidate.name().equals(columnType.name()) && ( candidate.width() == columnType.width() );
+ }
+
+ public NSArray statementsToDropForeignKeyConstraintsOnEntityGroups(NSArray entityGroups, NSDictionary changes, NSDictionary options) {
+ return NSArray.EmptyArray;
+ }
+
+ public NSArray statementsToDropPrimaryKeyConstraintsOnEntityGroups(NSArray entityGroups, EOSchemaSynchronizationModelChanges changes, EOSchemaGenerationOptions options) {
+ if(entityGroups == null) return NSArray.EmptyArray;
+ if(changes == null) changes = newChanges();
+
+ NSMutableArray expressions = new NSMutableArray();
+ for (Enumeration enumerator = entityGroups.objectEnumerator(); enumerator.hasMoreElements(); ) {
+ NSArray entities = (NSArray)enumerator.nextElement();
+ EOEntity _last = (EOEntity)entities.lastObject(); //only need entity to get the table name for the group
+ String nameInObjectStore = _nameInObjectStoreForEntityGroupWithChangeDictionary(entities, changes.changesForTableNamed(_last.externalName()));
+ if ( (nameInObjectStore != null) && ( ! "".equals(nameInObjectStore) ) ) {
+ expressions.addObject(this._expressionForString("delete from _SYS_RELATIONSHIP where source_table = '" + nameInObjectStore + "' or dest_table = '" + nameInObjectStore + "'"));
+ }
+ }
+ return expressions.immutableClone();
+ }
+
+ public NSArray statementsToImplementPrimaryKeyConstraintsOnEntityGroups(NSArray entityGroups, EOSchemaSynchronizationModelChanges changes, EOSchemaGenerationOptions options) {
+ NSArray primaryKeyExpressions = this.primaryKeyConstraintStatementsForEntityGroups(entityGroups);
+ NSMutableArray createStatements = new NSMutableArray();
+ NSMutableArray otherStatements = new NSMutableArray();
+ for (Enumeration enumerator = primaryKeyExpressions.objectEnumerator(); enumerator.hasMoreElements(); ) {
+ EOSQLExpression expression = (EOSQLExpression)enumerator.nextElement();
+ String statement = expression.statement();
+ if(statement.startsWith("create")) {
+ createStatements.addObject(expression);
+ } else if( ! statement.startsWith("delete from _SYS_RELATIONSHIP") ) {
+ otherStatements.addObject(expression);
+ }
+ }
+ return createStatements.arrayByAddingObjectsFromArray(otherStatements);
+ }
+
+ public NSArray statementsToModifyColumnNullRule(String columnName, String tableName, boolean allowsNull, EOSchemaGenerationOptions options) {
+ return new NSArray(this._expressionForString("alter table " + tableName + " add column " + columnName + " set " + (allowsNull ? "null" : "not null")));
+ }
+
+ public NSArray statementsToRenameColumnNamed(String columnName, String tableName, String newName, EOSchemaGenerationOptions options) {
+ return new NSArray(this._expressionForString("alter table " + tableName + " rename " + columnName + " to " + newName));
+ }
+
+ public NSArray statementsToRenameTableNamed(String tableName, String newName, EOSchemaGenerationOptions options) {
+ return new NSArray(this._expressionForString("rename " + tableName + " " + newName));
+ }
+
+ public boolean supportsDirectColumnCoercion() {
+ return true;
+ }
+
+ public boolean supportsDirectColumnDeletion() {
+ return true;
+ }
+
+ public boolean supportsDirectColumnInsertion() {
+ return true;
+ }
+
+ public boolean supportsDirectColumnNullRuleModification() {
+ return true;
+ }
+
+ public boolean supportsDirectColumnRenaming() {
+ return true;
+ }
+
+ public boolean supportsSchemaSynchronization() {
+ return true;
+ }
+
+ public NSArray primaryKeySupportStatementsForEntityGroup(NSArray entityGroup) {
+ return NSArray.EmptyArray;
+ }
+
+ public NSArray dropPrimaryKeySupportStatementsForEntityGroup(NSArray entityGroup) {
+ return NSArray.EmptyArray;
+ }
+
+ public EOSchemaSynchronizationColumnChanges objectStoreChangesFromAttributeToAttribute(EOAttribute schemaAttribute, EOAttribute modelAttribute) {
+ EOSchemaSynchronizationColumnChanges objectStoreChanges = super.objectStoreChangesFromAttributeToAttribute(schemaAttribute, modelAttribute);
+ if(objectStoreChanges.valueForKey("precision") != null || objectStoreChanges.valueForKey("scale") != null) {
+ objectStoreChanges.clearPrecision();
+ objectStoreChanges.clearScale();
+ }
+ if( ! modelAttribute.externalType().equals(schemaAttribute.externalType()) ) {
+ if(modelAttribute.externalType().equals("varchar") && schemaAttribute.externalType().equals("char"))
+ objectStoreChanges.clearExternalType();
+ } else {
+ if(schemaAttribute.externalType().equals("object") && objectStoreChanges.valueForKey("width") != null)
+ objectStoreChanges.clearWidth();
+ }
+ if((modelAttribute.externalType().equals("char") || modelAttribute.externalType().equals("varchar")) && modelAttribute.width() == 1024 && schemaAttribute.width() == 1023)
+ objectStoreChanges.clearWidth();
+
+ return objectStoreChanges;
+ }
+
+ public String schemaCreationScriptForEntities(NSArray arg0, NSDictionary arg1) {
+ System.err.println("calling OpenBaseSynchronizationFactory.schemaCreationScriptForEntities");
+ return null;
+ }
+
+ public NSArray schemaCreationStatementsForEntities(NSArray arg0, NSDictionary arg1) {
+ System.err.println("calling OpenBaseSynchronizationFactory.schemaCreationStatementsForEntities");
+ return null;
+ }
+ }
+
+ public _OpenBasePlugIn(JDBCAdaptor adaptor) {
+ super(adaptor);
+ }
+
+ public String connectionURL() {
+ return super.connectionURL() + ":wo";
+ }
+
+ public String defaultDriverName() {
+ return DriverClassName;
+ }
+
+ public String databaseProductName() {
+ return DriverProductName;
+ }
+
+ public Class defaultExpressionClass() {
+ return _OpenBasePlugIn.OpenBaseExpression.class;
+ }
+
+ public EOSchemaSynchronizationFactory createSchemaSynchronizationFactory() {
+ return new OpenBaseSynchronizationFactory(this.adaptor());
+ }
+
+ public boolean isPseudoColumnName(String columnName) {
+ return columnName.equalsIgnoreCase("_timestamp") || columnName.equalsIgnoreCase("_version") || super.isPseudoColumnName(columnName);
+ }
+
+ public NSDictionary jdbcInfo() {
+ NSDictionary jdbcInfo = super.jdbcInfo();
+ JDBCContext jdbccontext = this.adaptor()._cachedAdaptorContext();
+ try {
+ jdbccontext.connection().commit();
+ } catch(SQLException exception) {
+ if(NSLog.debugLoggingAllowedForLevelAndGroups(3, 0x0L)) NSLog.debug.appendln(exception);
+ }
+ return jdbcInfo;
+ }
+
+ private static final String DriverClassName = "com.openbase.jdbc.ObDriver";
+ private static final String DriverProductName = "OpenBase";
+}
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.properties b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.properties
new file mode 100644
index 00000000000..476057a2a59
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.properties
@@ -0,0 +1,10 @@
+classes.dir = bin
+project.name=OpenBaseWOPKPlugIn
+project.name.lowercase=openbasewopkplugin
+principalClass =
+customInfoPListContent =
+eoAdaptorClassName =
+cfBundleVersion =
+cfBundleShortVersion =
+cfBundleID = org.mywoapp
+javaVersion = 1.5+
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.xml b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.xml
new file mode 100644
index 00000000000..03c57bb9c81
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.exclude.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.exclude.patternset
new file mode 100644
index 00000000000..56fb545fa67
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.exclude.patternset
@@ -0,0 +1 @@
+build.properties
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.include.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.include.patternset
new file mode 100644
index 00000000000..3179091db39
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.include.patternset
@@ -0,0 +1,2 @@
+**/*.class
+*.properties
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.exclude.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.exclude.patternset
new file mode 100644
index 00000000000..905050dfb73
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.exclude.patternset
@@ -0,0 +1,3 @@
+**/*.eomodeld~/
+**/*.woa/**
+**/*.framework/**
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.include.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.include.patternset
new file mode 100644
index 00000000000..611978755e2
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.include.patternset
@@ -0,0 +1,3 @@
+Components/**/*.wo/**/*
+Components/**/*.api
+Resources/**/*
\ No newline at end of file
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.exclude.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.exclude.patternset
new file mode 100644
index 00000000000..9435a512320
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.exclude.patternset
@@ -0,0 +1,3 @@
+**/*.woa/**
+**/*.framework/**
+**/*.eomodeld~/**
diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.include.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.include.patternset
new file mode 100644
index 00000000000..234cdc88bb7
--- /dev/null
+++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.include.patternset
@@ -0,0 +1 @@
+WebServerResources/**/*