You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2008/05/13 16:47:55 UTC
svn commit: r655887 - in /cayenne/main/trunk: docs/doc/src/main/resources/
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/
framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/
Author: aadamchik
Date: Tue May 13 07:47:54 2008
New Revision: 655887
URL: http://svn.apache.org/viewvc?rev=655887&view=rev
Log:
CAY-1046 Make PK metadata available via Obj* API.
Added:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/SyntheticPKObjAttribute.java
Modified:
cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ClientObjEntity.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjAttribute.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/ObjEntityTest.java
Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=655887&r1=655886&r2=655887&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Tue May 13 07:47:54 2008
@@ -38,6 +38,7 @@
CAY-1033 remove completed merge tokens from view in cayenne modeler
CAY-1035 Replace QueryMetadata String cache policies with an enum
CAY-1038 Upgrade to Ashwood 2.0
+CAY-1046 Make PK metadata available via Obj* API.
CAY-1048 Deprecate but preserve functionality of QueryMetadata.isRefreshingObjects()
CAY-1049 Refactor QueryAssembler/SelectTranslator
CAY-1050 MySQLSniffer should configure created adapter to use MySQL default engine for tables
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ClientObjEntity.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ClientObjEntity.java?rev=655887&r1=655886&r2=655887&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ClientObjEntity.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ClientObjEntity.java Tue May 13 07:47:54 2008
@@ -19,34 +19,41 @@
package org.apache.cayenne.map;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
- * A client version of ObjEntity that delegates some of its method calls to
- * its corresponding server entity.
- *
+ * A client version of ObjEntity that overrides server entity algorithms for accessing
+ * some pieces of information
+ *
* @since 3.0
* @author Kevin Menard
*/
-public class ClientObjEntity extends ObjEntity {
+class ClientObjEntity extends ObjEntity {
- private Collection<String> primaryKeyNames;
+ private Collection<ObjAttribute> primaryKeys;
- public ClientObjEntity() {
- super();
- }
-
- public ClientObjEntity(final String name) {
+ ClientObjEntity(String name) {
super(name);
+ this.primaryKeys = Collections.<ObjAttribute> emptyList();
}
@Override
public Collection<String> getPrimaryKeyNames() {
- return Collections.unmodifiableCollection(primaryKeyNames);
+ Collection<String> names = new ArrayList<String>(primaryKeys.size());
+ for (ObjAttribute attribute : primaryKeys) {
+ names.add(attribute.getName());
+ }
+ return Collections.unmodifiableCollection(names);
+ }
+
+ @Override
+ public Collection<ObjAttribute> getPrimaryKeys() {
+ return Collections.unmodifiableCollection(primaryKeys);
}
- public void setPrimaryKeyNames(final Collection<String> primaryKeyNames) {
- this.primaryKeyNames = primaryKeyNames;
+ void setPrimaryKeys(Collection<ObjAttribute> primaryKeys) {
+ this.primaryKeys = primaryKeys;
}
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjAttribute.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjAttribute.java?rev=655887&r1=655886&r2=655887&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjAttribute.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjAttribute.java Tue May 13 07:47:54 2008
@@ -258,6 +258,12 @@
DbAttribute dbAttribute = getDbAttribute();
if (dbAttribute != null) {
+
+ // expose PK attribute names - the client may need those to build ObjectIds
+ if (dbAttribute.isPrimaryKey()) {
+ attribute.setDbAttributePath(dbAttribute.getName());
+ }
+
attribute.setMandatory(dbAttribute.isMandatory());
attribute.setMaxLength(dbAttribute.getMaxLength());
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java?rev=655887&r1=655886&r2=655887&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java Tue May 13 07:47:54 2008
@@ -30,6 +30,7 @@
import java.util.TreeMap;
import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.dba.TypesMapping;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionException;
import org.apache.cayenne.exp.ExpressionFactory;
@@ -38,6 +39,7 @@
import org.apache.cayenne.map.event.ObjEntityListener;
import org.apache.cayenne.map.event.RelationshipEvent;
import org.apache.cayenne.util.CayenneMapEntry;
+import org.apache.cayenne.util.NameConverter;
import org.apache.cayenne.util.Util;
import org.apache.cayenne.util.XMLEncoder;
import org.apache.commons.collections.Transformer;
@@ -189,17 +191,32 @@
entity.setClassName(getClientClassName());
entity.setSuperClassName(getClientSuperClassName());
entity.setSuperEntityName(getSuperEntityName());
- entity.setPrimaryKeyNames(getPrimaryKeyNames());
// TODO: should we also copy lock type?
- // copy attributes
- for (Attribute attribute : getDeclaredAttributes()) {
- entity.addAttribute(((ObjAttribute) attribute).getClientAttribute());
+ Collection<ObjAttribute> primaryKeys = getMutablePrimaryKeys();
+ Collection<ObjAttribute> clientPK = new ArrayList<ObjAttribute>(primaryKeys
+ .size());
+
+ for (ObjAttribute attribute : getDeclaredAttributes()) {
+ ObjAttribute clientAttribute = attribute.getClientAttribute();
+ entity.addAttribute(clientAttribute);
+
+ if (primaryKeys.remove(attribute)) {
+ clientPK.add(clientAttribute);
+ }
+ }
+
+ // after all meaningful pks got removed, here we only have synthetic pks left...
+ for (ObjAttribute attribute : primaryKeys) {
+ ObjAttribute clientAttribute = attribute.getClientAttribute();
+ clientPK.add(clientAttribute);
}
+ entity.setPrimaryKeys(clientPK);
+
// copy relationships; skip runtime generated relationships
- for (Relationship relationship : getDeclaredRelationships()) {
+ for (ObjRelationship relationship : getDeclaredRelationships()) {
if (relationship.isRuntime()) {
continue;
}
@@ -211,8 +228,7 @@
continue;
}
- entity.addRelationship(((ObjRelationship) relationship)
- .getClientRelationship());
+ entity.addRelationship(relationship.getClientRelationship());
}
// TODO: andrus 2/5/2007 - copy embeddables
@@ -571,6 +587,46 @@
}
/**
+ * Returns an unmodifiable collection of ObjAttributes representing the primary key of
+ * the table described by this DbEntity. Note that since PK is very often not an
+ * object property, the returned collection may contain "synthetic" ObjAttributes that
+ * are created on the fly and are not a part of ObjEntity and will not be a part of
+ * entity.getAttributes(). Real meaningful PK attributes
+ *
+ * @since 3.0
+ */
+ public Collection<ObjAttribute> getPrimaryKeys() {
+ return Collections.unmodifiableCollection(getMutablePrimaryKeys());
+ }
+
+ private Collection<ObjAttribute> getMutablePrimaryKeys() {
+ if (getDbEntity() == null) {
+ throw new CayenneRuntimeException("No DbEntity for ObjEntity: " + getName());
+ }
+
+ Collection<DbAttribute> pkAttributes = getDbEntity().getPrimaryKeys();
+ Collection<ObjAttribute> attributes = new ArrayList<ObjAttribute>(pkAttributes
+ .size());
+
+ for (DbAttribute pk : pkAttributes) {
+ ObjAttribute attribute = getAttributeForDbAttribute(pk);
+
+ // create synthetic attribute
+ if (attribute == null) {
+ attribute = new SyntheticPKObjAttribute(NameConverter.underscoredToJava(
+ pk.getName(),
+ false));
+ attribute.setDbAttributePath(pk.getName());
+ attribute.setType(TypesMapping.getJavaBySqlType(pk.getType()));
+ }
+
+ attributes.add(attribute);
+ }
+
+ return attributes;
+ }
+
+ /**
* Returns a named attribute that either belongs to this ObjEntity or is inherited.
* Returns null if no matching attribute is found.
*/
@@ -736,19 +792,22 @@
return null;
}
+ /**
+ * @since 3.0
+ */
public Collection<String> getPrimaryKeyNames() {
if (getDbEntity() == null) {
throw new CayenneRuntimeException("No DbEntity for ObjEntity: " + getName());
}
Collection<DbAttribute> pkAttributes = getDbEntity().getPrimaryKeys();
- Collection<String> ret = new ArrayList<String>(pkAttributes.size());
+ Collection<String> names = new ArrayList<String>(pkAttributes.size());
for (DbAttribute pk : pkAttributes) {
- ret.add(pk.getName());
+ names.add(pk.getName());
}
- return Collections.unmodifiableCollection(ret);
+ return Collections.unmodifiableCollection(names);
}
/**
@@ -829,7 +888,7 @@
return (superEntity != null) ? superEntity.isSubentityOf(entity) : false;
}
-
+
/**
* @since 3.0
*/
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/SyntheticPKObjAttribute.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/SyntheticPKObjAttribute.java?rev=655887&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/SyntheticPKObjAttribute.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/SyntheticPKObjAttribute.java Tue May 13 07:47:54 2008
@@ -0,0 +1,52 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.map;
+
+
+/**
+ * A "synthetic" server-side ObjAttribute used to describe unmapped PK>.
+ *
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class SyntheticPKObjAttribute extends ObjAttribute {
+
+ SyntheticPKObjAttribute(String name) {
+ super(name);
+ }
+
+ @Override
+ public ObjAttribute getClientAttribute() {
+ ClientObjAttribute attribute = new ClientObjAttribute(getName());
+ attribute.setType(getType());
+
+ // unconditionally expose DbAttribute path and configure as mandatory.
+ attribute.setDbAttributePath(dbAttributePath);
+ attribute.setMandatory(true);
+
+ DbAttribute dbAttribute = getDbAttribute();
+ if (dbAttribute != null) {
+ attribute.setMaxLength(dbAttribute.getMaxLength());
+ }
+
+ // TODO: will likely need "userForLocking" property as well.
+
+ return attribute;
+ }
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/ObjEntityTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/ObjEntityTest.java?rev=655887&r1=655886&r2=655887&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/ObjEntityTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/map/ObjEntityTest.java Tue May 13 07:47:54 2008
@@ -19,6 +19,7 @@
package org.apache.cayenne.map;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -32,6 +33,44 @@
public class ObjEntityTest extends CayenneCase {
+ public void testGetPrimaryKeys() {
+ ObjEntity artistE = getObjEntity("Artist");
+ Collection<ObjAttribute> pks = artistE.getPrimaryKeys();
+ assertEquals(1, pks.size());
+
+ ObjAttribute pk = pks.iterator().next();
+ assertEquals("java.lang.Long", pk.getType());
+ assertEquals("ARTIST_ID", pk.getDbAttributePath());
+ assertEquals("artistId", pk.getName());
+ assertNull(pk.getEntity());
+ assertFalse(artistE.getAttributes().contains(pk));
+
+ ObjEntity clientArtistE = artistE.getClientEntity();
+ Collection<ObjAttribute> clientpks = clientArtistE.getPrimaryKeys();
+ assertEquals(1, clientpks.size());
+ ObjAttribute clientPk = clientpks.iterator().next();
+ assertEquals("java.lang.Long", clientPk.getType());
+ assertEquals("ARTIST_ID", clientPk.getDbAttributePath());
+ assertEquals("artistId", clientPk.getName());
+ assertNull(clientPk.getEntity());
+ assertFalse(clientArtistE.getAttributes().contains(pk));
+
+ ObjEntity meaningfulPKE = getObjEntity("MeaningfulPKTest1");
+ Collection<ObjAttribute> mpks = meaningfulPKE.getPrimaryKeys();
+ assertEquals(1, mpks.size());
+
+ ObjAttribute mpk = mpks.iterator().next();
+ assertTrue(meaningfulPKE.getAttributes().contains(mpk));
+
+ ObjEntity clientMeaningfulPKE = meaningfulPKE.getClientEntity();
+ Collection<ObjAttribute> clientmpks = clientMeaningfulPKE.getPrimaryKeys();
+ assertEquals(1, clientmpks.size());
+
+ ObjAttribute clientmpk = clientmpks.iterator().next();
+ assertEquals("java.lang.Integer", clientmpk.getType());
+ assertTrue(clientMeaningfulPKE.getAttributes().contains(clientmpk));
+ }
+
/**
* @deprecated since 3.0 as the method being tested is deprecated.
*/