Author: adamw
Date: 2008-09-22 11:33:44 -0400 (Mon, 22 Sep 2008)
New Revision: 160
Removed:
trunk/src/main/org/jboss/envers/entities/mapper/relation/AbstractOneToManyMapper.java
Modified:
trunk/src/main/org/jboss/envers/configuration/metadata/CollectionMetadataGenerator.java
trunk/src/main/org/jboss/envers/configuration/metadata/VersionsMetadataGenerator.java
trunk/src/main/org/jboss/envers/entities/mapper/relation/OneToManyAttachedMapper.java
Log:
ENVERS-44: restructuring the collections mapper, making it statefull
Modified:
trunk/src/main/org/jboss/envers/configuration/metadata/CollectionMetadataGenerator.java
===================================================================
---
trunk/src/main/org/jboss/envers/configuration/metadata/CollectionMetadataGenerator.java 2008-09-22
11:26:24 UTC (rev 159)
+++
trunk/src/main/org/jboss/envers/configuration/metadata/CollectionMetadataGenerator.java 2008-09-22
15:33:44 UTC (rev 160)
@@ -28,113 +28,104 @@
import java.lang.annotation.Annotation;
/**
- * Generates metadata for collection-valued properties.
+ * Generates metadata for a collection-valued property.
* @author Adam Warski (adam at warski dot org)
*/
public final class CollectionMetadataGenerator {
private final VersionsMetadataGenerator mainGenerator;
+ private final String propertyName;
+ private final Collection propertyValue;
+ private final CompositeMapperBuilder currentMapper;
+ private final String referencingEntityName;
+ private final EntityXmlMappingData xmlMappingData;
+ private final VersionsJoinTable joinTable;
- CollectionMetadataGenerator(VersionsMetadataGenerator versionsMetadataGenerator) {
- mainGenerator = versionsMetadataGenerator;
- }
+ private final EntityConfiguration referencingEntityConfiguration;
+ /**
+ * Null if this collection isn't a relation to another entity.
+ */
+ private final String referencedEntityName;
- void addCollection(String name, Collection value, CompositeMapperBuilder
currentMapper,
- String entityName, EntityXmlMappingData xmlMappingData,
- VersionsJoinTable joinTable) {
- Type type = value.getType();
+ /**
+ * @param mainGenerator Main generator, giving access to configuration and the basic
mapper.
+ * @param propertyName Name of the property that references the collection in the
referencing entity.
+ * @param propertyValue Value of the collection, as mapped by Hibernate.
+ * @param currentMapper Mapper, to which the appropriate {@link
org.jboss.envers.entities.mapper.PropertyMapper}
+ * will be added.
+ * @param referencingEntityName Name of the entity that owns this collection.
+ * @param xmlMappingData In case this collection requires a middle table, additional
mapping documents will
+ * be created using this object.
+ * @param joinTable User data for the middle (join) table.
<code>null</code> if the user didn't specify it.
+ */
+ public CollectionMetadataGenerator(VersionsMetadataGenerator mainGenerator, String
propertyName,
+ Collection propertyValue, CompositeMapperBuilder
currentMapper,
+ String referencingEntityName, EntityXmlMappingData
xmlMappingData,
+ VersionsJoinTable joinTable) {
+ this.mainGenerator = mainGenerator;
+ this.propertyName = propertyName;
+ this.propertyValue = propertyValue;
+ this.currentMapper = currentMapper;
+ this.referencingEntityName = referencingEntityName;
+ this.xmlMappingData = xmlMappingData;
+ this.joinTable = joinTable == null ? getDefaultVersionsJoinTable() : joinTable;
- if ((type instanceof BagType || type instanceof SetType) &&
- (value.getElement() instanceof OneToMany) && (value.isInverse()))
{
- addOneToManyAttached(name, value, currentMapper, entityName);
- } else {
- addWithMiddleTable(name, value, currentMapper, entityName, xmlMappingData,
- joinTable == null ? getDefaultVersionsJoinTable() : joinTable);
+ referencingEntityConfiguration =
mainGenerator.getEntitiesConfigurations().get(referencingEntityName);
+ if (referencingEntityConfiguration == null) {
+ throw new MappingException("Unable to read versioning configuration for
" + referencingEntityName + "!");
}
- }
- private VersionsJoinTable getDefaultVersionsJoinTable() {
- return new VersionsJoinTable() {
- public String name() { return ""; }
- public String schema() { return ""; }
- public String catalog() { return ""; }
- public JoinColumn[] inverseJoinColumns() { return new JoinColumn[0]; }
- public Class<? extends Annotation> annotationType() { return
this.getClass(); }
- };
+ referencedEntityName = getReferencedEntityName(propertyValue.getElement());
}
- @SuppressWarnings({"unchecked"})
- private String getMappedBy(Collection collectionValue) {
- Iterator<Property> assocClassProps =
- ((OneToMany)
collectionValue.getElement()).getAssociatedClass().getPropertyIterator();
-
- while (assocClassProps.hasNext()) {
- Property property = assocClassProps.next();
-
- if (Tools.iteratorsContentEqual(property.getValue().getColumnIterator(),
- collectionValue.getKey().getColumnIterator())) {
- return property.getName();
- }
+ private String getReferencedEntityName(Value value) {
+ if (value instanceof ToOne) {
+ return ((ToOne) value).getReferencedEntityName();
+ } else if (value instanceof OneToMany) {
+ return ((OneToMany) value).getReferencedEntityName();
+ } else {
+ return null;
}
-
- return null;
}
- @SuppressWarnings({"unchecked"})
- private String getMappedBy(Table collectionTable, PersistentClass referencedClass) {
- Iterator<Property> properties = referencedClass.getPropertyIterator();
- while (properties.hasNext()) {
- Property property = properties.next();
- if (property.getValue() instanceof Collection) {
- // The equality is intentional. We want to find a collection property
with the same collection table.
- //noinspection ObjectEquality
- if (((Collection) property.getValue()).getCollectionTable() ==
collectionTable) {
- return property.getName();
- }
- }
+ void addCollection() {
+ Type type = propertyValue.getType();
+
+ if ((type instanceof BagType || type instanceof SetType) &&
+ (propertyValue.getElement() instanceof OneToMany) &&
(propertyValue.isInverse())) {
+ // A one-to-many relation mapped using @ManyToOne and
@OneToMany(mappedBy="...")
+ addOneToManyAttached();
+ } else {
+ // All other kinds of relations require a middle (join) table).
+ addWithMiddleTable();
}
-
- return null;
}
@SuppressWarnings({"unchecked"})
- private void addOneToManyAttached(String name, Collection value,
CompositeMapperBuilder mapper, String entityName) {
- String owningReferencePropertyName = getMappedBy(value);
- if (owningReferencePropertyName == null) {
- throw new MappingException("Unable to read the mapped by attribute for
" + name + " in " + entityName + "!");
- }
+ private void addOneToManyAttached() {
+ String owningReferencePropertyName = getMappedBy(propertyValue);
- EntityConfiguration configuration =
mainGenerator.getEntitiesConfigurations().get(entityName);
- if (configuration == null) {
- throw new MappingException("Unable to read versioning configuration for
" + entityName + "!");
- }
-
- IdMappingData referencingIdMapping = configuration.getIdMappingData();
-
- String owningEntityName = ((OneToMany)
value.getElement()).getReferencedEntityName();
+ IdMappingData referencingIdMapping =
referencingEntityConfiguration.getIdMappingData();
String lastPropertyPrefix = owningReferencePropertyName + "_";
// Generating the id mapper for the relation
IdMapper ownedIdMapper =
referencingIdMapping.getIdMapper().prefixMappedProperties(lastPropertyPrefix);
// Storing information about this relation
-
mainGenerator.getEntitiesConfigurations().get(entityName).addToManyNotOwningRelation(name,
owningReferencePropertyName,
- owningEntityName, ownedIdMapper);
+ referencingEntityConfiguration.addToManyNotOwningRelation(propertyName,
owningReferencePropertyName,
+ referencedEntityName, ownedIdMapper);
// Adding mapper for the id
- mapper.addComposite(name, new
OneToManyAttachedMapper(owningReferencePropertyName, owningEntityName,
- name));
+ currentMapper.addComposite(propertyName, new
OneToManyAttachedMapper(referencedEntityName, propertyName,
+ owningReferencePropertyName));
}
- private String getReferencedEntityName(Value value) {
- if (value instanceof ToOne) {
- return ((ToOne) value).getReferencedEntityName();
- } else if (value instanceof OneToMany) {
- return ((OneToMany) value).getReferencedEntityName();
- } else {
- return null;
- }
- }
-
+ /**
+ * Adds mapping of the id of a related entity to the given xml mapping, prefixing the
id with the given prefix.
+ * @param xmlMapping Mapping, to which to add the xml.
+ * @param prefix Prefix for the names of properties which will be prepended to
properties that form the id.
+ * @param columnNameIterator Iterator over the column names that will be used for
properties that form the id.
+ * @param relatedIdMapping Id mapping data of the related entity.
+ */
@SuppressWarnings({"unchecked"})
private void addRelatedToXmlMapping(Element xmlMapping, String prefix,
MetadataTools.ColumnNameIterator
columnNameIterator,
@@ -159,17 +150,15 @@
}
@SuppressWarnings({"unchecked"})
- private void addWithMiddleTable(String name, Collection value, CompositeMapperBuilder
currentMapper,
- String entityName, EntityXmlMappingData
xmlMappingData, VersionsJoinTable joinTable) {
+ private void addWithMiddleTable() {
// Generating the name of the middle table
-
String versionsMiddleTableName;
String versionsMiddleEntityName;
if (!StringTools.isEmpty(joinTable.name())) {
versionsMiddleTableName = joinTable.name();
versionsMiddleEntityName = joinTable.name();
} else {
- String middleTableName = getMiddleTableName(value, entityName);
+ String middleTableName = getMiddleTableName(propertyValue,
referencingEntityName);
versionsMiddleTableName =
mainGenerator.getVerEntCfg().getVersionsTableName(null, middleTableName);
versionsMiddleEntityName =
mainGenerator.getVerEntCfg().getVersionsEntityName(middleTableName);
}
@@ -177,32 +166,18 @@
// Generating the XML mapping for the middle entity, only if the relation
isn't inverse.
// If the relation is inverse, will be later checked by comparing middleEntityXml
with null.
Element middleEntityXml;
- Element middleEntityXmlId;
- if (!value.isInverse()) {
- String schema = StringTools.isEmpty(joinTable.schema()) ?
value.getCollectionTable().getSchema() : joinTable.schema();
- String catalog = StringTools.isEmpty(joinTable.catalog()) ?
value.getCollectionTable().getCatalog() : joinTable.catalog();
-
- middleEntityXml =
MetadataTools.createEntity(xmlMappingData.newAdditionalMapping(),
- versionsMiddleEntityName, versionsMiddleTableName, schema, catalog,
null);
- middleEntityXmlId = middleEntityXml.addElement("composite-id");
+ if (!propertyValue.isInverse()) {
+ middleEntityXml = createMiddleEntityXml(versionsMiddleTableName,
versionsMiddleEntityName);
} else {
middleEntityXml = null;
- middleEntityXmlId = null;
}
// ******
// Generating the mapping for the referencing entity (it must be an entity).
// ******
- EntityConfiguration referencingConfiguration =
mainGenerator.getEntitiesConfigurations().get(entityName);
- if (referencingConfiguration == null) {
- throw new MappingException("Unable to read versioning configuration for
" + entityName + "!");
- }
-
// Getting the id-mapping data of the referencing entity (the entity that
"owns" this collection).
- IdMappingData referencingIdMapping =
referencingConfiguration.getIdMappingData();
+ IdMappingData referencingIdMapping =
referencingEntityConfiguration.getIdMappingData();
- // Null if this collection doesn't reference an entity.
- String referencedEntityName = getReferencedEntityName(value.getElement());
// Only valid for an inverse relation; null otherwise.
String mappedBy;
@@ -210,28 +185,25 @@
String referencingPrefixRelated;
String referencedPrefix;
- if (value.isInverse()) {
+ if (propertyValue.isInverse()) {
// If the relation is inverse, then referencedEntityName is not null.
- mappedBy = getMappedBy(value.getCollectionTable(),
mainGenerator.getCfg().getClassMapping(referencedEntityName));
- if (mappedBy == null) {
- throw new MappingException("Unable to read the mapped by attribute
for " + name);
- }
+ mappedBy = getMappedBy(propertyValue.getCollectionTable(),
mainGenerator.getCfg().getClassMapping(referencedEntityName));
referencingPrefixRelated = mappedBy + "_";
referencedPrefix = referencedEntityName == null ? "element" :
StringTools.getLastComponent(referencedEntityName);
} else {
mappedBy = null;
- referencingPrefixRelated = StringTools.getLastComponent(entityName) +
"_";
- referencedPrefix = referencedEntityName == null ? "element" :
name;
+ referencingPrefixRelated =
StringTools.getLastComponent(referencingEntityName) + "_";
+ referencedPrefix = referencedEntityName == null ? "element" :
propertyName;
}
// Storing the id data of the referencing entity: original mapper, prefixed
mapper and entity name.
MiddleIdData referencingIdData = new MiddleIdData(
referencingIdMapping.getIdMapper(),
referencingIdMapping.getIdMapper().prefixMappedProperties(referencingPrefixRelated),
- entityName,
- mainGenerator.getVerEntCfg().getVersionsEntityName(entityName));
+ referencingEntityName,
+
mainGenerator.getVerEntCfg().getVersionsEntityName(referencingEntityName));
// Creating a query generator builder, to which additional id data will be added,
in case this collection
// references some entities (either from the element or index). At the end, this
will be used to build
@@ -241,34 +213,25 @@
// Adding the XML mapping for the referencing entity, if the relation isn't
inverse.
if (middleEntityXml != null) {
- middleEntityXmlId.addAttribute("name",
mainGenerator.getVerEntCfg().getOriginalIdPropName());
-
// Adding related-entity (in this case: the referencing's entity id) id
mapping to the xml.
- addRelatedToXmlMapping(middleEntityXmlId, referencingPrefixRelated,
-
MetadataTools.getColumnNameIterator(value.getKey().getColumnIterator()),
+ addRelatedToXmlMapping(middleEntityXml, referencingPrefixRelated,
+
MetadataTools.getColumnNameIterator(propertyValue.getKey().getColumnIterator()),
referencingIdMapping);
-
- // Adding the revision number as a foreign key to the revision info entity to
the composite id of the
- // middle table.
- mainGenerator.addRevisionInfoRelation(middleEntityXmlId);
-
- // Adding the revision type property to the entity xml.
- mainGenerator.addRevisionType(middleEntityXml);
}
// ******
// Generating the element mapping.
// ******
- MiddleComponentData elementComponentData =
addValueToMiddleTable(value.getElement(), middleEntityXmlId,
+ MiddleComponentData elementComponentData =
addValueToMiddleTable(propertyValue.getElement(), middleEntityXml,
queryGeneratorBuilder, referencedPrefix,
joinTable.inverseJoinColumns());
// ******
// Optionally, generating the index mapping.
// ******
MiddleComponentData indexComponentData;
- if (value instanceof IndexedCollection) {
- IndexedCollection indexedValue = (IndexedCollection) value;
- indexComponentData = addValueToMiddleTable(indexedValue.getIndex(),
middleEntityXmlId,
+ if (propertyValue instanceof IndexedCollection) {
+ IndexedCollection indexedValue = (IndexedCollection) propertyValue;
+ indexComponentData = addValueToMiddleTable(indexedValue.getIndex(),
middleEntityXml,
queryGeneratorBuilder, "mapkey", null);
// TODO: @MapKey support, @MapKeyManyToMany
} else {
@@ -280,58 +243,27 @@
// ******
// Generating the property mapper.
// ******
-
// Building the query generator.
MiddleTableQueryGenerator queryGenerator =
queryGeneratorBuilder.build(elementComponentData, indexComponentData);
// Creating common data
CommonCollectionMapperData commonCollectionMapperData = new
CommonCollectionMapperData(
- mainGenerator.getVerEntCfg(), versionsMiddleEntityName, name,
referencingIdData, queryGenerator);
+ mainGenerator.getVerEntCfg(), versionsMiddleEntityName, propertyName,
referencingIdData, queryGenerator);
// Checking the type of the collection and adding an appropriate mapper.
- Type type = value.getType();
- if (type instanceof SortedSetType) {
- currentMapper.addComposite(name, new
BasicCollectionMapper<Set>(commonCollectionMapperData,
- TreeSet.class, SortedSetProxy.class, elementComponentData));
- } else if (type instanceof SetType) {
- currentMapper.addComposite(name, new
BasicCollectionMapper<Set>(commonCollectionMapperData,
- HashSet.class, SetProxy.class, elementComponentData));
- } else if (type instanceof SortedMapType) {
- // Indexed collection, so <code>indexComponentData</code> is not
null.
- currentMapper.addComposite(name, new
MapCollectionMapper<Map>(commonCollectionMapperData,
- TreeMap.class, SortedMapProxy.class, elementComponentData,
indexComponentData));
- } else if (type instanceof MapType) {
- // Indexed collection, so <code>indexComponentData</code> is not
null.
- currentMapper.addComposite(name, new
MapCollectionMapper<Map>(commonCollectionMapperData,
- HashMap.class, MapProxy.class, elementComponentData,
indexComponentData));
- } else if (type instanceof BagType) {
- currentMapper.addComposite(name, new
BasicCollectionMapper<List>(commonCollectionMapperData,
- ArrayList.class, ListProxy.class, elementComponentData));
- } else {
- throw new RuntimeException();
- }
+ addMapper(commonCollectionMapperData, elementComponentData, indexComponentData);
// ******
// Storing information about this relation.
// ******
-
- // Only if this is a relation (when there is a referenced entity).
- if (referencedEntityName != null) {
- if (value.isInverse()) {
-
mainGenerator.getEntitiesConfigurations().get(entityName).addToManyMiddleNotOwningRelation(name,
mappedBy,
- referencedEntityName);
- } else {
-
mainGenerator.getEntitiesConfigurations().get(entityName).addToManyMiddleRelation(name,
- referencedEntityName);
- }
- }
+ storeMiddleEntityRelationInformation(mappedBy);
}
/**
*
* @param value Value, which should be mapped to the middle-table, either as a
relation to another entity,
* or as a simple value.
- * @param middleEntityXml If not <code>null</code>, xml mapping for this
value is added to this element.
+ * @param xmlMapping If not <code>null</code>, xml mapping for this value
is added to this element.
* @param queryGeneratorBuilder In case <code>value</code> is a relation
to another entity, information about it
* should be added to the given.
* @param prefix Prefix for proeprty names of related entities identifiers.
@@ -339,7 +271,7 @@
* @return Data for mapping this component.
*/
@SuppressWarnings({"unchecked"})
- private MiddleComponentData addValueToMiddleTable(Value value, Element
middleEntityXml,
+ private MiddleComponentData addValueToMiddleTable(Value value, Element xmlMapping,
QueryGeneratorBuilder
queryGeneratorBuilder,
String prefix, JoinColumn[]
joinColumns) {
Type type = value.getType();
@@ -351,9 +283,9 @@
referencedEntityName).getIdMappingData();
// Adding related-entity (in this case: the referenced entities id) id
mapping to the xml only if the
- // relation isn't inverse (so when
<code>middleEntityXml</code> is not null).
- if (middleEntityXml != null) {
- addRelatedToXmlMapping(middleEntityXml, prefixRelated,
+ // relation isn't inverse (so when <code>xmlMapping</code> is
not null).
+ if (xmlMapping != null) {
+ addRelatedToXmlMapping(xmlMapping, prefixRelated,
joinColumns != null && joinColumns.length > 0
? MetadataTools.getColumnNameIterator(joinColumns)
:
MetadataTools.getColumnNameIterator(value.getColumnIterator()),
@@ -374,7 +306,7 @@
queryGeneratorBuilder.getCurrentIndex());
} else if (type instanceof ImmutableType || type instanceof MutableType) {
// TODO: add support for enums, components, custom types
- mainGenerator.getBasicMetadataGenerator().addSimpleValue(middleEntityXml,
prefix, value, null, ModificationStore.FULL, true);
+ mainGenerator.getBasicMetadataGenerator().addSimpleValue(xmlMapping, prefix,
value, null, ModificationStore.FULL, true);
// Simple values are always stored in the first entity read by the query
generator.
return new MiddleComponentData(new
MiddleSimpleComponentMapper(mainGenerator.getVerEntCfg(), prefix), 0);
@@ -383,4 +315,107 @@
throw new RuntimeException();
}
}
+
+ private void addMapper(CommonCollectionMapperData commonCollectionMapperData,
MiddleComponentData elementComponentData,
+ MiddleComponentData indexComponentData) {
+ Type type = propertyValue.getType();
+ if (type instanceof SortedSetType) {
+ currentMapper.addComposite(propertyName, new
BasicCollectionMapper<Set>(commonCollectionMapperData,
+ TreeSet.class, SortedSetProxy.class, elementComponentData));
+ } else if (type instanceof SetType) {
+ currentMapper.addComposite(propertyName, new
BasicCollectionMapper<Set>(commonCollectionMapperData,
+ HashSet.class, SetProxy.class, elementComponentData));
+ } else if (type instanceof SortedMapType) {
+ // Indexed collection, so <code>indexComponentData</code> is not
null.
+ currentMapper.addComposite(propertyName, new
MapCollectionMapper<Map>(commonCollectionMapperData,
+ TreeMap.class, SortedMapProxy.class, elementComponentData,
indexComponentData));
+ } else if (type instanceof MapType) {
+ // Indexed collection, so <code>indexComponentData</code> is not
null.
+ currentMapper.addComposite(propertyName, new
MapCollectionMapper<Map>(commonCollectionMapperData,
+ HashMap.class, MapProxy.class, elementComponentData,
indexComponentData));
+ } else if (type instanceof BagType) {
+ currentMapper.addComposite(propertyName, new
BasicCollectionMapper<List>(commonCollectionMapperData,
+ ArrayList.class, ListProxy.class, elementComponentData));
+ } else {
+ mainGenerator.throwUnsupportedTypeException(type, referencingEntityName,
propertyName);
+ }
+ }
+
+ private void storeMiddleEntityRelationInformation(String mappedBy) {
+ // Only if this is a relation (when there is a referenced entity).
+ if (referencedEntityName != null) {
+ if (propertyValue.isInverse()) {
+
referencingEntityConfiguration.addToManyMiddleNotOwningRelation(propertyName, mappedBy,
referencedEntityName);
+ } else {
+ referencingEntityConfiguration.addToManyMiddleRelation(propertyName,
referencedEntityName);
+ }
+ }
+ }
+
+ private Element createMiddleEntityXml(String versionsMiddleTableName, String
versionsMiddleEntityName) {
+ String schema = StringTools.isEmpty(joinTable.schema()) ?
propertyValue.getCollectionTable().getSchema() : joinTable.schema();
+ String catalog = StringTools.isEmpty(joinTable.catalog()) ?
propertyValue.getCollectionTable().getCatalog() : joinTable.catalog();
+
+ Element middleEntityXml =
MetadataTools.createEntity(xmlMappingData.newAdditionalMapping(),
+ versionsMiddleEntityName, versionsMiddleTableName, schema, catalog,
null);
+ Element middleEntityXmlId =
middleEntityXml.addElement("composite-id");
+
+ middleEntityXmlId.addAttribute("name",
mainGenerator.getVerEntCfg().getOriginalIdPropName());
+
+ // Adding the revision number as a foreign key to the revision info entity to the
composite id of the
+ // middle table.
+ mainGenerator.addRevisionInfoRelation(middleEntityXmlId);
+
+ // Adding the revision type property to the entity xml.
+ mainGenerator.addRevisionType(middleEntityXml);
+
+ // All other properties should also be part of the primary key of the middle
entity.
+ return middleEntityXmlId;
+ }
+
+ private VersionsJoinTable getDefaultVersionsJoinTable() {
+ return new VersionsJoinTable() {
+ public String name() { return ""; }
+ public String schema() { return ""; }
+ public String catalog() { return ""; }
+ public JoinColumn[] inverseJoinColumns() { return new JoinColumn[0]; }
+ public Class<? extends Annotation> annotationType() { return
this.getClass(); }
+ };
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private String getMappedBy(Collection collectionValue) {
+ Iterator<Property> assocClassProps =
+ ((OneToMany)
collectionValue.getElement()).getAssociatedClass().getPropertyIterator();
+
+ while (assocClassProps.hasNext()) {
+ Property property = assocClassProps.next();
+
+ if (Tools.iteratorsContentEqual(property.getValue().getColumnIterator(),
+ collectionValue.getKey().getColumnIterator())) {
+ return property.getName();
+ }
+ }
+
+ throw new MappingException("Unable to read the mapped by attribute for
" + propertyName + " in "
+ + referencingEntityName + "!");
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private String getMappedBy(Table collectionTable, PersistentClass referencedClass) {
+ Iterator<Property> properties = referencedClass.getPropertyIterator();
+ while (properties.hasNext()) {
+ Property property = properties.next();
+ if (property.getValue() instanceof Collection) {
+ // The equality is intentional. We want to find a collection property
with the same collection table.
+ //noinspection ObjectEquality
+ if (((Collection) property.getValue()).getCollectionTable() ==
collectionTable) {
+ return property.getName();
+ }
+ }
+ }
+
+ throw new MappingException("Unable to read the mapped by attribute for
" + propertyName + " in "
+ + referencingEntityName + "!");
+ }
}
Modified:
trunk/src/main/org/jboss/envers/configuration/metadata/VersionsMetadataGenerator.java
===================================================================
---
trunk/src/main/org/jboss/envers/configuration/metadata/VersionsMetadataGenerator.java 2008-09-22
11:26:24 UTC (rev 159)
+++
trunk/src/main/org/jboss/envers/configuration/metadata/VersionsMetadataGenerator.java 2008-09-22
15:33:44 UTC (rev 160)
@@ -55,7 +55,6 @@
private final BasicMetadataGenerator basicMetadataGenerator;
private final IdMetadataGenerator idMetadataGenerator;
- private final CollectionMetadataGenerator collectionMetadataGenerator;
private final ToOneRelationMetadataGenerator toOneRelationMetadataGenerator;
private final Map<String, EntityConfiguration> entitiesConfigurations;
@@ -75,7 +74,6 @@
this.basicMetadataGenerator = new BasicMetadataGenerator(this);
this.idMetadataGenerator = new IdMetadataGenerator(this);
- this.collectionMetadataGenerator = new CollectionMetadataGenerator(this);
this.toOneRelationMetadataGenerator = new ToOneRelationMetadataGenerator(this);
entitiesConfigurations = new HashMap<String, EntityConfiguration>();
@@ -166,17 +164,12 @@
} else if (type instanceof CollectionType) {
// only second pass
if (!firstPass) {
- collectionMetadataGenerator.addCollection(name, (Collection) value,
currentMapper, entityName,
- xmlMappingData, joinTable);
+ CollectionMetadataGenerator collectionMetadataGenerator = new
CollectionMetadataGenerator(this,
+ name, (Collection) value, currentMapper, entityName,
xmlMappingData, joinTable);
+ collectionMetadataGenerator.addCollection();
}
} else {
- String message = "Type not supported for versioning: " +
type.getClass().getName() +
- ", on entity " + entityName + ", property '"
+ name + "'.";
- if (globalCfg.isWarnOnUnsupportedTypes()) {
- log.warn(message);
- } else {
- throw new MappingException(message);
- }
+ throwUnsupportedTypeException(type, entityName, name);
}
}
@@ -386,4 +379,14 @@
VersionsEntitiesConfiguration getVerEntCfg() {
return verEntCfg;
}
+
+ void throwUnsupportedTypeException(Type type, String entityName, String propertyName)
{
+ String message = "Type not supported for versioning: " +
type.getClass().getName() +
+ ", on entity " + entityName + ", property '" +
propertyName + "'.";
+ if (globalCfg.isWarnOnUnsupportedTypes()) {
+ log.warn(message);
+ } else {
+ throw new MappingException(message);
+ }
+ }
}
Deleted:
trunk/src/main/org/jboss/envers/entities/mapper/relation/AbstractOneToManyMapper.java
===================================================================
---
trunk/src/main/org/jboss/envers/entities/mapper/relation/AbstractOneToManyMapper.java 2008-09-22
11:26:24 UTC (rev 159)
+++
trunk/src/main/org/jboss/envers/entities/mapper/relation/AbstractOneToManyMapper.java 2008-09-22
15:33:44 UTC (rev 160)
@@ -1,84 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Copyright 2008, Red Hat Middleware LLC, and others contributors as indicated
- * by the @authors tag. All rights reserved.
- *
- * See the copyright.txt in the distribution for a full listing of individual
- * contributors. This copyrighted material is made available to anyone wishing
- * to use, modify, copy, or redistribute it subject to the terms and
- * conditions of the GNU Lesser General Public License, v. 2.1.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT A WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License, v.2.1 along with this distribution; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * Red Hat Author(s): Adam Warski
- */
-package org.jboss.envers.entities.mapper.relation;
-
-import org.jboss.envers.reader.VersionsReaderImplementor;
-import org.jboss.envers.tools.reflection.ReflectionTools;
-import org.jboss.envers.entities.mapper.relation.lazy.proxy.ListProxy;
-import org.jboss.envers.entities.mapper.relation.lazy.proxy.SetProxy;
-import org.jboss.envers.entities.mapper.relation.lazy.initializor.Initializor;
-import org.jboss.envers.entities.mapper.relation.lazy.proxy.MapProxy;
-import org.jboss.envers.entities.mapper.PropertyMapper;
-import org.jboss.envers.exception.VersionsException;
-import org.jboss.envers.configuration.VersionsConfiguration;
-import org.hibernate.property.Getter;
-import org.hibernate.property.Setter;
-
-import java.util.*;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public abstract class AbstractOneToManyMapper implements PropertyMapper {
- private final String owningEntityName;
- private final String propertyName;
-
- protected AbstractOneToManyMapper(String owningEntityName, String propertyName) {
- this.owningEntityName = owningEntityName;
- this.propertyName = propertyName;
- }
-
- protected abstract <T> Initializor<T>
getInitializator(VersionsConfiguration verCfg,
- VersionsReaderImplementor
versionsReader,
- Class<?> entityClass,
Object primaryKey,
- Number revision,
Class<T> collectionClass);
-
- @SuppressWarnings({"unchecked"})
- public void mapToEntityFromMap(VersionsConfiguration verCfg, Object obj, Map data,
Object primaryKey,
- VersionsReaderImplementor versionsReader, Number
revision) {
- if (obj == null) {
- return;
- }
-
- Class<?> entityClass = ReflectionTools.loadClass(owningEntityName);
-
- Getter getter = ReflectionTools.getGetter(obj.getClass(), propertyName);
- Class collectionClass = getter.getReturnType();
-
- // todo: investigate generics
- Object value;
- if (List.class.isAssignableFrom(collectionClass)) {
- value = new ListProxy(getInitializator(verCfg, versionsReader, entityClass,
primaryKey, revision, ArrayList.class));
- } else if (Set.class.isAssignableFrom(collectionClass) ||
Collection.class.isAssignableFrom(collectionClass)) {
- value = new SetProxy(getInitializator(verCfg, versionsReader, entityClass,
primaryKey, revision, HashSet.class));
- } else if (Map.class.isAssignableFrom(collectionClass)) {
- value = new MapProxy(getInitializator(verCfg, versionsReader, entityClass,
primaryKey, revision, HashMap.class));
- } else {
- throw new VersionsException("Unsupported versioned collection type:
" + collectionClass.getName());
- }
-
- Setter setter = ReflectionTools.getSetter(obj.getClass(), propertyName);
- setter.set(obj, value, null);
- }
-}
Modified:
trunk/src/main/org/jboss/envers/entities/mapper/relation/OneToManyAttachedMapper.java
===================================================================
---
trunk/src/main/org/jboss/envers/entities/mapper/relation/OneToManyAttachedMapper.java 2008-09-22
11:26:24 UTC (rev 159)
+++
trunk/src/main/org/jboss/envers/entities/mapper/relation/OneToManyAttachedMapper.java 2008-09-22
15:33:44 UTC (rev 160)
@@ -25,9 +25,16 @@
import org.jboss.envers.entities.mapper.PersistentCollectionChangeData;
import org.jboss.envers.reader.VersionsReaderImplementor;
import org.jboss.envers.entities.mapper.relation.lazy.OneToManyAttachedInitializor;
+import org.jboss.envers.entities.mapper.relation.lazy.proxy.ListProxy;
+import org.jboss.envers.entities.mapper.relation.lazy.proxy.SetProxy;
+import org.jboss.envers.entities.mapper.relation.lazy.proxy.MapProxy;
import org.jboss.envers.entities.mapper.relation.lazy.initializor.Initializor;
import org.jboss.envers.configuration.VersionsConfiguration;
+import org.jboss.envers.tools.reflection.ReflectionTools;
+import org.jboss.envers.exception.VersionsException;
import org.hibernate.collection.PersistentCollection;
+import org.hibernate.property.Getter;
+import org.hibernate.property.Setter;
import java.util.*;
import java.io.Serializable;
@@ -35,24 +42,54 @@
/**
* @author Adam Warski (adam at warski dot org)
*/
-public class OneToManyAttachedMapper extends AbstractOneToManyMapper implements
PropertyMapper {
+public class OneToManyAttachedMapper implements PropertyMapper {
+ private final String owningEntityName;
+ private final String propertyName;
private final String owningReferencePropertyName;
- public OneToManyAttachedMapper(String owningReferencePropertyName, String
owningEntityName, String propertyName) {
- super(owningEntityName, propertyName);
-
+ public OneToManyAttachedMapper(String owningEntityName, String propertyName, String
owningReferencePropertyName) {
+ this.owningEntityName = owningEntityName;
+ this.propertyName = propertyName;
this.owningReferencePropertyName = owningReferencePropertyName;
}
+ @SuppressWarnings({"unchecked"})
+ public void mapToEntityFromMap(VersionsConfiguration verCfg, Object obj, Map data,
Object primaryKey,
+ VersionsReaderImplementor versionsReader, Number
revision) {
+ if (obj == null) {
+ return;
+ }
+
+ Class<?> entityClass = ReflectionTools.loadClass(owningEntityName);
+
+ Getter getter = ReflectionTools.getGetter(obj.getClass(), propertyName);
+ Class collectionClass = getter.getReturnType();
+
+ // todo: investigate generics
+ // todo: add support for @MapKey, sorted collections
+ Object value;
+ if (List.class.isAssignableFrom(collectionClass)) {
+ value = new ListProxy(getInitializator(versionsReader, entityClass,
primaryKey, revision, ArrayList.class));
+ } else if (Set.class.isAssignableFrom(collectionClass) ||
Collection.class.isAssignableFrom(collectionClass)) {
+ value = new SetProxy(getInitializator(versionsReader, entityClass,
primaryKey, revision, HashSet.class));
+ } else if (Map.class.isAssignableFrom(collectionClass)) {
+ value = new MapProxy(getInitializator(versionsReader, entityClass,
primaryKey, revision, HashMap.class));
+ } else {
+ throw new VersionsException("Unsupported versioned collection type:
" + collectionClass.getName());
+ }
+
+ Setter setter = ReflectionTools.getSetter(obj.getClass(), propertyName);
+ setter.set(obj, value, null);
+ }
+
public boolean mapToMapFromEntity(Map<String, Object> data, Object newObj,
Object oldObj) {
return false;
}
- protected <T> Initializor<T> getInitializator(VersionsConfiguration
verCfg,
-
VersionsReaderImplementor versionsReader,
- Class<?>
entityClass, Object primaryKey,
- Number revision,
- Class<T>
collectionClass) {
+ protected <T> Initializor<T> getInitializator(VersionsReaderImplementor
versionsReader,
+ Class<?> entityClass, Object
primaryKey,
+ Number revision,
+ Class<T> collectionClass) {
return new OneToManyAttachedInitializor<T>(versionsReader, entityClass,
owningReferencePropertyName, primaryKey,
revision, collectionClass);
}