From f07044a82ff5884cbaa3513274e56c45396972e7 Mon Sep 17 00:00:00 2001 From: Michal Skowronek Date: Sat, 21 May 2011 22:11:28 +0200 Subject: [PATCH] Added test cases for SortedMap Fixed issue with custom comparators --- .../metadata/CollectionMetadataGenerator.java | 72 +++++--------- .../relation/BasicCollectionMapper.java | 12 ++- .../mapper/relation/MapCollectionMapper.java | 14 +-- .../relation/SortedMapCollectionMapper.java | 53 +++++++++++ .../relation/SortedSetCollectionMapper.java | 53 +++++++++++ .../BasicCollectionInitializor.java | 10 +- .../initializor/MapCollectionInitializor.java | 8 +- .../SortedMapCollectionInitializor.java | 72 ++++++++++++++ .../SortedSetCollectionInitializor.java | 66 +++++++++++++ .../entities/manytomany/SortedSetEntity.java | 30 ++++-- ...t.java => CustomComparatorEntityTest.java} | 93 ++++++++++++++++--- 11 files changed, 391 insertions(+), 92 deletions(-) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedMapCollectionMapper.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedSetCollectionMapper.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java rename hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/{SortedSetWithCustomComparatorEntityTest.java => CustomComparatorEntityTest.java} (64%) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java index 8d69b06f13..2e66f592b0 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java @@ -22,19 +22,9 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.configuration.metadata; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; -import javax.persistence.JoinColumn; + import org.dom4j.Element; import org.hibernate.MappingException; -import org.hibernate.envers.internal.EnversMessageLogger; import org.hibernate.envers.ModificationStore; import org.hibernate.envers.RelationTargetAuditMode; import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData; @@ -45,46 +35,26 @@ import org.hibernate.envers.entities.mapper.CompositeMapperBuilder; import org.hibernate.envers.entities.mapper.PropertyMapper; import org.hibernate.envers.entities.mapper.SinglePropertyMapper; import org.hibernate.envers.entities.mapper.id.IdMapper; -import org.hibernate.envers.entities.mapper.relation.BasicCollectionMapper; -import org.hibernate.envers.entities.mapper.relation.CommonCollectionMapperData; -import org.hibernate.envers.entities.mapper.relation.ListCollectionMapper; -import org.hibernate.envers.entities.mapper.relation.MapCollectionMapper; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.entities.mapper.relation.ToOneIdMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleDummyComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleMapKeyIdComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleMapKeyPropertyComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleRelatedComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleSimpleComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleStraightComponentMapper; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.MapProxy; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.SetProxy; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedMapProxy; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedSetProxy; +import org.hibernate.envers.entities.mapper.relation.*; +import org.hibernate.envers.entities.mapper.relation.component.*; +import org.hibernate.envers.entities.mapper.relation.lazy.proxy.*; import org.hibernate.envers.entities.mapper.relation.query.OneAuditEntityQueryGenerator; import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.EnversMessageLogger; import org.hibernate.envers.tools.MappingTools; import org.hibernate.envers.tools.StringTools; import org.hibernate.envers.tools.Tools; import org.hibernate.mapping.Collection; -import org.hibernate.mapping.IndexedCollection; -import org.hibernate.mapping.OneToMany; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.Property; -import org.hibernate.mapping.Table; -import org.hibernate.mapping.Value; -import org.hibernate.type.BagType; -import org.hibernate.type.ListType; -import org.hibernate.type.ManyToOneType; -import org.hibernate.type.MapType; -import org.hibernate.type.SetType; -import org.hibernate.type.SortedMapType; -import org.hibernate.type.SortedSetType; -import org.hibernate.type.Type; +import org.hibernate.mapping.*; +import org.hibernate.type.*; import org.jboss.logging.Logger; +import javax.persistence.JoinColumn; +import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * Generates metadata for a collection-valued property. * @author Adam Warski (adam at warski dot org) @@ -476,18 +446,18 @@ public final class CollectionMetadataGenerator { MiddleComponentData indexComponentData) { Type type = propertyValue.getType(); if (type instanceof SortedSetType) { - currentMapper.addComposite(propertyAuditingData.getPropertyData(), - new BasicCollectionMapper(commonCollectionMapperData, - TreeSet.class, SortedSetProxy.class, elementComponentData)); - } else if (type instanceof SetType) { - currentMapper.addComposite(propertyAuditingData.getPropertyData(), + currentMapper.addComposite(propertyAuditingData.getPropertyData(), + new SortedSetCollectionMapper(commonCollectionMapperData, + TreeSet.class, SortedSetProxy.class, elementComponentData, propertyValue.getComparator())); + } else if (type instanceof SetType) { + currentMapper.addComposite(propertyAuditingData.getPropertyData(), new BasicCollectionMapper(commonCollectionMapperData, HashSet.class, SetProxy.class, elementComponentData)); } else if (type instanceof SortedMapType) { // Indexed collection, so indexComponentData is not null. - currentMapper.addComposite(propertyAuditingData.getPropertyData(), - new MapCollectionMapper(commonCollectionMapperData, - TreeMap.class, SortedMapProxy.class, elementComponentData, indexComponentData)); + currentMapper.addComposite(propertyAuditingData.getPropertyData(), + new SortedMapCollectionMapper(commonCollectionMapperData, + TreeMap.class, SortedMapProxy.class, elementComponentData, indexComponentData, propertyValue.getComparator())); } else if (type instanceof MapType) { // Indexed collection, so indexComponentData is not null. currentMapper.addComposite(propertyAuditingData.getPropertyData(), diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/BasicCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/BasicCollectionMapper.java index 8145c87495..f87fd42a75 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/BasicCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/BasicCollectionMapper.java @@ -22,9 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.entities.mapper.relation; -import java.io.Serializable; -import java.util.Collection; -import java.util.Map; + import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.envers.configuration.AuditConfiguration; import org.hibernate.envers.entities.mapper.PropertyMapper; @@ -32,11 +30,15 @@ import org.hibernate.envers.entities.mapper.relation.lazy.initializor.BasicColle import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; import org.hibernate.envers.reader.AuditReaderImplementor; +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; + /** * @author Adam Warski (adam at warski dot org) */ -public final class BasicCollectionMapper extends AbstractCollectionMapper implements PropertyMapper { - private final MiddleComponentData elementComponentData; +public class BasicCollectionMapper extends AbstractCollectionMapper implements PropertyMapper { + protected final MiddleComponentData elementComponentData; public BasicCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, Class collectionClass, Class proxyClass, diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MapCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MapCollectionMapper.java index 6d2f29bb40..7b6a9899fe 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MapCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MapCollectionMapper.java @@ -22,9 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.entities.mapper.relation; -import java.io.Serializable; -import java.util.Collection; -import java.util.Map; + import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.envers.configuration.AuditConfiguration; import org.hibernate.envers.entities.mapper.PropertyMapper; @@ -32,12 +30,16 @@ import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializo import org.hibernate.envers.entities.mapper.relation.lazy.initializor.MapCollectionInitializor; import org.hibernate.envers.reader.AuditReaderImplementor; +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; + /** * @author Adam Warski (adam at warski dot org) */ -public final class MapCollectionMapper extends AbstractCollectionMapper implements PropertyMapper { - private final MiddleComponentData elementComponentData; - private final MiddleComponentData indexComponentData; +public class MapCollectionMapper extends AbstractCollectionMapper implements PropertyMapper { + protected final MiddleComponentData elementComponentData; + protected final MiddleComponentData indexComponentData; public MapCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, Class collectionClass, Class proxyClass, diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedMapCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedMapCollectionMapper.java new file mode 100644 index 0000000000..b40cdbd03c --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedMapCollectionMapper.java @@ -0,0 +1,53 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * 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, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY 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 + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.entities.mapper.relation; + +import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.entities.mapper.relation.lazy.initializor.SortedMapCollectionInitializor; +import org.hibernate.envers.reader.AuditReaderImplementor; + +import java.util.Comparator; +import java.util.SortedMap; + +/** + * @author Michal Skowronek (mskowr at o2 dot pl) + */ +public final class SortedMapCollectionMapper extends MapCollectionMapper { + private final Comparator comparator; + + public SortedMapCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, + Class collectionClass, Class proxyClass, + MiddleComponentData elementComponentData, MiddleComponentData indexComponentData, Comparator comparator) { + super(commonCollectionMapperData, collectionClass, proxyClass, elementComponentData, indexComponentData); + this.comparator = comparator; + } + + protected Initializor getInitializor(AuditConfiguration verCfg, AuditReaderImplementor versionsReader, + Object primaryKey, Number revision) { + return new SortedMapCollectionInitializor(verCfg, versionsReader, commonCollectionMapperData.getQueryGenerator(), + primaryKey, revision, collectionClass, elementComponentData, indexComponentData, comparator); + } + +} \ No newline at end of file diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedSetCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedSetCollectionMapper.java new file mode 100644 index 0000000000..2b29559334 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedSetCollectionMapper.java @@ -0,0 +1,53 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * 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, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY 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 + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.entities.mapper.relation; + +import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.entities.mapper.relation.lazy.initializor.SortedSetCollectionInitializor; +import org.hibernate.envers.reader.AuditReaderImplementor; + +import java.util.Comparator; +import java.util.SortedSet; + +/** + * @author Michal Skowronek (mskowr at o2 dot pl) + */ +public final class SortedSetCollectionMapper extends BasicCollectionMapper { + private final Comparator comparator; + + public SortedSetCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, + Class collectionClass, Class proxyClass, + MiddleComponentData elementComponentData, Comparator comparator) { + super(commonCollectionMapperData, collectionClass, proxyClass, elementComponentData); + this.comparator = comparator; + } + + protected Initializor getInitializor(AuditConfiguration verCfg, AuditReaderImplementor versionsReader, + Object primaryKey, Number revision) { + return new SortedSetCollectionInitializor(verCfg, versionsReader, commonCollectionMapperData.getQueryGenerator(), + primaryKey, revision, collectionClass, elementComponentData, comparator); + } + +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java index 9fc31c1c82..b975433a4a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java @@ -22,21 +22,23 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.entities.mapper.relation.lazy.initializor; -import java.util.Collection; -import java.util.List; -import java.util.Map; + import org.hibernate.envers.configuration.AuditConfiguration; import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.reader.AuditReaderImplementor; +import java.util.Collection; +import java.util.List; +import java.util.Map; + /** * Initializes a non-indexed java collection (set or list, eventually sorted). * @author Adam Warski (adam at warski dot org) */ public class BasicCollectionInitializor extends AbstractCollectionInitializor { - private final Class collectionClass; + protected final Class collectionClass; private final MiddleComponentData elementComponentData; public BasicCollectionInitializor(AuditConfiguration verCfg, diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java index f49810fdd3..dce3cdb0af 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java @@ -22,20 +22,22 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.entities.mapper.relation.lazy.initializor; -import java.util.List; -import java.util.Map; + import org.hibernate.envers.configuration.AuditConfiguration; import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.reader.AuditReaderImplementor; +import java.util.List; +import java.util.Map; + /** * Initializes a map. * @author Adam Warski (adam at warski dot org) */ public class MapCollectionInitializor extends AbstractCollectionInitializor { - private final Class collectionClass; + protected final Class collectionClass; private final MiddleComponentData elementComponentData; private final MiddleComponentData indexComponentData; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java new file mode 100644 index 0000000000..8b11aef4cf --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java @@ -0,0 +1,72 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * 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, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY 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 + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.entities.mapper.relation.lazy.initializor; + +import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.exception.AuditException; +import org.hibernate.envers.reader.AuditReaderImplementor; + +import java.lang.reflect.InvocationTargetException; +import java.util.Comparator; +import java.util.SortedMap; + +/** + * Initializes SortedMap collection with proper Comparator + * + * @author Michal Skowronek (mskowr at o2 dot pl) + */ +public class SortedMapCollectionInitializor extends MapCollectionInitializor { + private final Comparator comparator; + + public SortedMapCollectionInitializor(AuditConfiguration verCfg, + AuditReaderImplementor versionsReader, + RelationQueryGenerator queryGenerator, + Object primaryKey, Number revision, + Class collectionClass, + MiddleComponentData elementComponentData, + MiddleComponentData indexComponentData, Comparator comparator) { + super(verCfg, versionsReader, queryGenerator, primaryKey, revision, collectionClass, elementComponentData, indexComponentData); + this.comparator = comparator; + } + + protected SortedMap initializeCollection(int size) { + if (comparator == null) { + return super.initializeCollection(size); + } + try { + return collectionClass.getConstructor(Comparator.class).newInstance(comparator); + } catch (InstantiationException e) { + throw new AuditException(e); + } catch (IllegalAccessException e) { + throw new AuditException(e); + } catch (NoSuchMethodException e) { + throw new AuditException(e); + } catch (InvocationTargetException e) { + throw new AuditException(e); + } + } + +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java new file mode 100644 index 0000000000..0ec0865c61 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java @@ -0,0 +1,66 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * 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, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY 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 + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.entities.mapper.relation.lazy.initializor; + +import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.exception.AuditException; +import org.hibernate.envers.reader.AuditReaderImplementor; + +import java.lang.reflect.InvocationTargetException; +import java.util.Comparator; +import java.util.SortedSet; + +/** + * Initializes SortedSet collection with proper Comparator + * + * @author Michal Skowronek (mskowr at o2 dot pl) + */ +public class SortedSetCollectionInitializor extends BasicCollectionInitializor { + private final Comparator comparator; + + public SortedSetCollectionInitializor(AuditConfiguration verCfg, AuditReaderImplementor versionsReader, RelationQueryGenerator queryGenerator, Object primaryKey, Number revision, Class collectionClass, MiddleComponentData elementComponentData, Comparator comparator) { + super(verCfg, versionsReader, queryGenerator, primaryKey, revision, collectionClass, elementComponentData); + this.comparator = comparator; + } + + @Override + protected SortedSet initializeCollection(int size) { + if (comparator == null) { + return super.initializeCollection(size); + } + try { + return collectionClass.getConstructor(Comparator.class).newInstance(comparator); + } catch (InstantiationException e) { + throw new AuditException(e); + } catch (IllegalAccessException e) { + throw new AuditException(e); + } catch (NoSuchMethodException e) { + throw new AuditException(e); + } catch (InvocationTargetException e) { + throw new AuditException(e); + } + } +} diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/manytomany/SortedSetEntity.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/manytomany/SortedSetEntity.java index 780da619f8..47d82e16fb 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/manytomany/SortedSetEntity.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/manytomany/SortedSetEntity.java @@ -29,14 +29,14 @@ import org.hibernate.envers.Audited; import org.hibernate.envers.test.entities.StrTestEntity; import org.hibernate.envers.test.entities.StrTestEntityComparator; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToMany; +import javax.persistence.*; +import java.util.SortedMap; import java.util.SortedSet; +import java.util.TreeMap; import java.util.TreeSet; /** - * Entity with custom-ordered SortedSet + * Entity with custom-ordered SortedSet and SortedMap * * @author Michal Skowronek (mskowr at o2 pl) */ @@ -52,6 +52,11 @@ public class SortedSetEntity { @ManyToMany @Sort(type = SortType.COMPARATOR, comparator = StrTestEntityComparator.class) private SortedSet sortedSet = new TreeSet(StrTestEntityComparator.INSTANCE); + @Audited + @ElementCollection + @MapKeyJoinColumn + @Sort(type = SortType.COMPARATOR, comparator = StrTestEntityComparator.class) + private SortedMap sortedMap = new TreeMap(StrTestEntityComparator.INSTANCE); public SortedSetEntity() { } @@ -89,17 +94,22 @@ public class SortedSetEntity { this.sortedSet = sortedSet; } - public boolean equals(Object o) { + public SortedMap getSortedMap() { + return sortedMap; + } + + public void setSortedMap(SortedMap sortedMap) { + this.sortedMap = sortedMap; + } + + public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof SortedSetEntity)) return false; SortedSetEntity that = (SortedSetEntity) o; - if (data != null ? !data.equals(that.data) : that.data != null) return false; - if (id != null ? !id.equals(that.id) : that.id != null) return false; - - return true; - } + return !(data != null ? !data.equals(that.data) : that.data != null) && !(id != null ? !id.equals(that.id) : that.id != null); + } public int hashCode() { int result; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/SortedSetWithCustomComparatorEntityTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/CustomComparatorEntityTest.java similarity index 64% rename from hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/SortedSetWithCustomComparatorEntityTest.java rename to hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/CustomComparatorEntityTest.java index 5ee4a107e8..6e55a844e4 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/SortedSetWithCustomComparatorEntityTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/CustomComparatorEntityTest.java @@ -29,20 +29,17 @@ import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; import org.hibernate.envers.test.entities.StrTestEntityComparator; import org.hibernate.envers.test.entities.manytomany.SortedSetEntity; -import org.hibernate.testing.FailureExpected; import org.junit.Test; import javax.persistence.EntityManager; -import java.util.Arrays; -import java.util.Iterator; -import java.util.SortedSet; +import java.util.*; import static org.junit.Assert.assertEquals; /** * @author Michal Skowronek (mskowr at o2 pl) */ -public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest { +public class CustomComparatorEntityTest extends AbstractEntityTest { private Integer id1; private Integer id2; @@ -59,7 +56,7 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest public void initData() { EntityManager em = getEntityManager(); - SortedSetEntity entity1 = new SortedSetEntity(1, "sortedSet1"); + SortedSetEntity entity1 = new SortedSetEntity(1, "sortedEntity1"); // Revision 1 em.getTransaction().begin(); @@ -77,6 +74,7 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest em.persist(strTestEntity1); id1 = strTestEntity1.getId(); entity1.getSortedSet().add(strTestEntity1); + entity1.getSortedMap().put(strTestEntity1, "abc"); em.getTransaction().commit(); @@ -88,6 +86,7 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest em.persist(strTestEntity2); id2 = strTestEntity2.getId(); entity1.getSortedSet().add(strTestEntity2); + entity1.getSortedMap().put(strTestEntity2, "aaa"); em.getTransaction().commit(); @@ -99,6 +98,7 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest em.persist(strTestEntity3); id3 = strTestEntity3.getId(); entity1.getSortedSet().add(strTestEntity3); + entity1.getSortedMap().put(strTestEntity3, "aba"); em.getTransaction().commit(); @@ -110,6 +110,7 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest em.persist(strTestEntity4); id4 = strTestEntity4.getId(); entity1.getSortedSet().add(strTestEntity4); + entity1.getSortedMap().put(strTestEntity4, "aac"); em.getTransaction().commit(); } @@ -127,7 +128,7 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest public void testCurrentStateOfEntity1() { final SortedSetEntity entity1 = getEntityManager().find(SortedSetEntity.class, 1); - assertEquals("sortedSet1", entity1.getData()); + assertEquals("sortedEntity1", entity1.getData()); assertEquals(Integer.valueOf(1), entity1.getId()); final SortedSet sortedSet = entity1.getSortedSet(); @@ -138,6 +139,21 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest checkStrTestEntity(iterator.next(), id4, "aac"); checkStrTestEntity(iterator.next(), id3, "aba"); checkStrTestEntity(iterator.next(), id1, "abc"); + + final SortedMap sortedMap = entity1.getSortedMap(); + assertEquals(StrTestEntityComparator.class, sortedMap.comparator().getClass()); + assertEquals(4, sortedMap.size()); + Iterator> mapIterator = sortedMap.entrySet().iterator(); + checkStrTestEntity(mapIterator.next().getKey(), id2, "aaa"); + checkStrTestEntity(mapIterator.next().getKey(), id4, "aac"); + checkStrTestEntity(mapIterator.next().getKey(), id3, "aba"); + checkStrTestEntity(mapIterator.next().getKey(), id1, "abc"); + + mapIterator = sortedMap.entrySet().iterator(); + assertEquals(mapIterator.next().getValue(), "aaa"); + assertEquals(mapIterator.next().getValue(), "aac"); + assertEquals(mapIterator.next().getValue(), "aba"); + assertEquals(mapIterator.next().getValue(), "abc"); } private void checkStrTestEntity(StrTestEntity entity, Integer id, String sortKey) { @@ -146,20 +162,23 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest } @Test - @FailureExpected(message = "Envers doesn't support custom comparators yet", jiraKey = "HHH-6176") public void testHistoryOfEntity1() throws Exception { SortedSetEntity entity1 = getAuditReader().find(SortedSetEntity.class, 1, 1); - assertEquals("sortedSet1", entity1.getData()); + assertEquals("sortedEntity1", entity1.getData()); assertEquals(Integer.valueOf(1), entity1.getId()); SortedSet sortedSet = entity1.getSortedSet(); assertEquals(StrTestEntityComparator.class, sortedSet.comparator().getClass()); assertEquals(0, sortedSet.size()); + SortedMap sortedMap = entity1.getSortedMap(); + assertEquals(StrTestEntityComparator.class, sortedMap.comparator().getClass()); + assertEquals(0, sortedMap.size()); + entity1 = getAuditReader().find(SortedSetEntity.class, 1, 2); - assertEquals("sortedSet1", entity1.getData()); + assertEquals("sortedEntity1", entity1.getData()); assertEquals(Integer.valueOf(1), entity1.getId()); sortedSet = entity1.getSortedSet(); @@ -168,9 +187,18 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest Iterator iterator = sortedSet.iterator(); checkStrTestEntity(iterator.next(), id1, "abc"); + sortedMap = entity1.getSortedMap(); + assertEquals(StrTestEntityComparator.class, sortedMap.comparator().getClass()); + assertEquals(1, sortedMap.size()); + Iterator> mapIterator = sortedMap.entrySet().iterator(); + checkStrTestEntity(mapIterator.next().getKey(), id1, "abc"); + + mapIterator = sortedMap.entrySet().iterator(); + assertEquals(mapIterator.next().getValue(), "abc"); + entity1 = getAuditReader().find(SortedSetEntity.class, 1, 3); - assertEquals("sortedSet1", entity1.getData()); + assertEquals("sortedEntity1", entity1.getData()); assertEquals(Integer.valueOf(1), entity1.getId()); sortedSet = entity1.getSortedSet(); @@ -180,9 +208,20 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest checkStrTestEntity(iterator.next(), id2, "aaa"); checkStrTestEntity(iterator.next(), id1, "abc"); + sortedMap = entity1.getSortedMap(); + assertEquals(StrTestEntityComparator.class, sortedMap.comparator().getClass()); + assertEquals(2, sortedMap.size()); + mapIterator = sortedMap.entrySet().iterator(); + checkStrTestEntity(mapIterator.next().getKey(), id2, "aaa"); + checkStrTestEntity(mapIterator.next().getKey(), id1, "abc"); + + mapIterator = sortedMap.entrySet().iterator(); + assertEquals(mapIterator.next().getValue(), "aaa"); + assertEquals(mapIterator.next().getValue(), "abc"); + entity1 = getAuditReader().find(SortedSetEntity.class, 1, 4); - assertEquals("sortedSet1", entity1.getData()); + assertEquals("sortedEntity1", entity1.getData()); assertEquals(Integer.valueOf(1), entity1.getId()); sortedSet = entity1.getSortedSet(); @@ -193,9 +232,22 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest checkStrTestEntity(iterator.next(), id3, "aba"); checkStrTestEntity(iterator.next(), id1, "abc"); + sortedMap = entity1.getSortedMap(); + assertEquals(StrTestEntityComparator.class, sortedMap.comparator().getClass()); + assertEquals(3, sortedMap.size()); + mapIterator = sortedMap.entrySet().iterator(); + checkStrTestEntity(mapIterator.next().getKey(), id2, "aaa"); + checkStrTestEntity(mapIterator.next().getKey(), id3, "aba"); + checkStrTestEntity(mapIterator.next().getKey(), id1, "abc"); + + mapIterator = sortedMap.entrySet().iterator(); + assertEquals(mapIterator.next().getValue(), "aaa"); + assertEquals(mapIterator.next().getValue(), "aba"); + assertEquals(mapIterator.next().getValue(), "abc"); + entity1 = getAuditReader().find(SortedSetEntity.class, 1, 5); - assertEquals("sortedSet1", entity1.getData()); + assertEquals("sortedEntity1", entity1.getData()); assertEquals(Integer.valueOf(1), entity1.getId()); sortedSet = entity1.getSortedSet(); @@ -206,6 +258,21 @@ public class SortedSetWithCustomComparatorEntityTest extends AbstractEntityTest checkStrTestEntity(iterator.next(), id4, "aac"); checkStrTestEntity(iterator.next(), id3, "aba"); checkStrTestEntity(iterator.next(), id1, "abc"); + + sortedMap = entity1.getSortedMap(); + assertEquals(StrTestEntityComparator.class, sortedMap.comparator().getClass()); + assertEquals(4, sortedMap.size()); + mapIterator = sortedMap.entrySet().iterator(); + checkStrTestEntity(mapIterator.next().getKey(), id2, "aaa"); + checkStrTestEntity(mapIterator.next().getKey(), id4, "aac"); + checkStrTestEntity(mapIterator.next().getKey(), id3, "aba"); + checkStrTestEntity(mapIterator.next().getKey(), id1, "abc"); + + mapIterator = sortedMap.entrySet().iterator(); + assertEquals(mapIterator.next().getValue(), "aaa"); + assertEquals(mapIterator.next().getValue(), "aac"); + assertEquals(mapIterator.next().getValue(), "aba"); + assertEquals(mapIterator.next().getValue(), "abc"); } }