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/StrTestEntityComparator.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/StrTestEntityComparator.java new file mode 100644 index 0000000000..5954cc8842 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/StrTestEntityComparator.java @@ -0,0 +1,12 @@ +package org.hibernate.envers.test.entities; + +import java.util.Comparator; + +public class StrTestEntityComparator implements Comparator { + public static final StrTestEntityComparator INSTANCE = new StrTestEntityComparator(); + + @Override + public int compare(StrTestEntity o1, StrTestEntity o2) { + return o1.getStr().compareTo(o2.getStr()); + } +} 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 new file mode 100644 index 0000000000..47d82e16fb --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/manytomany/SortedSetEntity.java @@ -0,0 +1,124 @@ +/* + * 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.test.entities.manytomany; + +import org.hibernate.annotations.Sort; +import org.hibernate.annotations.SortType; +import org.hibernate.envers.Audited; +import org.hibernate.envers.test.entities.StrTestEntity; +import org.hibernate.envers.test.entities.StrTestEntityComparator; + +import javax.persistence.*; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Entity with custom-ordered SortedSet and SortedMap + * + * @author Michal Skowronek (mskowr at o2 pl) + */ +@Entity +public class SortedSetEntity { + @Id + private Integer id; + + @Audited + private String data; + + @Audited + @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() { + } + + public SortedSetEntity(Integer id, String data) { + this.id = id; + this.data = data; + } + + public SortedSetEntity(String data) { + this.data = data; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public SortedSet getSortedSet() { + return sortedSet; + } + + public void setSortedSet(SortedSet sortedSet) { + this.sortedSet = sortedSet; + } + + 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; + + return !(data != null ? !data.equals(that.data) : that.data != null) && !(id != null ? !id.equals(that.id) : that.id != null); + } + + public int hashCode() { + int result; + result = (id != null ? id.hashCode() : 0); + result = 31 * result + (data != null ? data.hashCode() : 0); + return result; + } + + public String toString() { + return "SetOwnedEntity(id = " + id + ", data = " + data + ")"; + } +} diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/CustomComparatorEntityTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/CustomComparatorEntityTest.java new file mode 100644 index 0000000000..6e55a844e4 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/CustomComparatorEntityTest.java @@ -0,0 +1,278 @@ +/* + * 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.test.integration.manytomany; + +import org.hibernate.ejb.Ejb3Configuration; +import org.hibernate.envers.test.AbstractEntityTest; +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.junit.Test; + +import javax.persistence.EntityManager; +import java.util.*; + +import static org.junit.Assert.assertEquals; + +/** + * @author Michal Skowronek (mskowr at o2 pl) + */ +public class CustomComparatorEntityTest extends AbstractEntityTest { + + private Integer id1; + private Integer id2; + private Integer id3; + private Integer id4; + + public void configure(Ejb3Configuration cfg) { + cfg.addAnnotatedClass(StrTestEntity.class); + cfg.addAnnotatedClass(SortedSetEntity.class); + } + + @Test + @Priority(10) + public void initData() { + EntityManager em = getEntityManager(); + + SortedSetEntity entity1 = new SortedSetEntity(1, "sortedEntity1"); + + // Revision 1 + em.getTransaction().begin(); + + em.persist(entity1); + + em.getTransaction().commit(); + + // Revision 2 + + em.getTransaction().begin(); + + entity1 = em.find(SortedSetEntity.class, 1); + final StrTestEntity strTestEntity1 = new StrTestEntity("abc"); + em.persist(strTestEntity1); + id1 = strTestEntity1.getId(); + entity1.getSortedSet().add(strTestEntity1); + entity1.getSortedMap().put(strTestEntity1, "abc"); + + em.getTransaction().commit(); + + // Revision 3 + em.getTransaction().begin(); + + entity1 = em.find(SortedSetEntity.class, 1); + final StrTestEntity strTestEntity2 = new StrTestEntity("aaa"); + em.persist(strTestEntity2); + id2 = strTestEntity2.getId(); + entity1.getSortedSet().add(strTestEntity2); + entity1.getSortedMap().put(strTestEntity2, "aaa"); + + em.getTransaction().commit(); + + // Revision 4 + em.getTransaction().begin(); + + entity1 = em.find(SortedSetEntity.class, 1); + final StrTestEntity strTestEntity3 = new StrTestEntity("aba"); + em.persist(strTestEntity3); + id3 = strTestEntity3.getId(); + entity1.getSortedSet().add(strTestEntity3); + entity1.getSortedMap().put(strTestEntity3, "aba"); + + em.getTransaction().commit(); + + // Revision 5 + em.getTransaction().begin(); + + entity1 = em.find(SortedSetEntity.class, 1); + final StrTestEntity strTestEntity4 = new StrTestEntity("aac"); + em.persist(strTestEntity4); + id4 = strTestEntity4.getId(); + entity1.getSortedSet().add(strTestEntity4); + entity1.getSortedMap().put(strTestEntity4, "aac"); + + em.getTransaction().commit(); + } + + @Test + public void testRevisionsCounts() { + assertEquals(Arrays.asList(1, 2, 3, 4, 5), getAuditReader().getRevisions(SortedSetEntity.class, 1)); + assertEquals(Arrays.asList(2), getAuditReader().getRevisions(StrTestEntity.class, id1)); + assertEquals(Arrays.asList(3), getAuditReader().getRevisions(StrTestEntity.class, id2)); + assertEquals(Arrays.asList(4), getAuditReader().getRevisions(StrTestEntity.class, id3)); + assertEquals(Arrays.asList(5), getAuditReader().getRevisions(StrTestEntity.class, id4)); + } + + @Test + public void testCurrentStateOfEntity1() { + final SortedSetEntity entity1 = getEntityManager().find(SortedSetEntity.class, 1); + + assertEquals("sortedEntity1", entity1.getData()); + assertEquals(Integer.valueOf(1), entity1.getId()); + + final SortedSet sortedSet = entity1.getSortedSet(); + assertEquals(StrTestEntityComparator.class, sortedSet.comparator().getClass()); + assertEquals(4, sortedSet.size()); + final Iterator iterator = sortedSet.iterator(); + checkStrTestEntity(iterator.next(), id2, "aaa"); + 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) { + assertEquals(id, entity.getId()); + assertEquals(sortKey, entity.getStr()); + } + + @Test + public void testHistoryOfEntity1() throws Exception { + SortedSetEntity entity1 = getAuditReader().find(SortedSetEntity.class, 1, 1); + + 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("sortedEntity1", entity1.getData()); + assertEquals(Integer.valueOf(1), entity1.getId()); + + sortedSet = entity1.getSortedSet(); + assertEquals(StrTestEntityComparator.class, sortedSet.comparator().getClass()); + assertEquals(1, sortedSet.size()); + 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("sortedEntity1", entity1.getData()); + assertEquals(Integer.valueOf(1), entity1.getId()); + + sortedSet = entity1.getSortedSet(); + assertEquals(StrTestEntityComparator.class, sortedSet.comparator().getClass()); + assertEquals(2, sortedSet.size()); + iterator = sortedSet.iterator(); + 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("sortedEntity1", entity1.getData()); + assertEquals(Integer.valueOf(1), entity1.getId()); + + sortedSet = entity1.getSortedSet(); + assertEquals(StrTestEntityComparator.class, sortedSet.comparator().getClass()); + assertEquals(3, sortedSet.size()); + iterator = sortedSet.iterator(); + checkStrTestEntity(iterator.next(), id2, "aaa"); + 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("sortedEntity1", entity1.getData()); + assertEquals(Integer.valueOf(1), entity1.getId()); + + sortedSet = entity1.getSortedSet(); + assertEquals(StrTestEntityComparator.class, sortedSet.comparator().getClass()); + assertEquals(4, sortedSet.size()); + iterator = sortedSet.iterator(); + checkStrTestEntity(iterator.next(), id2, "aaa"); + 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"); + } + +}