HHH-3570: renaming versioned to audited
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15461 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
9fc49bf328
commit
fabb73a8d1
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* 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.configuration;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.hibernate.envers.entities.EntitiesConfigurations;
|
||||
import org.hibernate.envers.revisioninfo.RevisionInfoNumberReader;
|
||||
import org.hibernate.envers.revisioninfo.RevisionInfoQueryCreator;
|
||||
import org.hibernate.envers.synchronization.VersionsSyncManager;
|
||||
import org.hibernate.envers.tools.reflection.YReflectionManager;
|
||||
|
||||
import org.hibernate.cfg.Configuration;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsConfiguration {
|
||||
private final GlobalConfiguration globalCfg;
|
||||
private final VersionsEntitiesConfiguration verEntCfg;
|
||||
private final VersionsSyncManager versionsSyncManager;
|
||||
private final EntitiesConfigurations entCfg;
|
||||
private final RevisionInfoQueryCreator revisionInfoQueryCreator;
|
||||
private final RevisionInfoNumberReader revisionInfoNumberReader;
|
||||
|
||||
public VersionsEntitiesConfiguration getVerEntCfg() {
|
||||
return verEntCfg;
|
||||
}
|
||||
|
||||
public VersionsSyncManager getSyncManager() {
|
||||
return versionsSyncManager;
|
||||
}
|
||||
|
||||
public GlobalConfiguration getGlobalCfg() {
|
||||
return globalCfg;
|
||||
}
|
||||
|
||||
public EntitiesConfigurations getEntCfg() {
|
||||
return entCfg;
|
||||
}
|
||||
|
||||
public RevisionInfoQueryCreator getRevisionInfoQueryCreator() {
|
||||
return revisionInfoQueryCreator;
|
||||
}
|
||||
|
||||
public RevisionInfoNumberReader getRevisionInfoNumberReader() {
|
||||
return revisionInfoNumberReader;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public VersionsConfiguration(Configuration cfg) {
|
||||
Properties properties = cfg.getProperties();
|
||||
|
||||
YReflectionManager reflectionManager = YReflectionManager.get(cfg);
|
||||
RevisionInfoConfiguration revInfoCfg = new RevisionInfoConfiguration();
|
||||
RevisionInfoConfigurationResult revInfoCfgResult = revInfoCfg.configure(cfg, reflectionManager);
|
||||
verEntCfg = new VersionsEntitiesConfiguration(properties, revInfoCfgResult.getRevisionInfoEntityName());
|
||||
globalCfg = new GlobalConfiguration(properties);
|
||||
versionsSyncManager = new VersionsSyncManager(revInfoCfgResult.getRevisionInfoGenerator());
|
||||
revisionInfoQueryCreator = revInfoCfgResult.getRevisionInfoQueryCreator();
|
||||
revisionInfoNumberReader = revInfoCfgResult.getRevisionInfoNumberReader();
|
||||
entCfg = new EntitiesConfigurator().configure(cfg, reflectionManager, globalCfg, verEntCfg,
|
||||
revInfoCfgResult.getRevisionInfoXmlMapping(), revInfoCfgResult.getRevisionInfoRelationMapping());
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
private static Map<Configuration, VersionsConfiguration> cfgs
|
||||
= new WeakHashMap<Configuration, VersionsConfiguration>();
|
||||
|
||||
public synchronized static VersionsConfiguration getFor(Configuration cfg) {
|
||||
VersionsConfiguration verCfg = cfgs.get(cfg);
|
||||
|
||||
if (verCfg == null) {
|
||||
verCfg = new VersionsConfiguration(cfg);
|
||||
cfgs.put(cfg, verCfg);
|
||||
|
||||
cfg.buildMappings();
|
||||
}
|
||||
|
||||
return verCfg;
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* 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.configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Configuration of versions entities - names of fields, entities and tables created to store versioning information.
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsEntitiesConfiguration {
|
||||
private final String versionsTablePrefix;
|
||||
private final String versionsTableSuffix;
|
||||
|
||||
private final String originalIdPropName;
|
||||
|
||||
private final String revisionPropName;
|
||||
private final String revisionPropPath;
|
||||
|
||||
private final String revisionTypePropName;
|
||||
private final String revisionTypePropType;
|
||||
|
||||
private final String revisionInfoEntityName;
|
||||
|
||||
private final Map<String, String> customVersionsTablesNames;
|
||||
|
||||
public VersionsEntitiesConfiguration(Properties properties, String revisionInfoEntityName) {
|
||||
this.revisionInfoEntityName = revisionInfoEntityName;
|
||||
|
||||
versionsTablePrefix = properties.getProperty("org.hibernate.envers.versionsTablePrefix", "");
|
||||
versionsTableSuffix = properties.getProperty("org.hibernate.envers.versionsTableSuffix", "_versions");
|
||||
|
||||
originalIdPropName = "originalId";
|
||||
|
||||
revisionPropName = properties.getProperty("org.hibernate.envers.revisionFieldName", "_revision");
|
||||
|
||||
revisionTypePropName = properties.getProperty("org.hibernate.envers.revisionTypeFieldName", "_revision_type");
|
||||
revisionTypePropType = "byte";
|
||||
|
||||
customVersionsTablesNames = new HashMap<String, String>();
|
||||
|
||||
revisionPropPath = originalIdPropName + "." + revisionPropName + ".id";
|
||||
}
|
||||
|
||||
public String getOriginalIdPropName() {
|
||||
return originalIdPropName;
|
||||
}
|
||||
|
||||
public String getRevisionPropName() {
|
||||
return revisionPropName;
|
||||
}
|
||||
|
||||
public String getRevisionPropPath() {
|
||||
return revisionPropPath;
|
||||
}
|
||||
|
||||
public String getRevisionTypePropName() {
|
||||
return revisionTypePropName;
|
||||
}
|
||||
|
||||
public String getRevisionTypePropType() {
|
||||
return revisionTypePropType;
|
||||
}
|
||||
|
||||
public String getRevisionInfoEntityName() {
|
||||
return revisionInfoEntityName;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public void addCustomVersionsTableName(String entityName, String tableName) {
|
||||
customVersionsTablesNames.put(entityName, tableName);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public String getVersionsEntityName(String entityName) {
|
||||
return versionsTablePrefix + entityName + versionsTableSuffix;
|
||||
}
|
||||
|
||||
public String getVersionsTableName(String entityName, String tableName) {
|
||||
String customHistoryTableName = customVersionsTablesNames.get(entityName);
|
||||
if (customHistoryTableName == null) {
|
||||
return versionsTablePrefix + tableName + versionsTableSuffix;
|
||||
}
|
||||
|
||||
return customHistoryTableName;
|
||||
}
|
||||
}
|
|
@ -1,385 +0,0 @@
|
|||
/*
|
||||
* 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.configuration.metadata;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.dom4j.Element;
|
||||
import org.hibernate.envers.ModificationStore;
|
||||
import org.hibernate.envers.AuditJoinTable;
|
||||
import org.hibernate.envers.configuration.GlobalConfiguration;
|
||||
import org.hibernate.envers.configuration.VersionsEntitiesConfiguration;
|
||||
import org.hibernate.envers.entities.EntityConfiguration;
|
||||
import org.hibernate.envers.entities.IdMappingData;
|
||||
import org.hibernate.envers.entities.mapper.CompositeMapperBuilder;
|
||||
import org.hibernate.envers.entities.mapper.ExtendedPropertyMapper;
|
||||
import org.hibernate.envers.entities.mapper.MultiPropertyMapper;
|
||||
import org.hibernate.envers.entities.mapper.SubclassPropertyMapper;
|
||||
import org.hibernate.envers.entity.VersionsInheritanceEntityPersister;
|
||||
import org.hibernate.envers.tools.StringTools;
|
||||
import org.hibernate.envers.tools.log.YLog;
|
||||
import org.hibernate.envers.tools.log.YLogManager;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.Join;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.ManyToOneType;
|
||||
import org.hibernate.type.OneToOneType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
* @author Sebastian Komander
|
||||
*/
|
||||
public final class VersionsMetadataGenerator {
|
||||
private final Configuration cfg;
|
||||
private final GlobalConfiguration globalCfg;
|
||||
private final VersionsEntitiesConfiguration verEntCfg;
|
||||
private final Element revisionInfoRelationMapping;
|
||||
|
||||
private final BasicMetadataGenerator basicMetadataGenerator;
|
||||
private final IdMetadataGenerator idMetadataGenerator;
|
||||
private final ToOneRelationMetadataGenerator toOneRelationMetadataGenerator;
|
||||
|
||||
private final Map<String, EntityConfiguration> entitiesConfigurations;
|
||||
|
||||
// Map entity name -> (join descriptor -> element describing the "versioned" join)
|
||||
private final Map<String, Map<Join, Element>> entitiesJoins;
|
||||
|
||||
private YLog log = YLogManager.getLogManager().getLog(VersionsMetadataGenerator.class);
|
||||
|
||||
public VersionsMetadataGenerator(Configuration cfg, GlobalConfiguration globalCfg,
|
||||
VersionsEntitiesConfiguration verEntCfg,
|
||||
Element revisionInfoRelationMapping) {
|
||||
this.cfg = cfg;
|
||||
this.globalCfg = globalCfg;
|
||||
this.verEntCfg = verEntCfg;
|
||||
this.revisionInfoRelationMapping = revisionInfoRelationMapping;
|
||||
|
||||
this.basicMetadataGenerator = new BasicMetadataGenerator();
|
||||
this.idMetadataGenerator = new IdMetadataGenerator(this);
|
||||
this.toOneRelationMetadataGenerator = new ToOneRelationMetadataGenerator(this);
|
||||
|
||||
entitiesConfigurations = new HashMap<String, EntityConfiguration>();
|
||||
entitiesJoins = new HashMap<String, Map<Join, Element>>();
|
||||
}
|
||||
|
||||
void addRevisionInfoRelation(Element any_mapping) {
|
||||
Element rev_mapping = (Element) revisionInfoRelationMapping.clone();
|
||||
rev_mapping.addAttribute("name", verEntCfg.getRevisionPropName());
|
||||
MetadataTools.addColumn(rev_mapping, verEntCfg.getRevisionPropName(), null);
|
||||
|
||||
any_mapping.add(rev_mapping);
|
||||
}
|
||||
|
||||
void addRevisionType(Element any_mapping) {
|
||||
Element revTypeProperty = MetadataTools.addProperty(any_mapping, verEntCfg.getRevisionTypePropName(),
|
||||
verEntCfg.getRevisionTypePropType(), true, false);
|
||||
revTypeProperty.addAttribute("type", "org.hibernate.envers.entities.RevisionTypeType");
|
||||
}
|
||||
|
||||
private ModificationStore getStoreForProperty(Property property, PropertyStoreInfo propertyStoreInfo,
|
||||
List<String> unversionedProperties) {
|
||||
/*
|
||||
* Checks if a property is versioned, which is when:
|
||||
* - the property isn't unversioned
|
||||
* - the whole entity is versioned, then the default store is not null
|
||||
* - there is a store defined for this entity, which is when this property is annotated
|
||||
*/
|
||||
|
||||
if (unversionedProperties.contains(property.getName())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ModificationStore store = propertyStoreInfo.propertyStores.get(property.getName());
|
||||
|
||||
if (store == null) {
|
||||
return propertyStoreInfo.defaultStore;
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
void addValue(Element parent, String name, Value value, CompositeMapperBuilder currentMapper,
|
||||
ModificationStore store, String entityName, EntityXmlMappingData xmlMappingData,
|
||||
AuditJoinTable joinTable, String mapKey, boolean insertable, boolean firstPass) {
|
||||
Type type = value.getType();
|
||||
|
||||
// only first pass
|
||||
if (firstPass) {
|
||||
if (basicMetadataGenerator.addBasic(parent, name, value, currentMapper, store, entityName, insertable,
|
||||
false)) {
|
||||
// The property was mapped by the basic generator.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (type instanceof ManyToOneType) {
|
||||
// only second pass
|
||||
if (!firstPass) {
|
||||
toOneRelationMetadataGenerator.addToOne(parent, name, value, currentMapper, entityName);
|
||||
}
|
||||
} else if (type instanceof OneToOneType) {
|
||||
// only second pass
|
||||
if (!firstPass) {
|
||||
toOneRelationMetadataGenerator.addOneToOneNotOwning(name, value, currentMapper, entityName);
|
||||
}
|
||||
} else if (type instanceof CollectionType) {
|
||||
// only second pass
|
||||
if (!firstPass) {
|
||||
CollectionMetadataGenerator collectionMetadataGenerator = new CollectionMetadataGenerator(this,
|
||||
name, (Collection) value, currentMapper, entityName, xmlMappingData, joinTable, mapKey);
|
||||
collectionMetadataGenerator.addCollection();
|
||||
}
|
||||
} else {
|
||||
if (firstPass) {
|
||||
// If we got here in the first pass, it means the basic mapper didn't map it, and none of the
|
||||
// above branches either.
|
||||
throwUnsupportedTypeException(type, entityName, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private void addProperties(Element parent, Iterator<Property> properties, CompositeMapperBuilder currentMapper,
|
||||
PersistentClassVersioningData versioningData, String entityName, EntityXmlMappingData xmlMappingData,
|
||||
boolean firstPass) {
|
||||
while (properties.hasNext()) {
|
||||
Property property = properties.next();
|
||||
if (!"_identifierMapper".equals(property.getName())) {
|
||||
ModificationStore store = getStoreForProperty(property, versioningData.propertyStoreInfo,
|
||||
versioningData.unversionedProperties);
|
||||
|
||||
if (store != null) {
|
||||
addValue(parent, property.getName(), property.getValue(), currentMapper, store, entityName,
|
||||
xmlMappingData, versioningData.versionsJoinTables.get(property.getName()),
|
||||
versioningData.mapKeys.get(property.getName()), property.isInsertable(), firstPass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private void createJoins(PersistentClass pc, Element parent, PersistentClassVersioningData versioningData) {
|
||||
Iterator<Join> joins = pc.getJoinIterator();
|
||||
|
||||
Map<Join, Element> joinElements = new HashMap<Join, Element>();
|
||||
entitiesJoins.put(pc.getEntityName(), joinElements);
|
||||
|
||||
while (joins.hasNext()) {
|
||||
Join join = joins.next();
|
||||
|
||||
// Determining the table name. If there is no entry in the dictionary, just constructing the table name
|
||||
// as if it was an entity (by appending/prepending configured strings).
|
||||
String originalTableName = join.getTable().getName();
|
||||
String versionedTableName = versioningData.secondaryTableDictionary.get(originalTableName);
|
||||
if (versionedTableName == null) {
|
||||
versionedTableName = verEntCfg.getVersionsEntityName(originalTableName);
|
||||
}
|
||||
|
||||
String schema = versioningData.versionsTable.schema();
|
||||
if (StringTools.isEmpty(schema)) {
|
||||
schema = join.getTable().getSchema();
|
||||
}
|
||||
|
||||
String catalog = versioningData.versionsTable.catalog();
|
||||
if (StringTools.isEmpty(catalog)) {
|
||||
catalog = join.getTable().getCatalog();
|
||||
}
|
||||
|
||||
Element joinElement = MetadataTools.createJoin(parent, versionedTableName, schema, catalog);
|
||||
joinElements.put(join, joinElement);
|
||||
|
||||
Element joinKey = joinElement.addElement("key");
|
||||
MetadataTools.addColumns(joinKey, join.getKey().getColumnIterator());
|
||||
MetadataTools.addColumn(joinKey, verEntCfg.getRevisionPropName(), null);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private void addJoins(PersistentClass pc, CompositeMapperBuilder currentMapper, PersistentClassVersioningData versioningData,
|
||||
String entityName, EntityXmlMappingData xmlMappingData,boolean firstPass) {
|
||||
Iterator<Join> joins = pc.getJoinIterator();
|
||||
|
||||
while (joins.hasNext()) {
|
||||
Join join = joins.next();
|
||||
Element joinElement = entitiesJoins.get(entityName).get(join);
|
||||
|
||||
addProperties(joinElement, join.getPropertyIterator(), currentMapper, versioningData, entityName,
|
||||
xmlMappingData, firstPass);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPersisterHack(Element class_mapping) {
|
||||
class_mapping.addAttribute("persister", VersionsInheritanceEntityPersister.class.getName() );
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public void generateFirstPass(PersistentClass pc, PersistentClassVersioningData versioningData,
|
||||
EntityXmlMappingData xmlMappingData) {
|
||||
String schema = versioningData.versionsTable.schema();
|
||||
if (StringTools.isEmpty(schema)) {
|
||||
schema = pc.getTable().getSchema();
|
||||
}
|
||||
|
||||
String catalog = versioningData.versionsTable.catalog();
|
||||
if (StringTools.isEmpty(catalog)) {
|
||||
catalog = pc.getTable().getCatalog();
|
||||
}
|
||||
|
||||
String entityName = pc.getEntityName();
|
||||
String versionsEntityName = verEntCfg.getVersionsEntityName(entityName);
|
||||
String versionsTableName = verEntCfg.getVersionsTableName(entityName, pc.getTable().getName());
|
||||
|
||||
// Generating a mapping for the id
|
||||
IdMappingData idMapper = idMetadataGenerator.addId(pc);
|
||||
|
||||
Element class_mapping;
|
||||
ExtendedPropertyMapper propertyMapper;
|
||||
|
||||
InheritanceType inheritanceType = InheritanceType.get(pc);
|
||||
String parentEntityName = null;
|
||||
|
||||
switch (inheritanceType) {
|
||||
case NONE:
|
||||
class_mapping = MetadataTools.createEntity(xmlMappingData.getMainXmlMapping(), versionsEntityName, versionsTableName,
|
||||
schema, catalog, pc.getDiscriminatorValue());
|
||||
propertyMapper = new MultiPropertyMapper();
|
||||
|
||||
// Checking if there is a discriminator column
|
||||
if (pc.getDiscriminator() != null) {
|
||||
Element discriminator_element = class_mapping.addElement("discriminator");
|
||||
MetadataTools.addColumns(discriminator_element, pc.getDiscriminator().getColumnIterator());
|
||||
discriminator_element.addAttribute("type", pc.getDiscriminator().getType().getName());
|
||||
|
||||
// If so, there is some inheritance scheme -> using the persister hack.
|
||||
addPersisterHack(class_mapping);
|
||||
}
|
||||
|
||||
// Adding the id mapping
|
||||
class_mapping.add((Element) idMapper.getXmlMapping().clone());
|
||||
|
||||
// Adding the "revision type" property
|
||||
addRevisionType(class_mapping);
|
||||
|
||||
break;
|
||||
case SINGLE:
|
||||
String extendsEntityName = verEntCfg.getVersionsEntityName(pc.getSuperclass().getEntityName());
|
||||
class_mapping = MetadataTools.createSubclassEntity(xmlMappingData.getMainXmlMapping(), versionsEntityName,
|
||||
versionsTableName, schema, catalog, extendsEntityName, pc.getDiscriminatorValue());
|
||||
|
||||
addPersisterHack(class_mapping);
|
||||
|
||||
// The id and revision type is already mapped in the parent
|
||||
|
||||
// Getting the property mapper of the parent - when mapping properties, they need to be included
|
||||
parentEntityName = pc.getSuperclass().getEntityName();
|
||||
ExtendedPropertyMapper parentPropertyMapper = entitiesConfigurations.get(parentEntityName).getPropertyMapper();
|
||||
propertyMapper = new SubclassPropertyMapper(new MultiPropertyMapper(), parentPropertyMapper);
|
||||
|
||||
break;
|
||||
case JOINED:
|
||||
throw new MappingException("Joined inheritance strategy not supported for versioning!");
|
||||
case TABLE_PER_CLASS:
|
||||
throw new MappingException("Table-per-class inheritance strategy not supported for versioning!");
|
||||
default:
|
||||
throw new AssertionError("Impossible enum value.");
|
||||
}
|
||||
|
||||
// Mapping unjoined properties
|
||||
addProperties(class_mapping, (Iterator<Property>) pc.getUnjoinedPropertyIterator(), propertyMapper,
|
||||
versioningData, pc.getEntityName(), xmlMappingData,
|
||||
true);
|
||||
|
||||
// Creating and mapping joins (first pass)
|
||||
createJoins(pc, class_mapping, versioningData);
|
||||
addJoins(pc, propertyMapper, versioningData, pc.getEntityName(), xmlMappingData, true);
|
||||
|
||||
// Storing the generated configuration
|
||||
EntityConfiguration entityCfg = new EntityConfiguration(versionsEntityName, idMapper,
|
||||
propertyMapper, parentEntityName);
|
||||
entitiesConfigurations.put(pc.getEntityName(), entityCfg);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public void generateSecondPass(PersistentClass pc, PersistentClassVersioningData versioningData,
|
||||
EntityXmlMappingData xmlMappingData) {
|
||||
String entityName = pc.getEntityName();
|
||||
|
||||
CompositeMapperBuilder propertyMapper = entitiesConfigurations.get(entityName).getPropertyMapper();
|
||||
|
||||
// Mapping unjoined properties
|
||||
Element parent = xmlMappingData.getMainXmlMapping().getRootElement().element("class");
|
||||
if (parent == null) {
|
||||
parent = xmlMappingData.getMainXmlMapping().getRootElement().element("subclass");
|
||||
}
|
||||
|
||||
addProperties(parent, (Iterator<Property>) pc.getUnjoinedPropertyIterator(),
|
||||
propertyMapper, versioningData, entityName, xmlMappingData, false);
|
||||
|
||||
// Mapping joins (second pass)
|
||||
addJoins(pc, propertyMapper, versioningData, entityName, xmlMappingData, false);
|
||||
}
|
||||
|
||||
public Map<String, EntityConfiguration> getEntitiesConfigurations() {
|
||||
return entitiesConfigurations;
|
||||
}
|
||||
|
||||
// Getters for generators and configuration
|
||||
|
||||
BasicMetadataGenerator getBasicMetadataGenerator() {
|
||||
return basicMetadataGenerator;
|
||||
}
|
||||
|
||||
Configuration getCfg() {
|
||||
return cfg;
|
||||
}
|
||||
|
||||
GlobalConfiguration getGlobalCfg() {
|
||||
return globalCfg;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* 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.exception;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsException extends HibernateException {
|
||||
public VersionsException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public VersionsException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public VersionsException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* 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.query;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
|
||||
import org.hibernate.envers.exception.VersionsException;
|
||||
import org.hibernate.envers.query.criteria.VersionsCriterion;
|
||||
import org.hibernate.envers.query.order.VersionsOrder;
|
||||
import org.hibernate.envers.query.projection.VersionsProjection;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockMode;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
* @see org.hibernate.Criteria
|
||||
*/
|
||||
public interface VersionsQuery {
|
||||
List getResultList() throws VersionsException;
|
||||
|
||||
Object getSingleResult() throws VersionsException, NonUniqueResultException, NoResultException;
|
||||
|
||||
VersionsQuery add(VersionsCriterion criterion);
|
||||
|
||||
VersionsQuery addProjection(String function, String propertyName);
|
||||
|
||||
VersionsQuery addProjection(VersionsProjection projection);
|
||||
|
||||
VersionsQuery addOrder(String propertyName, boolean asc);
|
||||
|
||||
VersionsQuery addOrder(VersionsOrder order);
|
||||
|
||||
VersionsQuery setMaxResults(int maxResults);
|
||||
|
||||
VersionsQuery setFirstResult(int firstResult);
|
||||
|
||||
VersionsQuery setCacheable(boolean cacheable);
|
||||
|
||||
VersionsQuery setCacheRegion(String cacheRegion);
|
||||
|
||||
VersionsQuery setComment(String comment);
|
||||
|
||||
VersionsQuery setFlushMode(FlushMode flushMode);
|
||||
|
||||
VersionsQuery setCacheMode(CacheMode cacheMode);
|
||||
|
||||
VersionsQuery setTimeout(int timeout);
|
||||
|
||||
VersionsQuery setLockMode(LockMode lockMode);
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* 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.query;
|
||||
|
||||
import org.hibernate.envers.configuration.VersionsConfiguration;
|
||||
import org.hibernate.envers.query.impl.EntitiesAtRevisionQuery;
|
||||
import org.hibernate.envers.query.impl.RevisionsOfEntityQuery;
|
||||
import org.hibernate.envers.reader.VersionsReaderImplementor;
|
||||
import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull;
|
||||
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsQueryCreator {
|
||||
private final VersionsConfiguration verCfg;
|
||||
private final VersionsReaderImplementor versionsReaderImplementor;
|
||||
|
||||
public VersionsQueryCreator(VersionsConfiguration verCfg, VersionsReaderImplementor versionsReaderImplementor) {
|
||||
this.verCfg = verCfg;
|
||||
this.versionsReaderImplementor = versionsReaderImplementor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a query, which will return entities satisfying some conditions (specified later),
|
||||
* at a given revision.
|
||||
* @param c Class of the entities for which to query.
|
||||
* @param revision Revision number at which to execute the query.
|
||||
* @return A query for entities at a given revision, to which conditions can be added and which
|
||||
* can then be executed. The result of the query will be a list of entities (beans), unless a
|
||||
* projection is added.
|
||||
*/
|
||||
public VersionsQuery forEntitiesAtRevision(Class<?> c, Number revision) {
|
||||
checkNotNull(revision, "Entity revision");
|
||||
checkPositive(revision, "Entity revision");
|
||||
return new EntitiesAtRevisionQuery(verCfg, versionsReaderImplementor, c, revision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a query, which selects the revisions, at which the given entity was modified.
|
||||
* Unless an explicit projection is set, the result will be a list of three-element arrays, containing:
|
||||
* <ol>
|
||||
* <li>the entity instance</li>
|
||||
* <li>revision entity, corresponding to the revision at which the entity was modified. If no custom
|
||||
* revision entity is used, this will be an instance of {@link org.hibernate.envers.DefaultRevisionEntity}</li>
|
||||
* <li>type of the revision (an enum instance of class {@link org.hibernate.envers.RevisionType})</li>.
|
||||
* </ol>
|
||||
* Additional conditions that the results must satisfy may be specified.
|
||||
* @param c Class of the entities for which to query.
|
||||
* @param selectEntitiesOnly If true, instead of a list of three-element arrays, a list of entites will be
|
||||
* returned as a result of executing this query.
|
||||
* @param selectDeletedEntities If true, also revisions where entities were deleted will be returned. The additional
|
||||
* entities will have revision type "delete", and contain no data (all fields null), except for the id field.
|
||||
* @return A query for revisions at which instances of the given entity were modified, to which
|
||||
* conditions can be added (for example - a specific id of an entity of class <code>c</code>), and which
|
||||
* can then be executed. The results of the query will be sorted in ascending order by the revision number,
|
||||
* unless an order or projection is added.
|
||||
*/
|
||||
public VersionsQuery forRevisionsOfEntity(Class<?> c, boolean selectEntitiesOnly, boolean selectDeletedEntities) {
|
||||
return new RevisionsOfEntityQuery(verCfg, versionsReaderImplementor, c, selectEntitiesOnly,selectDeletedEntities);
|
||||
}
|
||||
}
|
|
@ -1,258 +0,0 @@
|
|||
/*
|
||||
* 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.query;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.hibernate.envers.query.criteria.AggregatedFieldVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.BetweenVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.IdentifierEqVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.InVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.LogicalVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.NotNullVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.NotVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.NullVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.PropertyVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.RelatedVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.SimpleVersionsExpression;
|
||||
import org.hibernate.envers.query.criteria.VersionsConjunction;
|
||||
import org.hibernate.envers.query.criteria.VersionsCriterion;
|
||||
import org.hibernate.envers.query.criteria.VersionsDisjunction;
|
||||
|
||||
import org.hibernate.criterion.MatchMode;
|
||||
|
||||
/**
|
||||
* TODO: ilike
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
* @see org.hibernate.criterion.Restrictions
|
||||
*/
|
||||
@SuppressWarnings({"JavaDoc"})
|
||||
public class VersionsRestrictions {
|
||||
private VersionsRestrictions() { }
|
||||
|
||||
/**
|
||||
* Apply an "equal" constraint to the identifier property.
|
||||
*/
|
||||
public static VersionsCriterion idEq(Object value) {
|
||||
return new IdentifierEqVersionsExpression(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an "equal" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion eq(String propertyName, Object value) {
|
||||
return new SimpleVersionsExpression(propertyName, value, "=");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "not equal" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion ne(String propertyName, Object value) {
|
||||
return new SimpleVersionsExpression(propertyName, value, "<>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an "equal" constraint on an id of a related entity
|
||||
*/
|
||||
public static VersionsCriterion relatedIdEq(String propertyName, Object id) {
|
||||
return new RelatedVersionsExpression(propertyName, id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "not equal" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion relatedIdNe(String propertyName, Object id) {
|
||||
return new RelatedVersionsExpression(propertyName, id, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "like" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion like(String propertyName, Object value) {
|
||||
return new SimpleVersionsExpression(propertyName, value, " like ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "like" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion like(String propertyName, String value, MatchMode matchMode) {
|
||||
return new SimpleVersionsExpression(propertyName, matchMode.toMatchString(value), " like " );
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "greater than" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion gt(String propertyName, Object value) {
|
||||
return new SimpleVersionsExpression(propertyName, value, ">");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "less than" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion lt(String propertyName, Object value) {
|
||||
return new SimpleVersionsExpression(propertyName, value, "<");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "less than or equal" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion le(String propertyName, Object value) {
|
||||
return new SimpleVersionsExpression(propertyName, value, "<=");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "greater than or equal" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion ge(String propertyName, Object value) {
|
||||
return new SimpleVersionsExpression(propertyName, value, ">=");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "between" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion between(String propertyName, Object lo, Object hi) {
|
||||
return new BetweenVersionsExpression(propertyName, lo, hi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an "in" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion in(String propertyName, Object[] values) {
|
||||
return new InVersionsExpression(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an "in" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion in(String propertyName, Collection values) {
|
||||
return new InVersionsExpression(propertyName, values.toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an "is null" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion isNull(String propertyName) {
|
||||
return new NullVersionsExpression(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an "equal" constraint to two properties
|
||||
*/
|
||||
public static VersionsCriterion eqProperty(String propertyName, String otherPropertyName) {
|
||||
return new PropertyVersionsExpression(propertyName, otherPropertyName, "=");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "not equal" constraint to two properties
|
||||
*/
|
||||
public static VersionsCriterion neProperty(String propertyName, String otherPropertyName) {
|
||||
return new PropertyVersionsExpression(propertyName, otherPropertyName, "<>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "less than" constraint to two properties
|
||||
*/
|
||||
public static VersionsCriterion ltProperty(String propertyName, String otherPropertyName) {
|
||||
return new PropertyVersionsExpression(propertyName, otherPropertyName, "<");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "less than or equal" constraint to two properties
|
||||
*/
|
||||
public static VersionsCriterion leProperty(String propertyName, String otherPropertyName) {
|
||||
return new PropertyVersionsExpression(propertyName, otherPropertyName, "<=");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "greater than" constraint to two properties
|
||||
*/
|
||||
public static VersionsCriterion gtProperty(String propertyName, String otherPropertyName) {
|
||||
return new PropertyVersionsExpression(propertyName, otherPropertyName, ">");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "greater than or equal" constraint to two properties
|
||||
*/
|
||||
public static VersionsCriterion geProperty(String propertyName, String otherPropertyName) {
|
||||
return new PropertyVersionsExpression(propertyName, otherPropertyName, ">=");
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an "is not null" constraint to the named property
|
||||
*/
|
||||
public static VersionsCriterion isNotNull(String propertyName) {
|
||||
return new NotNullVersionsExpression(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the conjuction of two expressions
|
||||
*/
|
||||
public static VersionsCriterion and(VersionsCriterion lhs, VersionsCriterion rhs) {
|
||||
return new LogicalVersionsExpression(lhs, rhs, "and");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the disjuction of two expressions
|
||||
*/
|
||||
public static VersionsCriterion or(VersionsCriterion lhs, VersionsCriterion rhs) {
|
||||
return new LogicalVersionsExpression(lhs, rhs, "or");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the negation of an expression
|
||||
*/
|
||||
public static VersionsCriterion not(VersionsCriterion expression) {
|
||||
return new NotVersionsExpression(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Group expressions together in a single conjunction (A and B and C...)
|
||||
*/
|
||||
public static VersionsConjunction conjunction() {
|
||||
return new VersionsConjunction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Group expressions together in a single disjunction (A or B or C...)
|
||||
*/
|
||||
public static VersionsDisjunction disjunction() {
|
||||
return new VersionsDisjunction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "maximalize property" constraint.
|
||||
*/
|
||||
public static AggregatedFieldVersionsExpression maximizeProperty(String propertyName) {
|
||||
return new AggregatedFieldVersionsExpression(propertyName,
|
||||
AggregatedFieldVersionsExpression.AggregatedMode.MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a "minimize property" constraint.
|
||||
*/
|
||||
public static AggregatedFieldVersionsExpression minimizeProperty(String propertyName) {
|
||||
return new AggregatedFieldVersionsExpression(propertyName,
|
||||
AggregatedFieldVersionsExpression.AggregatedMode.MIN);
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* 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.query.criteria;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.envers.configuration.VersionsConfiguration;
|
||||
import org.hibernate.envers.tools.query.Parameters;
|
||||
import org.hibernate.envers.tools.query.QueryBuilder;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsConjunction implements VersionsCriterion, ExtendableCriterion {
|
||||
private List<VersionsCriterion> criterions;
|
||||
|
||||
public VersionsConjunction() {
|
||||
criterions = new ArrayList<VersionsCriterion>();
|
||||
}
|
||||
|
||||
public VersionsConjunction add(VersionsCriterion criterion) {
|
||||
criterions.add(criterion);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void addToQuery(VersionsConfiguration verCfg, String entityName, QueryBuilder qb, Parameters parameters) {
|
||||
Parameters andParameters = parameters.addSubParameters(Parameters.AND);
|
||||
|
||||
for (VersionsCriterion criterion : criterions) {
|
||||
criterion.addToQuery(verCfg, entityName, qb, andParameters);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* 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.query.criteria;
|
||||
|
||||
import org.hibernate.envers.configuration.VersionsConfiguration;
|
||||
import org.hibernate.envers.tools.query.Parameters;
|
||||
import org.hibernate.envers.tools.query.QueryBuilder;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public interface VersionsCriterion {
|
||||
void addToQuery(VersionsConfiguration verCfg, String entityName, QueryBuilder qb, Parameters parameters);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* 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.query.criteria;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.envers.configuration.VersionsConfiguration;
|
||||
import org.hibernate.envers.tools.query.Parameters;
|
||||
import org.hibernate.envers.tools.query.QueryBuilder;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsDisjunction implements VersionsCriterion, ExtendableCriterion {
|
||||
private List<VersionsCriterion> criterions;
|
||||
|
||||
public VersionsDisjunction() {
|
||||
criterions = new ArrayList<VersionsCriterion>();
|
||||
}
|
||||
|
||||
public VersionsDisjunction add(VersionsCriterion criterion) {
|
||||
criterions.add(criterion);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void addToQuery(VersionsConfiguration verCfg, String entityName, QueryBuilder qb, Parameters parameters) {
|
||||
Parameters orParameters = parameters.addSubParameters(Parameters.OR);
|
||||
|
||||
for (VersionsCriterion criterion : criterions) {
|
||||
criterion.addToQuery(verCfg, entityName, qb, orParameters);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* 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.query.order;
|
||||
|
||||
import org.hibernate.envers.configuration.VersionsConfiguration;
|
||||
import org.hibernate.envers.tools.Pair;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public interface VersionsOrder {
|
||||
/**
|
||||
* @param verCfg Configuration.
|
||||
* @return A pair: (property name, ascending?).
|
||||
*/
|
||||
Pair<String, Boolean> getData(VersionsConfiguration verCfg);
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* 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.query.projection;
|
||||
|
||||
import org.hibernate.envers.configuration.VersionsConfiguration;
|
||||
import org.hibernate.envers.tools.Triple;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public interface VersionsProjection {
|
||||
/**
|
||||
*
|
||||
* @param verCfg Configuration.
|
||||
* @return A triple: (function name - possibly null, property name, add distinct?).
|
||||
*/
|
||||
Triple<String, String, Boolean> getData(VersionsConfiguration verCfg);
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* 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.reader;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.persistence.NoResultException;
|
||||
|
||||
import org.hibernate.envers.configuration.VersionsConfiguration;
|
||||
import org.hibernate.envers.exception.NotVersionedException;
|
||||
import org.hibernate.envers.exception.RevisionDoesNotExistException;
|
||||
import org.hibernate.envers.exception.VersionsException;
|
||||
import org.hibernate.envers.query.RevisionProperty;
|
||||
import org.hibernate.envers.query.VersionsQueryCreator;
|
||||
import org.hibernate.envers.query.VersionsRestrictions;
|
||||
import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull;
|
||||
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
|
||||
|
||||
import org.hibernate.NonUniqueResultException;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsReaderImpl implements VersionsReaderImplementor {
|
||||
private final VersionsConfiguration verCfg;
|
||||
private final SessionImplementor sessionImplementor;
|
||||
private final Session session;
|
||||
private final FirstLevelCache firstLevelCache;
|
||||
|
||||
public VersionsReaderImpl(VersionsConfiguration verCfg, Session session,
|
||||
SessionImplementor sessionImplementor) {
|
||||
this.verCfg = verCfg;
|
||||
this.sessionImplementor = sessionImplementor;
|
||||
this.session = session;
|
||||
|
||||
firstLevelCache = new FirstLevelCache();
|
||||
}
|
||||
|
||||
private void checkSession() {
|
||||
if (!session.isOpen()) {
|
||||
throw new IllegalStateException("The associated entity manager is closed!");
|
||||
}
|
||||
}
|
||||
|
||||
public SessionImplementor getSessionImplementor() {
|
||||
return sessionImplementor;
|
||||
}
|
||||
|
||||
public Session getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public FirstLevelCache getFirstLevelCache() {
|
||||
return firstLevelCache;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T> T find(Class<T> cls, Object primaryKey, Number revision) throws
|
||||
IllegalArgumentException, NotVersionedException, IllegalStateException {
|
||||
checkNotNull(cls, "Entity class");
|
||||
checkNotNull(primaryKey, "Primary key");
|
||||
checkNotNull(revision, "Entity revision");
|
||||
checkPositive(revision, "Entity revision");
|
||||
checkSession();
|
||||
|
||||
String entityName = cls.getName();
|
||||
|
||||
if (!verCfg.getEntCfg().isVersioned(entityName)) {
|
||||
throw new NotVersionedException(entityName, entityName + " is not versioned!");
|
||||
}
|
||||
|
||||
if (firstLevelCache.contains(entityName, revision, primaryKey)) {
|
||||
return (T) firstLevelCache.get(entityName, revision, primaryKey);
|
||||
}
|
||||
|
||||
Object result;
|
||||
try {
|
||||
// The result is put into the cache by the entity instantiator called from the query
|
||||
result = createQuery().forEntitiesAtRevision(cls, revision)
|
||||
.add(VersionsRestrictions.idEq(primaryKey)).getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
result = null;
|
||||
} catch (NonUniqueResultException e) {
|
||||
throw new VersionsException(e);
|
||||
}
|
||||
|
||||
return (T) result;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public List<Number> getRevisions(Class<?> cls, Object primaryKey)
|
||||
throws IllegalArgumentException, NotVersionedException, IllegalStateException {
|
||||
// todo: if a class is not versioned from the beginning, there's a missing ADD rev - what then?
|
||||
checkNotNull(cls, "Entity class");
|
||||
checkNotNull(primaryKey, "Primary key");
|
||||
checkSession();
|
||||
|
||||
String entityName = cls.getName();
|
||||
|
||||
if (!verCfg.getEntCfg().isVersioned(entityName)) {
|
||||
throw new NotVersionedException(entityName, entityName + " is not versioned!");
|
||||
}
|
||||
|
||||
return createQuery().forRevisionsOfEntity(cls, false, true)
|
||||
.addProjection(RevisionProperty.revisionNumber())
|
||||
.add(VersionsRestrictions.idEq(primaryKey))
|
||||
.getResultList();
|
||||
}
|
||||
|
||||
public Date getRevisionDate(Number revision) throws IllegalArgumentException, RevisionDoesNotExistException,
|
||||
IllegalStateException{
|
||||
checkNotNull(revision, "Entity revision");
|
||||
checkPositive(revision, "Entity revision");
|
||||
checkSession();
|
||||
|
||||
Query query = verCfg.getRevisionInfoQueryCreator().getRevisionDateQuery(session, revision);
|
||||
|
||||
try {
|
||||
Long timestamp = (Long) query.uniqueResult();
|
||||
if (timestamp == null) {
|
||||
throw new RevisionDoesNotExistException(revision);
|
||||
}
|
||||
|
||||
return new Date(timestamp);
|
||||
} catch (NonUniqueResultException e) {
|
||||
throw new VersionsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Number getRevisionNumberForDate(Date date) {
|
||||
checkNotNull(date, "Date of revision");
|
||||
checkSession();
|
||||
|
||||
Query query = verCfg.getRevisionInfoQueryCreator().getRevisionNumberForDateQuery(session, date);
|
||||
|
||||
try {
|
||||
Number res = (Number) query.uniqueResult();
|
||||
if (res == null) {
|
||||
throw new RevisionDoesNotExistException(date);
|
||||
}
|
||||
|
||||
return res;
|
||||
} catch (NonUniqueResultException e) {
|
||||
throw new VersionsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T> T findRevision(Class<T> revisionEntityClass, Number revision) throws IllegalArgumentException,
|
||||
RevisionDoesNotExistException, IllegalStateException {
|
||||
checkNotNull(revision, "Entity revision");
|
||||
checkPositive(revision, "Entity revision");
|
||||
checkSession();
|
||||
|
||||
Query query = verCfg.getRevisionInfoQueryCreator().getRevisionQuery(session, revision);
|
||||
|
||||
try {
|
||||
T revisionData = (T) query.uniqueResult();
|
||||
|
||||
if (revisionData == null) {
|
||||
throw new RevisionDoesNotExistException(revision);
|
||||
}
|
||||
|
||||
return revisionData;
|
||||
} catch (NonUniqueResultException e) {
|
||||
throw new VersionsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public VersionsQueryCreator createQuery() {
|
||||
return new VersionsQueryCreator(verCfg, this);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* 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.reader;
|
||||
|
||||
import org.hibernate.envers.AuditReader;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
|
||||
/**
|
||||
* An interface exposed by a VersionsReader to library-facing classes.
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public interface VersionsReaderImplementor extends AuditReader {
|
||||
SessionImplementor getSessionImplementor();
|
||||
Session getSession();
|
||||
FirstLevelCache getFirstLevelCache();
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
/*
|
||||
* 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.synchronization;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import javax.transaction.Synchronization;
|
||||
|
||||
import org.hibernate.envers.revisioninfo.RevisionInfoGenerator;
|
||||
import org.hibernate.envers.synchronization.work.VersionsWorkUnit;
|
||||
import org.hibernate.envers.tools.Pair;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.event.EventSource;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsSync implements Synchronization {
|
||||
private final RevisionInfoGenerator revisionInfoGenerator;
|
||||
private final VersionsSyncManager manager;
|
||||
private final EventSource session;
|
||||
|
||||
private final Transaction transaction;
|
||||
private final LinkedList<VersionsWorkUnit> workUnits;
|
||||
private final Queue<VersionsWorkUnit> undoQueue;
|
||||
private final Map<Pair<String, Object>, VersionsWorkUnit> usedIds;
|
||||
|
||||
private Object revisionData;
|
||||
|
||||
public VersionsSync(VersionsSyncManager manager, EventSource session, RevisionInfoGenerator revisionInfoGenerator) {
|
||||
this.manager = manager;
|
||||
this.session = session;
|
||||
this.revisionInfoGenerator = revisionInfoGenerator;
|
||||
|
||||
transaction = session.getTransaction();
|
||||
workUnits = new LinkedList<VersionsWorkUnit>();
|
||||
undoQueue = new LinkedList<VersionsWorkUnit>();
|
||||
usedIds = new HashMap<Pair<String, Object>, VersionsWorkUnit>();
|
||||
}
|
||||
|
||||
private void removeWorkUnit(VersionsWorkUnit vwu) {
|
||||
workUnits.remove(vwu);
|
||||
if (vwu.isPerformed()) {
|
||||
// If this work unit has already been performed, it must be deleted (undone) first.
|
||||
undoQueue.offer(vwu);
|
||||
}
|
||||
}
|
||||
|
||||
public void addWorkUnit(VersionsWorkUnit vwu) {
|
||||
if (vwu.containsWork()) {
|
||||
Object entityId = vwu.getEntityId();
|
||||
|
||||
if (entityId == null) {
|
||||
// Just adding the work unit - it's not associated with any persistent entity.
|
||||
workUnits.offer(vwu);
|
||||
} else {
|
||||
String entityName = vwu.getEntityName();
|
||||
Pair<String, Object> usedIdsKey = Pair.make(entityName, entityId);
|
||||
|
||||
if (usedIds.containsKey(usedIdsKey)) {
|
||||
VersionsWorkUnit other = usedIds.get(usedIdsKey);
|
||||
|
||||
// The entity with entityId has two work units; checking which one should be kept.
|
||||
switch (vwu.dispatch(other)) {
|
||||
case FIRST:
|
||||
// Simply not adding the second
|
||||
break;
|
||||
|
||||
case SECOND:
|
||||
removeWorkUnit(other);
|
||||
usedIds.put(usedIdsKey, vwu);
|
||||
workUnits.offer(vwu);
|
||||
break;
|
||||
|
||||
case NONE:
|
||||
removeWorkUnit(other);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
usedIds.put(usedIdsKey, vwu);
|
||||
workUnits.offer(vwu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void executeInSession(Session session) {
|
||||
if (revisionData == null) {
|
||||
revisionData = revisionInfoGenerator.generate(session);
|
||||
}
|
||||
|
||||
VersionsWorkUnit vwu;
|
||||
|
||||
// First undoing any performed work units
|
||||
while ((vwu = undoQueue.poll()) != null) {
|
||||
vwu.undo(session);
|
||||
}
|
||||
|
||||
while ((vwu = workUnits.poll()) != null) {
|
||||
vwu.perform(session, revisionData);
|
||||
}
|
||||
}
|
||||
|
||||
public void beforeCompletion() {
|
||||
if (workUnits.size() == 0 && undoQueue.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
|
||||
if (FlushMode.isManualFlushMode(session.getFlushMode()) || session.isClosed()) {
|
||||
Session temporarySession = null;
|
||||
try {
|
||||
temporarySession = session.getFactory().openTemporarySession();
|
||||
|
||||
executeInSession(temporarySession);
|
||||
|
||||
temporarySession.flush();
|
||||
} finally {
|
||||
if (temporarySession != null) {
|
||||
temporarySession.close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
executeInSession(session);
|
||||
|
||||
// Explicity flushing the session, as the auto-flush may have already happened.
|
||||
session.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void afterCompletion(int i) {
|
||||
manager.remove(transaction);
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* 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.synchronization;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.envers.revisioninfo.RevisionInfoGenerator;
|
||||
import org.hibernate.envers.tools.ConcurrentReferenceHashMap;
|
||||
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.event.EventSource;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public class VersionsSyncManager {
|
||||
private final Map<Transaction, VersionsSync> versionsSyncs;
|
||||
private final RevisionInfoGenerator revisionInfoGenerator;
|
||||
|
||||
public VersionsSyncManager(RevisionInfoGenerator revisionInfoGenerator) {
|
||||
versionsSyncs = new ConcurrentReferenceHashMap<Transaction, VersionsSync>(10,
|
||||
ConcurrentReferenceHashMap.ReferenceType.WEAK,
|
||||
ConcurrentReferenceHashMap.ReferenceType.STRONG);
|
||||
|
||||
this.revisionInfoGenerator = revisionInfoGenerator;
|
||||
}
|
||||
|
||||
public VersionsSync get(EventSource session) {
|
||||
Transaction transaction = session.getTransaction();
|
||||
|
||||
VersionsSync verSync = versionsSyncs.get(transaction);
|
||||
if (verSync == null) {
|
||||
verSync = new VersionsSync(this, session, revisionInfoGenerator);
|
||||
versionsSyncs.put(transaction, verSync);
|
||||
|
||||
transaction.registerSynchronization(verSync);
|
||||
}
|
||||
|
||||
return verSync;
|
||||
}
|
||||
|
||||
public void remove(Transaction transaction) {
|
||||
versionsSyncs.remove(transaction);
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* 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.synchronization.work;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.envers.RevisionType;
|
||||
import org.hibernate.envers.configuration.VersionsConfiguration;
|
||||
import org.hibernate.envers.configuration.VersionsEntitiesConfiguration;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public abstract class AbstractVersionsWorkUnit implements VersionsWorkUnit {
|
||||
protected final VersionsConfiguration verCfg;
|
||||
protected final Serializable id;
|
||||
|
||||
private final String entityName;
|
||||
|
||||
private Object performedData;
|
||||
|
||||
protected AbstractVersionsWorkUnit(String entityName, VersionsConfiguration verCfg, Serializable id) {
|
||||
this.verCfg = verCfg;
|
||||
this.id = id;
|
||||
this.entityName = entityName;
|
||||
}
|
||||
|
||||
protected void fillDataWithId(Map<String, Object> data, Object revision, RevisionType revisionType) {
|
||||
VersionsEntitiesConfiguration entitiesCfg = verCfg.getVerEntCfg();
|
||||
|
||||
Map<String, Object> originalId = new HashMap<String, Object>();
|
||||
originalId.put(entitiesCfg.getRevisionPropName(), revision);
|
||||
|
||||
verCfg.getEntCfg().get(getEntityName()).getIdMapper().mapToMapFromId(originalId, id);
|
||||
data.put(entitiesCfg.getRevisionTypePropName(), revisionType);
|
||||
data.put(entitiesCfg.getOriginalIdPropName(), originalId);
|
||||
}
|
||||
|
||||
public Object getEntityId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean isPerformed() {
|
||||
return performedData != null;
|
||||
}
|
||||
|
||||
public String getEntityName() {
|
||||
return entityName;
|
||||
}
|
||||
|
||||
protected void setPerformed(Object performedData) {
|
||||
this.performedData = performedData;
|
||||
}
|
||||
|
||||
public void undo(Session session) {
|
||||
if (isPerformed()) {
|
||||
session.delete(verCfg.getVerEntCfg().getVersionsEntityName(getEntityName()), performedData);
|
||||
session.flush();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* 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.synchronization.work;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
*/
|
||||
public interface VersionsWorkUnit extends KeepCheckVisitor, KeepCheckDispatcher {
|
||||
Object getEntityId();
|
||||
String getEntityName();
|
||||
|
||||
boolean containsWork();
|
||||
|
||||
boolean isPerformed();
|
||||
|
||||
void perform(Session session, Object revisionData);
|
||||
void undo(Session session);
|
||||
}
|
Loading…
Reference in New Issue