Hibernate SVN: r17819 - core/trunk/parent.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-10-22 08:04:02 -0400 (Thu, 22 Oct 2009)
New Revision: 17819
Modified:
core/trunk/parent/pom.xml
Log:
changed the dependecy definitions for the postgres profiles. 'jdbc3' is in the postgres sense no classifier. Or if i is they don't package the driver in the right way for maven
Modified: core/trunk/parent/pom.xml
===================================================================
--- core/trunk/parent/pom.xml 2009-10-22 11:10:31 UTC (rev 17818)
+++ core/trunk/parent/pom.xml 2009-10-22 12:04:02 UTC (rev 17819)
@@ -570,8 +570,7 @@
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
- <version>8.2-504</version>
- <classifier>jdbc3</classifier>
+ <version>8.2-504.jdbc3</version>
</dependency>
</dependencies>
<properties>
@@ -591,8 +590,7 @@
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
- <version>8.2-504</version>
- <classifier>jdbc3</classifier>
+ <version>8.2-504.jdbc3</version>
</dependency>
</dependencies>
<properties>
14 years, 6 months
Hibernate SVN: r17818 - in core/trunk/annotations/src: test/java/org/hibernate/test/annotations/beanvalidation and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-10-22 07:10:31 -0400 (Thu, 22 Oct 2009)
New Revision: 17818
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationGroupsTest.java
Log:
HHH-4513
Made sure hibernate.validator.apply_to_ddl property is honored
Also changed BeanValidationGroupsTest to work against other databases than HSQLDB
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-10-22 10:02:12 UTC (rev 17817)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-10-22 11:10:31 UTC (rev 17818)
@@ -95,15 +95,15 @@
*/
public class AnnotationConfiguration extends Configuration {
private Logger log = LoggerFactory.getLogger( AnnotationConfiguration.class );
-
+
/**
* Class name of the class needed to enable Search.
*/
private static final String SEARCH_STARTUP_CLASS = "org.hibernate.search.event.EventListenerRegister";
-
+
/**
* Method to call to enable Search.
- */
+ */
private static final String SEARCH_STARTUP_METHOD = "enableHibernateSearch";
static {
@@ -113,7 +113,7 @@
public static final String ARTEFACT = "hibernate.mapping.precedence";
public static final String DEFAULT_PRECEDENCE = "hbm, class";
- private Map<String,IdGenerator> namedGenerators;
+ private Map<String, IdGenerator> namedGenerators;
private Map<String, Map<String, Join>> joins;
private Map<String, AnnotatedClassType> classTypes;
private Set<String> defaultNamedQueryNames;
@@ -148,9 +148,11 @@
//TODO remove embeddable
List<XClass> copy = new ArrayList<XClass>( original );
//for each class, copy all the relevant hierarchy
- for (XClass clazz : original) {
+ for ( XClass clazz : original ) {
XClass superClass = clazz.getSuperclass();
- while ( superClass != null && !reflectionManager.equals( superClass, Object.class ) && !copy.contains( superClass ) ) {
+ while ( superClass != null && !reflectionManager.equals( superClass, Object.class ) && !copy.contains(
+ superClass
+ ) ) {
if ( superClass.isAnnotationPresent( Entity.class )
|| superClass.isAnnotationPresent( MappedSuperclass.class ) ) {
copy.add( superClass );
@@ -168,7 +170,9 @@
}
private void orderHierarchy(List<XClass> copy, List<XClass> newList, List<XClass> original, XClass clazz) {
- if ( clazz == null || reflectionManager.equals( clazz, Object.class ) ) return;
+ if ( clazz == null || reflectionManager.equals( clazz, Object.class ) ) {
+ return;
+ }
//process superclass first
orderHierarchy( copy, newList, original, clazz.getSuperclass() );
if ( original.contains( clazz ) ) {
@@ -183,6 +187,7 @@
* Read a mapping from the class annotation metadata (JSR 175).
*
* @param persistentClass the mapped class
+ *
* @return the configuration object
*/
public AnnotationConfiguration addAnnotatedClass(Class persistentClass) throws MappingException {
@@ -191,7 +196,7 @@
annotatedClasses.add( persistentXClass );
return this;
}
- catch (MappingException me) {
+ catch ( MappingException me ) {
log.error( "Could not compile the mapping annotations", me );
throw me;
}
@@ -201,6 +206,7 @@
* Read package level metadata
*
* @param packageName java package name
+ *
* @return the configuration object
*/
public AnnotationConfiguration addPackage(String packageName) throws MappingException {
@@ -209,7 +215,7 @@
AnnotationBinder.bindPackage( packageName, createExtendedMappings() );
return this;
}
- catch (MappingException me) {
+ catch ( MappingException me ) {
log.error( "Could not compile the mapping annotations", me );
throw me;
}
@@ -255,7 +261,7 @@
setEntityResolver( new EJB3DTDEntityResolver() );
anyMetaDefs = new HashMap<String, AnyMetaDef>();
reflectionManager = new JavaReflectionManager();
- ((MetadataProviderInjector) reflectionManager).setMetadataProvider( new JPAMetadataProvider() );
+ ( ( MetadataProviderInjector ) reflectionManager ).setMetadataProvider( new JPAMetadataProvider() );
}
@@ -265,7 +271,7 @@
//build annotatedClassEntities
{
List<XClass> tempAnnotatedClasses = new ArrayList<XClass>( annotatedClasses.size() );
- for (XClass clazz : annotatedClasses) {
+ for ( XClass clazz : annotatedClasses ) {
if ( clazz.isAnnotationPresent( Entity.class ) ) {
annotatedClassEntities.put( clazz.getName(), clazz );
tempAnnotatedClasses.add( clazz );
@@ -283,22 +289,26 @@
AnnotationBinder.bindDefaults( createExtendedMappings() );
isDefaultProcessed = true;
}
-
+
//process entities
- if ( precedence == null ) precedence = getProperties().getProperty( ARTEFACT );
- if ( precedence == null ) precedence = DEFAULT_PRECEDENCE;
+ if ( precedence == null ) {
+ precedence = getProperties().getProperty( ARTEFACT );
+ }
+ if ( precedence == null ) {
+ precedence = DEFAULT_PRECEDENCE;
+ }
StringTokenizer precedences = new StringTokenizer( precedence, ",; ", false );
if ( !precedences.hasMoreElements() ) {
throw new MappingException( ARTEFACT + " cannot be empty: " + precedence );
}
while ( precedences.hasMoreElements() ) {
- String artifact = (String) precedences.nextElement();
+ String artifact = ( String ) precedences.nextElement();
removeConflictedArtifact( artifact );
processArtifactsOfType( artifact );
}
int cacheNbr = caches.size();
- for (int index = 0; index < cacheNbr; index++) {
+ for ( int index = 0; index < cacheNbr; index++ ) {
CacheHolder cacheHolder = caches.get( index );
if ( cacheHolder.isClass ) {
super.setCacheConcurrencyStrategy(
@@ -314,7 +324,7 @@
inSecondPass = true;
Iterator iter = secondPasses.iterator();
while ( iter.hasNext() ) {
- SecondPass sp = (SecondPass) iter.next();
+ SecondPass sp = ( SecondPass ) iter.next();
//do the second pass of simple value types first and remove them
if ( sp instanceof SetSimpleValueTypeSecondPass ) {
sp.doSecondPass( classes );
@@ -324,7 +334,7 @@
processFkSecondPassInOrder();
iter = secondPasses.iterator();
while ( iter.hasNext() ) {
- SecondPass sp = (SecondPass) iter.next();
+ SecondPass sp = ( SecondPass ) iter.next();
//do the second pass of fk before the others and remove them
if ( sp instanceof CreateKeySecondPass ) {
sp.doSecondPass( classes );
@@ -334,7 +344,7 @@
iter = secondPasses.iterator();
while ( iter.hasNext() ) {
- SecondPass sp = (SecondPass) iter.next();
+ SecondPass sp = ( SecondPass ) iter.next();
//do the SecondaryTable second pass before any association becasue associations can be built on joins
if ( sp instanceof SecondaryTableSecondPass ) {
sp.doSecondPass( classes );
@@ -344,9 +354,9 @@
super.secondPassCompile();
inSecondPass = false;
}
- catch (RecoverableException e) {
+ catch ( RecoverableException e ) {
//the exception was not recoverable after all
- throw (RuntimeException) e.getCause();
+ throw ( RuntimeException ) e.getCause();
}
Iterator tables = tableUniqueConstraints.entrySet().iterator();
Table table;
@@ -354,42 +364,59 @@
String keyName;
int uniqueIndexPerTable;
while ( tables.hasNext() ) {
- entry = (Map.Entry) tables.next();
- table = (Table) entry.getKey();
- List<String[]> uniqueConstraints = (List<String[]>) entry.getValue();
+ entry = ( Map.Entry ) tables.next();
+ table = ( Table ) entry.getKey();
+ List<String[]> uniqueConstraints = ( List<String[]> ) entry.getValue();
uniqueIndexPerTable = 0;
- for (String[] columnNames : uniqueConstraints) {
+ for ( String[] columnNames : uniqueConstraints ) {
keyName = "key" + uniqueIndexPerTable++;
buildUniqueKeyFromColumnNames( columnNames, table, keyName );
}
}
+ applyConstraintsToDDL();
+ }
+
+ private void applyConstraintsToDDL() {
boolean applyOnDdl = getProperties().getProperty(
- "hibernate.validator.apply_to_ddl", //org.hibernate.validator.Environment.APPLY_TO_DDL
- "true" )
+ "hibernate.validator.apply_to_ddl",
+ "true"
+ )
.equalsIgnoreCase( "true" );
+ if ( !applyOnDdl ) {
+ return; // nothing to do in this case
+ }
+ applyHibernateValidatorLegacyConstraintsOnDDL();
+ applyBeanValidationConstraintsOnDDL();
+ }
+
+ private void applyHibernateValidatorLegacyConstraintsOnDDL() {
//TODO search for the method only once and cache it?
Constructor validatorCtr = null;
Method applyMethod = null;
try {
- Class classValidator = ReflectHelper.classForName( "org.hibernate.validator.ClassValidator", this.getClass() );
- Class messageInterpolator = ReflectHelper.classForName( "org.hibernate.validator.MessageInterpolator", this.getClass() );
+ Class classValidator = ReflectHelper.classForName(
+ "org.hibernate.validator.ClassValidator", this.getClass()
+ );
+ Class messageInterpolator = ReflectHelper.classForName(
+ "org.hibernate.validator.MessageInterpolator", this.getClass()
+ );
validatorCtr = classValidator.getDeclaredConstructor(
Class.class, ResourceBundle.class, messageInterpolator, Map.class, ReflectionManager.class
);
applyMethod = classValidator.getMethod( "apply", PersistentClass.class );
}
- catch (ClassNotFoundException e) {
+ catch ( ClassNotFoundException e ) {
if ( !isValidatorNotPresentLogged ) {
log.info( "Hibernate Validator not found: ignoring" );
}
isValidatorNotPresentLogged = true;
}
- catch (NoSuchMethodException e) {
+ catch ( NoSuchMethodException e ) {
throw new AnnotationException( e );
}
- if ( applyMethod != null && applyOnDdl ) {
- for (PersistentClass persistentClazz : (Collection<PersistentClass>) classes.values()) {
+ if ( applyMethod != null ) {
+ for ( PersistentClass persistentClazz : ( Collection<PersistentClass> ) classes.values() ) {
//integrate the validate framework
String className = persistentClazz.getClassName();
if ( StringHelper.isNotEmpty( className ) ) {
@@ -399,17 +426,16 @@
);
applyMethod.invoke( validator, persistentClazz );
}
- catch (Exception e) {
+ catch ( Exception e ) {
log.warn( "Unable to apply constraints on DDL for " + className, e );
}
}
}
}
- applyDDLOnBeanValidation( (Collection<PersistentClass>) classes.values(), getProperties() );
}
- private void applyDDLOnBeanValidation(Collection<PersistentClass> persistentClasses, Properties properties) {
- BeanValidationActivator.applyDDL( persistentClasses, properties );
+ private void applyBeanValidationConstraintsOnDDL() {
+ BeanValidationActivator.applyDDL( ( Collection<PersistentClass> ) classes.values(), getProperties() );
}
/**
@@ -420,16 +446,16 @@
private void processFkSecondPassInOrder() {
log.debug( "processing fk mappings (*ToOne and JoinedSubclass)" );
List<FkSecondPass> fkSecondPasses = getFKSecondPassesOnly();
-
- if (fkSecondPasses.size() == 0) {
+
+ if ( fkSecondPasses.size() == 0 ) {
return; // nothing to do here
}
-
+
// split FkSecondPass instances into primary key and non primary key FKs.
// While doing so build a map of class names to FkSecondPass instances depending on this class.
Map<String, Set<FkSecondPass>> isADependencyOf = new HashMap<String, Set<FkSecondPass>>();
List endOfQueueFkSecondPasses = new ArrayList( fkSecondPasses.size() );
- for (FkSecondPass sp : fkSecondPasses) {
+ for ( FkSecondPass sp : fkSecondPasses ) {
if ( sp.isInPrimaryKey() ) {
String referenceEntityName = sp.getReferencedEntityName();
PersistentClass classMapping = getClassMapping( referenceEntityName );
@@ -443,19 +469,19 @@
endOfQueueFkSecondPasses.add( sp );
}
}
-
+
// using the isADependencyOf map we order the FkSecondPass recursively instances into the right order for processing
List<FkSecondPass> orderedFkSecondPasses = new ArrayList( fkSecondPasses.size() );
- for (String tableName : isADependencyOf.keySet()) {
- buildRecursiveOrderedFkSecondPasses(orderedFkSecondPasses, isADependencyOf, tableName, tableName);
+ for ( String tableName : isADependencyOf.keySet() ) {
+ buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, isADependencyOf, tableName, tableName );
}
-
+
// process the ordered FkSecondPasses
for ( FkSecondPass sp : orderedFkSecondPasses ) {
sp.doSecondPass( classes );
}
- processEndOfQueue(endOfQueueFkSecondPasses);
+ processEndOfQueue( endOfQueueFkSecondPasses );
}
private void processEndOfQueue(List endOfQueueFkSecondPasses) {
@@ -467,39 +493,41 @@
*/
boolean stopProcess = false;
RuntimeException originalException = null;
- while ( ! stopProcess ) {
+ while ( !stopProcess ) {
List failingSecondPasses = new ArrayList();
Iterator it = endOfQueueFkSecondPasses.listIterator();
while ( it.hasNext() ) {
- final SecondPass pass = (SecondPass) it.next();
+ final SecondPass pass = ( SecondPass ) it.next();
try {
pass.doSecondPass( classes );
}
- catch (RecoverableException e) {
+ catch ( RecoverableException e ) {
failingSecondPasses.add( pass );
- if (originalException == null) originalException = (RuntimeException) e.getCause();
+ if ( originalException == null ) {
+ originalException = ( RuntimeException ) e.getCause();
+ }
}
}
stopProcess = failingSecondPasses.size() == 0 || failingSecondPasses.size() == endOfQueueFkSecondPasses.size();
endOfQueueFkSecondPasses = failingSecondPasses;
}
- if (endOfQueueFkSecondPasses.size() > 0) {
+ if ( endOfQueueFkSecondPasses.size() > 0 ) {
throw originalException;
}
}
/**
* @return Returns a list of all <code>secondPasses</code> instances which are a instance of
- * <code>FkSecondPass</code>.
+ * <code>FkSecondPass</code>.
*/
private List<FkSecondPass> getFKSecondPassesOnly() {
Iterator iter = secondPasses.iterator();
- List<FkSecondPass> fkSecondPasses = new ArrayList<FkSecondPass>(secondPasses.size());
+ List<FkSecondPass> fkSecondPasses = new ArrayList<FkSecondPass>( secondPasses.size() );
while ( iter.hasNext() ) {
- SecondPass sp = (SecondPass) iter.next();
+ SecondPass sp = ( SecondPass ) iter.next();
//do the second pass of fk before the others and remove them
if ( sp instanceof FkSecondPass ) {
- fkSecondPasses.add( (FkSecondPass) sp );
+ fkSecondPasses.add( ( FkSecondPass ) sp );
iter.remove();
}
}
@@ -508,12 +536,12 @@
/**
* Recursively builds a list of FkSecondPass instances ready to be processed in this order.
- * Checking all dependencies recursively seems quite expensive, but the original code just relied
+ * Checking all dependencies recursively seems quite expensive, but the original code just relied
* on some sort of table name sorting which failed in certain circumstances.
* <p/>
* See <tt>ANN-722</tt> and <tt>ANN-730</tt>
- *
- * @param orderedFkSecondPasses The list containing the <code>FkSecondPass<code> instances ready
+ *
+ * @param orderedFkSecondPasses The list containing the <code>FkSecondPass<code> instances ready
* for processing.
* @param isADependencyOf Our lookup data structure to determine dependencies between tables
* @param startTable Table name to start recursive algorithm.
@@ -523,31 +551,32 @@
List orderedFkSecondPasses,
Map<String, Set<FkSecondPass>> isADependencyOf, String startTable, String currentTable) {
- Set<FkSecondPass> dependencies = isADependencyOf.get(currentTable);
-
+ Set<FkSecondPass> dependencies = isADependencyOf.get( currentTable );
+
// bottom out
- if (dependencies == null || dependencies.size() == 0) {
+ if ( dependencies == null || dependencies.size() == 0 ) {
return;
}
-
- for (FkSecondPass sp : dependencies) {
+
+ for ( FkSecondPass sp : dependencies ) {
String dependentTable = sp.getValue().getTable().getQuotedName();
- if (dependentTable.compareTo(startTable) == 0) {
+ if ( dependentTable.compareTo( startTable ) == 0 ) {
StringBuilder sb = new StringBuilder(
- "Foreign key circularity dependency involving the following tables: ");
- throw new AnnotationException(sb.toString());
+ "Foreign key circularity dependency involving the following tables: "
+ );
+ throw new AnnotationException( sb.toString() );
}
- buildRecursiveOrderedFkSecondPasses(orderedFkSecondPasses, isADependencyOf, startTable, dependentTable);
- if (!orderedFkSecondPasses.contains(sp)) {
- orderedFkSecondPasses.add(0, sp);
+ buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, isADependencyOf, startTable, dependentTable );
+ if ( !orderedFkSecondPasses.contains( sp ) ) {
+ orderedFkSecondPasses.add( 0, sp );
}
- }
+ }
}
private void processArtifactsOfType(String artifact) {
if ( "hbm".equalsIgnoreCase( artifact ) ) {
log.debug( "Process hbm files" );
- for (Document document : hbmDocuments) {
+ for ( Document document : hbmDocuments ) {
super.add( document );
}
hbmDocuments.clear();
@@ -561,7 +590,7 @@
orderedClasses, reflectionManager
);
ExtendedMappings mappings = createExtendedMappings();
- for (XClass clazz : orderedClasses) {
+ for ( XClass clazz : orderedClasses ) {
//todo use the same extended mapping
AnnotationBinder.bindClass( clazz, inheritanceStatePerClass, mappings );
}
@@ -569,13 +598,13 @@
annotatedClassEntities.clear();
}
else {
- log.warn( "Unknown artifact: {}", artifact );
+ log.warn( "Unknown artifact: {}", artifact );
}
}
private void removeConflictedArtifact(String artifact) {
if ( "hbm".equalsIgnoreCase( artifact ) ) {
- for (String entity : hbmEntities.keySet()) {
+ for ( String entity : hbmEntities.keySet() ) {
if ( annotatedClassEntities.containsKey( entity ) ) {
annotatedClasses.remove( annotatedClassEntities.get( entity ) );
annotatedClassEntities.remove( entity );
@@ -583,7 +612,7 @@
}
}
else if ( "class".equalsIgnoreCase( artifact ) ) {
- for (String entity : annotatedClassEntities.keySet()) {
+ for ( String entity : annotatedClassEntities.keySet() ) {
if ( hbmEntities.containsKey( entity ) ) {
hbmDocuments.remove( hbmEntities.get( entity ) );
hbmEntities.remove( entity );
@@ -599,7 +628,7 @@
Set<Column> unbound = new HashSet<Column>();
Set<Column> unboundNoLogical = new HashSet<Column>();
ExtendedMappings mappings = createExtendedMappings();
- for (int index = 0; index < size; index++) {
+ for ( int index = 0; index < size; index++ ) {
String columnName;
try {
columnName = mappings.getPhysicalColumnName( columnNames[index], table );
@@ -607,11 +636,11 @@
unbound.add( columns[index] );
//column equals and hashcode is based on column name
}
- catch (MappingException e) {
+ catch ( MappingException e ) {
unboundNoLogical.add( new Column( columnNames[index] ) );
}
}
- for (Column column : columns) {
+ for ( Column column : columns ) {
if ( table.containsColumn( column ) ) {
uc = table.getOrCreateUniqueKey( keyName );
uc.addColumn( table.getColumn( column ) );
@@ -620,15 +649,15 @@
}
if ( unbound.size() > 0 || unboundNoLogical.size() > 0 ) {
StringBuilder sb = new StringBuilder( "Unable to create unique key constraint (" );
- for (String columnName : columnNames) {
+ for ( String columnName : columnNames ) {
sb.append( columnName ).append( ", " );
}
sb.setLength( sb.length() - 2 );
sb.append( ") on table " ).append( table.getName() ).append( ": " );
- for (Column column : unbound) {
+ for ( Column column : unbound ) {
sb.append( column.getName() ).append( ", " );
}
- for (Column column : unboundNoLogical) {
+ for ( Column column : unboundNoLogical ) {
sb.append( column.getName() ).append( ", " );
}
sb.setLength( sb.length() - 2 );
@@ -653,26 +682,26 @@
addJar( new File( jar.getValue() ) );
}
else if ( file != null ) {
- log.debug( "{} <- {}", name, file );
+ log.debug( "{} <- {}", name, file );
addFile( file.getValue() );
}
else if ( pckg != null ) {
- log.debug( "{} <- {}", name, pckg );
+ log.debug( "{} <- {}", name, pckg );
addPackage( pckg.getValue() );
}
else if ( clazz != null ) {
- log.debug( "{} <- {}", name, clazz );
+ log.debug( "{} <- {}", name, clazz );
Class loadedClass;
try {
loadedClass = ReflectHelper.classForName( clazz.getValue() );
}
- catch (ClassNotFoundException cnf) {
+ catch ( ClassNotFoundException cnf ) {
throw new MappingException(
"Unable to load class declared as <mapping class=\"" + clazz.getValue() + "\"/> in the configuration:",
cnf
);
}
- catch (NoClassDefFoundError ncdf) {
+ catch ( NoClassDefFoundError ncdf ) {
throw new MappingException(
"Unable to load class declared as <mapping class=\"" + clazz.getValue() + "\"/> in the configuration:",
ncdf
@@ -691,7 +720,9 @@
boolean ejb3Xml = "entity-mappings".equals( doc.getRootElement().getName() );
if ( inSecondPass ) {
//if in second pass bypass the queueing, getExtendedQueue reuse this method
- if ( !ejb3Xml ) super.add( doc );
+ if ( !ejb3Xml ) {
+ super.add( doc );
+ }
}
else {
if ( !ejb3Xml ) {
@@ -702,20 +733,20 @@
: "";
Set<String> entityNames = new HashSet<String>();
findClassNames( defaultPackage, hmNode, entityNames );
- for (String entity : entityNames) {
+ for ( String entity : entityNames ) {
hbmEntities.put( entity, doc );
}
hbmDocuments.add( doc );
}
else {
final MetadataProvider metadataProvider = ( ( MetadataProviderInjector ) reflectionManager ).getMetadataProvider();
- JPAMetadataProvider jpaMetadataProvider = (JPAMetadataProvider) metadataProvider;
+ JPAMetadataProvider jpaMetadataProvider = ( JPAMetadataProvider ) metadataProvider;
List<String> classnames = jpaMetadataProvider.getXMLContext().addDocument( doc );
- for (String classname : classnames) {
+ for ( String classname : classnames ) {
try {
annotatedClasses.add( reflectionManager.classForName( classname, this.getClass() ) );
}
- catch (ClassNotFoundException e) {
+ catch ( ClassNotFoundException e ) {
throw new AnnotationException( "Unable to load class defined in XML: " + classname, e );
}
}
@@ -737,18 +768,24 @@
Iterator classIterator = new JoinedIterator( classes );
while ( classIterator.hasNext() ) {
- Element element = (Element) classIterator.next();
+ Element element = ( Element ) classIterator.next();
String entityName = element.attributeValue( "entity-name" );
- if ( entityName == null ) entityName = getClassName( element.attribute( "name" ), defaultPackage );
+ if ( entityName == null ) {
+ entityName = getClassName( element.attribute( "name" ), defaultPackage );
+ }
names.add( entityName );
findClassNames( defaultPackage, element, names );
}
}
private static String getClassName(Attribute name, String defaultPackage) {
- if ( name == null ) return null;
+ if ( name == null ) {
+ return null;
+ }
String unqualifiedName = name.getValue();
- if ( unqualifiedName == null ) return null;
+ if ( unqualifiedName == null ) {
+ return null;
+ }
if ( unqualifiedName.indexOf( '.' ) < 0 && defaultPackage != null ) {
return defaultPackage + '.' + unqualifiedName;
}
@@ -789,26 +826,26 @@
"http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
);
}
- catch (SAXException e) {
+ catch ( SAXException e ) {
saxReader.setValidation( false );
}
org.dom4j.Document doc = saxReader
.read( new InputSource( xmlInputStream ) );
if ( errors.size() != 0 ) {
- throw new MappingException( "invalid mapping", (Throwable) errors.get( 0 ) );
+ throw new MappingException( "invalid mapping", ( Throwable ) errors.get( 0 ) );
}
add( doc );
return this;
}
- catch (DocumentException e) {
+ catch ( DocumentException e ) {
throw new MappingException( "Could not parse mapping document in input stream", e );
}
finally {
try {
xmlInputStream.close();
}
- catch (IOException ioe) {
+ catch ( IOException ioe ) {
log.warn( "Could not close input stream", ioe );
}
}
@@ -817,20 +854,25 @@
public SessionFactory buildSessionFactory() throws HibernateException {
enableLegacyHibernateValidator();
enableBeanValidation();
- enableHibernateSearch();
+ enableHibernateSearch();
return super.buildSessionFactory();
}
private void enableLegacyHibernateValidator() {
//add validator events if the jar is available
- boolean enableValidatorListeners = !"false".equalsIgnoreCase( getProperty( "hibernate.validator.autoregister_listeners" ) );
+ boolean enableValidatorListeners = !"false".equalsIgnoreCase(
+ getProperty(
+ "hibernate.validator.autoregister_listeners"
+ )
+ );
Class validateEventListenerClass = null;
try {
validateEventListenerClass = ReflectHelper.classForName(
"org.hibernate.validator.event.ValidateEventListener",
- AnnotationConfiguration.class );
+ AnnotationConfiguration.class
+ );
}
- catch (ClassNotFoundException e) {
+ catch ( ClassNotFoundException e ) {
//validator is not present
log.debug( "Validator not present in classpath, ignoring event listener registration" );
}
@@ -840,14 +882,14 @@
try {
validateEventListener = validateEventListenerClass.newInstance();
}
- catch (Exception e) {
+ catch ( Exception e ) {
throw new AnnotationException( "Unable to load Validator event listener", e );
}
{
boolean present = false;
PreInsertEventListener[] listeners = getEventListeners().getPreInsertEventListeners();
if ( listeners != null ) {
- for (Object eventListener : listeners) {
+ for ( Object eventListener : listeners ) {
//not isAssignableFrom since the user could subclass
present = present || validateEventListenerClass == eventListener.getClass();
}
@@ -855,13 +897,13 @@
int length = listeners.length + 1;
PreInsertEventListener[] newListeners = new PreInsertEventListener[length];
System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
- newListeners[length - 1] = (PreInsertEventListener) validateEventListener;
+ newListeners[length - 1] = ( PreInsertEventListener ) validateEventListener;
getEventListeners().setPreInsertEventListeners( newListeners );
}
}
else {
getEventListeners().setPreInsertEventListeners(
- new PreInsertEventListener[] { (PreInsertEventListener) validateEventListener }
+ new PreInsertEventListener[] { ( PreInsertEventListener ) validateEventListener }
);
}
}
@@ -871,7 +913,7 @@
boolean present = false;
PreUpdateEventListener[] listeners = getEventListeners().getPreUpdateEventListeners();
if ( listeners != null ) {
- for (Object eventListener : listeners) {
+ for ( Object eventListener : listeners ) {
//not isAssignableFrom since the user could subclass
present = present || validateEventListenerClass == eventListener.getClass();
}
@@ -879,13 +921,13 @@
int length = listeners.length + 1;
PreUpdateEventListener[] newListeners = new PreUpdateEventListener[length];
System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
- newListeners[length - 1] = (PreUpdateEventListener) validateEventListener;
+ newListeners[length - 1] = ( PreUpdateEventListener ) validateEventListener;
getEventListeners().setPreUpdateEventListeners( newListeners );
}
}
else {
getEventListeners().setPreUpdateEventListeners(
- new PreUpdateEventListener[] { (PreUpdateEventListener) validateEventListener }
+ new PreUpdateEventListener[] { ( PreUpdateEventListener ) validateEventListener }
);
}
}
@@ -897,40 +939,50 @@
}
/**
- * Tries to automatically register Hibernate Search event listeners by locating the
+ * Tries to automatically register Hibernate Search event listeners by locating the
* appropriate bootstrap class and calling the <code>enableHibernateSearch</code> method.
*/
private void enableHibernateSearch() {
// load the bootstrap class
Class searchStartupClass;
try {
- searchStartupClass = ReflectHelper.classForName(SEARCH_STARTUP_CLASS, AnnotationConfiguration.class);
- } catch ( ClassNotFoundException e ) {
+ searchStartupClass = ReflectHelper.classForName( SEARCH_STARTUP_CLASS, AnnotationConfiguration.class );
+ }
+ catch ( ClassNotFoundException e ) {
// TODO remove this together with SearchConfiguration after 3.1.0 release of Search
// try loading deprecated HibernateSearchEventListenerRegister
try {
- searchStartupClass = ReflectHelper.classForName("org.hibernate.cfg.search.HibernateSearchEventListenerRegister", AnnotationConfiguration.class);
- } catch ( ClassNotFoundException cnfe ) {
- log.debug("Search not present in classpath, ignoring event listener registration.");
+ searchStartupClass = ReflectHelper.classForName(
+ "org.hibernate.cfg.search.HibernateSearchEventListenerRegister", AnnotationConfiguration.class
+ );
+ }
+ catch ( ClassNotFoundException cnfe ) {
+ log.debug( "Search not present in classpath, ignoring event listener registration." );
return;
}
}
-
+
// call the method for registering the listeners
try {
Object searchStartupInstance = searchStartupClass.newInstance();
- Method enableSearchMethod = searchStartupClass.getDeclaredMethod(SEARCH_STARTUP_METHOD,
- EventListeners.class, Properties.class);
- enableSearchMethod.invoke(searchStartupInstance, getEventListeners(), getProperties());
- } catch ( InstantiationException e ) {
- log.debug("Unable to instantiate {}, ignoring event listener registration.", SEARCH_STARTUP_CLASS);
- } catch ( IllegalAccessException e ) {
- log.debug("Unable to instantiate {}, ignoring event listener registration.", SEARCH_STARTUP_CLASS);
- } catch ( NoSuchMethodException e ) {
- log.debug("Method enableHibernateSearch() not found in {}.", SEARCH_STARTUP_CLASS);
- } catch ( InvocationTargetException e ) {
- log.debug("Unable to execute {}, ignoring event listener registration.", SEARCH_STARTUP_METHOD);
+ Method enableSearchMethod = searchStartupClass.getDeclaredMethod(
+ SEARCH_STARTUP_METHOD,
+ EventListeners.class, Properties.class
+ );
+ enableSearchMethod.invoke( searchStartupInstance, getEventListeners(), getProperties() );
}
+ catch ( InstantiationException e ) {
+ log.debug( "Unable to instantiate {}, ignoring event listener registration.", SEARCH_STARTUP_CLASS );
+ }
+ catch ( IllegalAccessException e ) {
+ log.debug( "Unable to instantiate {}, ignoring event listener registration.", SEARCH_STARTUP_CLASS );
+ }
+ catch ( NoSuchMethodException e ) {
+ log.debug( "Method enableHibernateSearch() not found in {}.", SEARCH_STARTUP_CLASS );
+ }
+ catch ( InvocationTargetException e ) {
+ log.debug( "Unable to execute {}, ignoring event listener registration.", SEARCH_STARTUP_METHOD );
+ }
}
@Override
@@ -1078,13 +1130,15 @@
}
@Override
- public AnnotationConfiguration setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy) throws MappingException {
+ public AnnotationConfiguration setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy)
+ throws MappingException {
super.setCacheConcurrencyStrategy( clazz, concurrencyStrategy );
return this;
}
@Override
- public AnnotationConfiguration setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy) throws MappingException {
+ public AnnotationConfiguration setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy)
+ throws MappingException {
super.setCollectionCacheConcurrencyStrategy( collectionRole, concurrencyStrategy );
return this;
}
@@ -1121,10 +1175,10 @@
}
public boolean isInSecondPass() {
- return inSecondPass;
+ return inSecondPass;
}
-
-
+
+
public IdGenerator getGenerator(String name) {
return getGenerator( name, null );
}
@@ -1276,8 +1330,9 @@
@Override
public void addResultSetMapping(ResultSetMappingDefinition definition) throws DuplicateMappingException {
- if ( !defaultSqlResulSetMappingNames.contains( definition.getName() ) )
+ if ( !defaultSqlResulSetMappingNames.contains( definition.getName() ) ) {
super.addResultSetMapping( definition );
+ }
}
@Override
Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationGroupsTest.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationGroupsTest.java 2009-10-22 10:02:12 UTC (rev 17817)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationGroupsTest.java 2009-10-22 11:10:31 UTC (rev 17818)
@@ -42,7 +42,7 @@
catch ( ConstraintViolationException e ) {
assertEquals( 1, e.getConstraintViolations().size() );
// TODO - seems this explicit case is necessary with JDK 5 (at least on Mac). With Java 6 there is no problem
- Annotation annotation = (Annotation) e.getConstraintViolations()
+ Annotation annotation = ( Annotation ) e.getConstraintViolations()
.iterator()
.next()
.getConstraintDescriptor()
@@ -71,6 +71,7 @@
"javax.persistence.validation.group.pre-remove",
Default.class.getName() + ", " + Strict.class.getName()
);
+ cfg.setProperty( "hibernate.validator.apply_to_ddl", "false" );
}
protected Class<?>[] getMappings() {
14 years, 6 months
Hibernate SVN: r17817 - core/trunk/annotations/src/main/docbook/en/modules.
by hibernate-commits@lists.jboss.org
Author: sharathjreddy
Date: 2009-10-22 06:02:12 -0400 (Thu, 22 Oct 2009)
New Revision: 17817
Modified:
core/trunk/annotations/src/main/docbook/en/modules/entity.xml
Log:
HHH-4473 Create documentation to explain the usage of the new 'defaultForType' attribute of the TypeDef annotation
Modified: core/trunk/annotations/src/main/docbook/en/modules/entity.xml
===================================================================
--- core/trunk/annotations/src/main/docbook/en/modules/entity.xml 2009-10-22 00:59:53 UTC (rev 17816)
+++ core/trunk/annotations/src/main/docbook/en/modules/entity.xml 2009-10-22 10:02:12 UTC (rev 17817)
@@ -2656,15 +2656,36 @@
<para><literal>@org.hibernate.annotations.TypeDef</literal> and
<literal>@org.hibernate.annotations.TypeDefs</literal> allows you to
declare type definitions. These annotations can be placed at the class or
- package level. Note that these definitions are be global for the
- session factory (even when defined at the class level). Type definitions have
- to be defined before any usage. If the type is used on a single entity, you
- can plance the definition on the entity itself. Otherwise, it is recommended
- to place the definition a the package level since the entity processing order
- is not guaranteed.</para>
+ package level. Note that these definitions are global for the
+ session factory (even when defined at the class level). If the type is used on a single entity, you can place the definition on the entity itself. Otherwise, it is recommended to place the definition at the package level. In the example below, when Hibernate encounters a property of class <literal>PhoneNumer</literal>, it delegates the persistence strategy to the custom mapping type <literal>PhoneNumberType</literal>. However, properties belonging to other classes, too, can delegate their persistence strategy to <literal>PhoneNumberType</literal>, by explicitly using the <literal>@Type</literal> annotation. </para>
+
<note>Package level annotations are placed in a file named <filename>package-info.java</filename>
in the appropriate package. Place your annotations before the package declaration.</note>
+<programlisting>
+@TypeDef(
+ name = "phoneNumber",
+ defaultForType = PhoneNumber.class,
+ typeClass = PhoneNumberType.class
+)
+
+@Entity
+public class ContactDetails {
+ ...
+ private PhoneNumber localPhoneNumber;
+ @Type(type="phoneNumber")
+ private OverseasPhoneNumber overseasPhoneNumber;
+ ...
+}
+
+
+</programlisting>
+
+<para>
+The following example shows the usage of the <literal>parameters</literal> attribute to customize the TypeDef.
+</para>
+
+
<programlisting>//in org/hibernate/test/annotations/entity/package-info.java
@TypeDefs(
{
14 years, 6 months
Hibernate SVN: r17816 - in core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr: metadata and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-10-21 20:59:53 -0400 (Wed, 21 Oct 2009)
New Revision: 17816
Added:
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarDelegate.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFileMetadata.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarMetadata.java
Removed:
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/Grammar.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFile.java
Modified:
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrPlugin.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrSourceVirtualDirectory.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrSourceVirtualDirectoryImpl.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrTask.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/MetadataExtracter.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/XRef.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/plan/GenerationPlan.java
core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/plan/GenerationPlanBuilder.java
Log:
cleaned up javadocs, reorganized code a bit
Modified: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrPlugin.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrPlugin.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrPlugin.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -50,7 +50,9 @@
public class AntlrPlugin implements Plugin {
public static final String ANTLR_CONFIGURATION_NAME = "antlr";
-
+ /**
+ * {@inheritDoc}
+ */
public void use(final Project project, ProjectPluginsContainer projectPluginsHandler) {
projectPluginsHandler.usePlugin( JavaPlugin.class, project );
Modified: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrSourceVirtualDirectory.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrSourceVirtualDirectory.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrSourceVirtualDirectory.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -28,7 +28,10 @@
import groovy.lang.Closure;
/**
- * Virtual directory mapping handler for 'antlr'.
+ * Contract for a Gradle "convention object" that acts as a handler for what I call a virtual directory mapping,
+ * injecting a virtual directory named 'antlr' into the project's various
+ * {@link org.gradle.api.tasks.SourceSet source sets}. Its implementation gets pushed onto the
+ * {@link org.gradle.api.internal.DynamicObjectAware} portion of the source set under the name 'antlr'.
*
* @author Steve Ebersole
*/
Modified: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrSourceVirtualDirectoryImpl.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrSourceVirtualDirectoryImpl.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrSourceVirtualDirectoryImpl.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -33,9 +33,7 @@
import groovy.lang.Closure;
/**
- * Acts as a delegate to the {@link org.gradle.api.internal.DynamicObjectAware} portion of
- * Gradle's {@link org.gradle.api.tasks.SourceSet} in order to add Antlr-relate directory
- * mapping to the source sets.
+ * The implementation of the {@link AntlrSourceVirtualDirectory} contract.
*
* @author Steve Ebersole
*/
Modified: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrTask.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrTask.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/AntlrTask.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -39,6 +39,13 @@
/**
* Gradle task for executing Antlr generations. Wrapper around the Ant {@link ANTLR} task.
+ * <p/>
+ * Most properties here are self-evident, but I wanted to highlight one in particular:
+ * {@link #setAntlrClasspath} is used to define the classpath that should be passed along to the
+ * Ant {@link ANTLR} task as its classpath. That is the classpath it uses to perform generation
+ * execution. This <b>should<b> really only require the antlr jar. In {@link AntlrPlugin}
+ * usage, this would happen simply by adding your antlr jar into the 'antlr' dependency configuration
+ * created and exposed by the {@link AntlrPlugin} itself.
*
* @author Steve Ebersole
*/
Deleted: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/Grammar.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/Grammar.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/Grammar.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -1,100 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
- * third-party contributors as indicated by either @author tags or express
- * copyright attribution statements applied by the authors. All
- * third-party contributions are distributed under license by Red Hat Inc.
- *
- * 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.gradle.plugin.antlr.metadata;
-
-import java.io.File;
-
-/**
- * Models a grammar defined within an Antlr grammar file.
- *
- * @author Steve Ebersole
- */
-public class Grammar {
- private final GrammarFile grammarFile;
- private String className;
- private String superGrammarName;
- private String importVocab;
- private String exportVocab;
-
- public Grammar(GrammarFile grammarFile) {
- this.grammarFile = grammarFile;
- grammarFile.addGrammar( this );
- }
-
- public GrammarFile getGrammarFile() {
- return grammarFile;
- }
-
- public String getClassName() {
- return className;
- }
-
- public void setClassName(String className) {
- this.className = className;
- }
-
- public String getSuperGrammarName() {
- return superGrammarName;
- }
-
- public void setSuperGrammarName(String superGrammarName) {
- this.superGrammarName = superGrammarName;
- }
-
- public String getImportVocab() {
- return importVocab;
- }
-
- public void setImportVocab(String importVocab) {
- this.importVocab = importVocab;
- }
-
- public String getExportVocab() {
- return exportVocab;
- }
-
- public void setExportVocab(String exportVocab) {
- this.exportVocab = exportVocab;
- }
-
- public String getPackageName() {
- return getGrammarFile().getPackageName();
- }
-
- public String determineGeneratedParserPath() {
- if ( isEmpty( getPackageName() ) ) {
- return getClassName() + ".java";
- }
- else {
- return getPackageName().replace( '.', File.separatorChar )
- + File.separatorChar
- + getClassName()
- + ".java";
- }
- }
-
- private boolean isEmpty(String packageName) {
- return packageName == null || packageName.trim().length() == 0;
- }
-}
Added: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarDelegate.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarDelegate.java (rev 0)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarDelegate.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -0,0 +1,172 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * 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.gradle.plugin.antlr.metadata;
+
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.ArrayList;
+import java.util.List;
+
+import antlr.collections.impl.IndexedVector;
+import antlr.preprocessor.GrammarFile;
+
+/**
+ * Antlr defines its {@link antlr.preprocessor.Grammar} class as package-protected for some unfortunate reason.
+ * So this class acts as a delegate to the Antlr {@link antlr.preprocessor.Grammar} class, hiding all the
+ * ugly necessary reflection code.
+ *
+ * @author Steve Ebersole
+ */
+public class GrammarDelegate {
+ public static List<GrammarDelegate> extractGrammarDelegates(GrammarFile antlrGrammarFile) {
+ List<GrammarDelegate> grammarDelegates = new ArrayList<GrammarDelegate>();
+ Enumeration grammarFileGramars = antlrGrammarFile.getGrammars().elements();
+ while ( grammarFileGramars.hasMoreElements() ) {
+ grammarDelegates.add( new GrammarDelegate( grammarFileGramars.nextElement() ) );
+ }
+ return grammarDelegates;
+ }
+
+ private final String className;
+ private final String importVocab;
+ private final String exportVocab;
+ private final GrammarDelegate superGrammarDelegate;
+
+ public GrammarDelegate(Object antlrGrammarMetadata) {
+ try {
+ final Method getNameMethod = antlrGrammarClass.getDeclaredMethod( "getName", NO_ARG_SIGNATURE );
+ getNameMethod.setAccessible( true );
+ this.className = ( String ) getNameMethod.invoke( antlrGrammarMetadata, NO_ARGS );
+
+ final Method getSuperGrammarMethod = antlrGrammarClass.getMethod( "getSuperGrammar", NO_ARG_SIGNATURE );
+ getSuperGrammarMethod.setAccessible( true );
+ final Object antlrSuperGrammarGrammarMetadata = getSuperGrammarMethod.invoke( antlrGrammarMetadata, NO_ARGS );
+ this.superGrammarDelegate = antlrSuperGrammarGrammarMetadata == null
+ ? null
+ : new GrammarDelegate( antlrSuperGrammarGrammarMetadata );
+
+ Method getOptionsMethod = antlrGrammarClass.getMethod( "getOptions", NO_ARG_SIGNATURE );
+ getOptionsMethod.setAccessible( true );
+ IndexedVector options = ( IndexedVector ) getOptionsMethod.invoke( antlrGrammarMetadata, NO_ARGS );
+
+ Method getRHSMethod = antlrOptionClass.getMethod( "getRHS", NO_ARG_SIGNATURE );
+ getRHSMethod.setAccessible( true );
+
+ final Object importVocabOption = options == null
+ ? null
+ : options.getElement( "importVocab" );
+ this.importVocab = importVocabOption == null
+ ? null
+ : vocabName( (String) getRHSMethod.invoke( importVocabOption, NO_ARGS ) );
+
+ final Object exportVocabOption = options == null
+ ? null
+ : options.getElement( "exportVocab" );
+ this.exportVocab = exportVocabOption == null
+ ? null
+ : vocabName( (String) getRHSMethod.invoke( exportVocabOption, NO_ARGS ) );
+ }
+ catch ( Throwable t ) {
+ throw new IllegalStateException( "Error accessing Antlr grammar metadata", t );
+ }
+ }
+
+ /**
+ * Retrieves the unqualified name of the lexer/parser class.
+ *
+ * @return The unqualified lexer/parser class name.
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Retrieves the name of this vocabulary imported by this grammar.
+ *
+ * @return The gammar's imported vocabulary name.
+ */
+ public String getImportVocab() {
+ return importVocab;
+ }
+
+ /**
+ * Retrieves the name of this vocabulary exported by this grammar.
+ *
+ * @return The gammar's exported vocabulary name.
+ */
+ public String getExportVocab() {
+ return exportVocab;
+ }
+
+ /**
+ * Retrieves the grammar delegate associated with this grammars super grammar deduced during preprocessing
+ * from its extends clause.
+ *
+ * @return The super-grammar grammar delegate
+ */
+ public GrammarDelegate getSuperGrammarDelegate() {
+ return superGrammarDelegate;
+ }
+
+ private GrammarMetadata associatedGrammarMetadata;
+
+ public void associateWith(GrammarMetadata associatedGrammarMetadata) {
+ this.associatedGrammarMetadata = associatedGrammarMetadata;
+ }
+
+ public GrammarMetadata getAssociatedGrammarMetadata() {
+ return associatedGrammarMetadata;
+ }
+
+ private String vocabName(String vocabName) {
+ if ( vocabName == null ) {
+ return null;
+ }
+ vocabName = vocabName.trim();
+ if ( vocabName.endsWith( ";" ) ) {
+ vocabName = vocabName.substring( 0, vocabName.length() - 1 );
+ }
+ return vocabName;
+ }
+
+ private static final Class antlrGrammarClass;
+ private static final Class antlrOptionClass;
+
+ static {
+ antlrGrammarClass = loadAntlrClass( "antlr.preprocessor.Grammar" );
+ antlrOptionClass = loadAntlrClass( "antlr.preprocessor.Option" );
+ }
+
+ public static final Class[] NO_ARG_SIGNATURE = new Class[0];
+ public static final Object[] NO_ARGS = new Object[0];
+
+ private static Class loadAntlrClass(String className) {
+ try {
+ return Class.forName( className, true, GrammarDelegate.class.getClassLoader() );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new IllegalStateException( "Unable to locate Antlr class [" + className + "]", e );
+ }
+ }
+}
Deleted: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFile.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFile.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFile.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -1,68 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
- * third-party contributors as indicated by either @author tags or express
- * copyright attribution statements applied by the authors. All
- * third-party contributions are distributed under license by Red Hat Inc.
- *
- * 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.gradle.plugin.antlr.metadata;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * TODO : javadoc
- *
- * @author Steve Ebersole
- */
-public class GrammarFile {
- private final String fileName;
- private final String[] glibs;
- private String packageName;
- private List<Grammar> grammars = new ArrayList<Grammar>();
-
- public GrammarFile(String fileName, String[] glibs) {
- this.fileName = fileName;
- this.glibs = glibs != null ? glibs : new String[0];
- }
-
- public String getFileName() {
- return fileName;
- }
-
- public String[] getGlibs() {
- return glibs;
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- void setPackageName(String packageName) {
- this.packageName = packageName;
- }
-
- void addGrammar(Grammar grammar) {
- grammars.add( grammar );
- }
-
- public List<Grammar> getGrammars() {
- return grammars;
- }
-}
Copied: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFileMetadata.java (from rev 17800, core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFile.java)
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFileMetadata.java (rev 0)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarFileMetadata.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -0,0 +1,69 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * 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.gradle.plugin.antlr.metadata;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.io.File;
+
+/**
+ * Models information about an Antlr grammar file, including the inidividual {@link #getGrammars grammars}
+ * (lexers, parsers, etc) contained within it.
+ *
+ * @author Steve Ebersole
+ */
+public class GrammarFileMetadata {
+ private final File filePath;
+ private final antlr.preprocessor.GrammarFile antlrGrammarFile;
+ private final String packageName;
+ private List<GrammarMetadata> grammarMetadatas = new ArrayList<GrammarMetadata>();
+
+ public GrammarFileMetadata(File filePath, antlr.preprocessor.GrammarFile antlrGrammarFile, String packageName) {
+ this.filePath = filePath;
+ this.antlrGrammarFile = antlrGrammarFile;
+ this.packageName = packageName;
+
+ List<GrammarDelegate> antlrGrammarDelegates = GrammarDelegate.extractGrammarDelegates( antlrGrammarFile );
+ for ( GrammarDelegate antlrGrammarDelegate : antlrGrammarDelegates ) {
+ GrammarMetadata grammarMetadata = new GrammarMetadata( this, antlrGrammarDelegate );
+ grammarMetadatas.add( grammarMetadata );
+ }
+ }
+
+ public File getFilePath() {
+ return filePath;
+ }
+
+ public antlr.preprocessor.GrammarFile getAntlrGrammarFile() {
+ return antlrGrammarFile;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public List<GrammarMetadata> getGrammars() {
+ return grammarMetadatas;
+ }
+}
Copied: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarMetadata.java (from rev 17800, core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/Grammar.java)
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarMetadata.java (rev 0)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/GrammarMetadata.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -0,0 +1,108 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * 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.gradle.plugin.antlr.metadata;
+
+import java.io.File;
+
+import antlr.TreeParser;
+import antlr.Parser;
+
+/**
+ * Models a grammar defined within an Antlr grammar file.
+ *
+ * @author Steve Ebersole
+ */
+public class GrammarMetadata {
+ private final GrammarFileMetadata grammarFileMetadata;
+ private final GrammarDelegate grammarDelegate;
+
+ public GrammarMetadata(GrammarFileMetadata grammarFileMetadata, GrammarDelegate grammarDelegate) {
+ this.grammarFileMetadata = grammarFileMetadata;
+ this.grammarDelegate = grammarDelegate;
+ grammarDelegate.associateWith( this );
+ }
+
+ public GrammarFileMetadata getGrammarFile() {
+ return grammarFileMetadata;
+ }
+
+ public String getClassName() {
+ return grammarDelegate.getClassName();
+ }
+
+ public String getQualifiedClassName() {
+ if ( isEmpty( getPackageName() ) ) {
+ return getClassName();
+ }
+ else {
+ return getPackageName() + '.' + getClassName();
+ }
+ }
+
+ public GrammarDelegate getSuperGrammarDelegate() {
+ return grammarDelegate.getSuperGrammarDelegate();
+ }
+
+ public boolean extendsStandardGrammar() {
+ final String superGrammarClassName = getSuperGrammarDelegate().getClassName();
+ return Parser.class.getName().equals( superGrammarClassName )
+ || Parser.class.getSimpleName().equals( superGrammarClassName )
+ || TreeParser.class.getName().equals( superGrammarClassName )
+ || TreeParser.class.getSimpleName().equals( superGrammarClassName )
+ || "Lexer".equals( superGrammarClassName );
+ }
+
+ public String getImportVocab() {
+ return grammarDelegate.getImportVocab();
+ }
+
+ public String getExportVocab() {
+ return grammarDelegate.getExportVocab();
+ }
+
+ public String getPackageName() {
+ return getGrammarFile().getPackageName();
+ }
+
+ /**
+ * Determine the relative path of the generated parser java file.
+ *
+ * @return The relative generated parser file path.
+ */
+ public String determineGeneratedParserPath() {
+ if ( isEmpty( getPackageName() ) ) {
+ return getClassName() + ".java";
+ }
+ else {
+ return getPackageName().replace( '.', File.separatorChar )
+ + File.separatorChar
+ + getClassName()
+ + ".java";
+ }
+ }
+
+ private boolean isEmpty(String packageName) {
+ return packageName == null || packageName.trim().length() == 0;
+ }
+}
Modified: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/MetadataExtracter.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/MetadataExtracter.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/MetadataExtracter.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -28,17 +28,13 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.lang.reflect.Method;
import org.gradle.api.file.FileTree;
-import antlr.collections.impl.IndexedVector;
/**
- * Preprocess an Antlr grammar file to that dependencies between grammars
- * can be properly determined so that they can be passed to the Antlr {@link antlr.Tool}
- * in proper order.
+ * Preprocess an Antlr grammar file so that dependencies between grammars
+ * can be properly determined such that they can be processed for generation
+ * in proper order later.
*
* @author Steve Ebersole
*/
@@ -48,23 +44,33 @@
antlr.Tool tool = new antlr.Tool();
antlr.preprocessor.Hierarchy hierarchy = new antlr.preprocessor.Hierarchy( tool );
- final ArrayList<GrammarFile> grammarFiles = new ArrayList<GrammarFile>();
+ // first let antlr preprocess the grammars...
for ( File grammarFileFile : source.getFiles() ) {
final String grammarFilePath = grammarFileFile.getPath();
- GrammarFile grammarFile = new GrammarFile(
- grammarFilePath,
- null // todo : account for glibs
- );
- // :( antlr.preprocessor.GrammarFile's only access to package is through a protected field :(
try {
+ hierarchy.readGrammarFile( grammarFilePath );
+ }
+ catch ( FileNotFoundException e ) {
+ // should never happen here
+ throw new IllegalStateException( "Received FileNotFoundException on already read file", e );
+ }
+ }
+
+ // now, do our processing using the antlr preprocessor results whenever possible.
+ XRef xref = new XRef( hierarchy );
+ for ( File grammarFileFile : source.getFiles() ) {
+
+ // determine the package name :(
+ String grammarPackageName = null;
+ try {
BufferedReader in = new BufferedReader( new FileReader( grammarFileFile ) );
try {
String line;
while ( ( line = in.readLine() ) != null ) {
line = line.trim();
if ( line.startsWith( "package" ) && line.endsWith( ";" ) ) {
- grammarFile.setPackageName( line.substring( 8, line.length() -1 ) );
+ grammarPackageName = line.substring( 8, line.length() -1 );
break;
}
}
@@ -81,114 +87,18 @@
e.printStackTrace();
}
- grammarFiles.add( grammarFile );
+ final String grammarFilePath = grammarFileFile.getPath();
+ antlr.preprocessor.GrammarFile antlrGrammarFile = hierarchy.getFile( grammarFilePath );
- try {
- hierarchy.readGrammarFile( grammarFilePath );
- }
- catch ( FileNotFoundException e ) {
- // should never happen here
- throw new IllegalStateException( "Received FileNotFoundException on already read file", e );
- }
- }
+ GrammarFileMetadata grammarFileMetadata = new GrammarFileMetadata(
+ grammarFileFile,
+ antlrGrammarFile,
+ grammarPackageName
+ );
- XRef xref = new XRef( hierarchy );
- for ( GrammarFile grammarFile : grammarFiles ) {
- final String grammarFilePath = grammarFile.getFileName();
- try {
- antlr.preprocessor.GrammarFile antlrToolGrammarFile = hierarchy.getFile( grammarFilePath );
- intrepretMetadata( grammarFile, antlrToolGrammarFile );
- xref.addGrammarFile( grammarFile );
- }
- catch ( Throwable t ) {
- throw new IllegalStateException( "Unable to build grammar metadata", t );
- }
+ xref.addGrammarFile( grammarFileMetadata );
}
return xref;
}
-
- private void intrepretMetadata(GrammarFile grammarFile, antlr.preprocessor.GrammarFile antlrToolGrammarFile) {
- final Enumeration antlrGrammars = antlrToolGrammarFile.getGrammars().elements();
- while ( antlrGrammars.hasMoreElements() ) {
- Grammar grammar = new Grammar( grammarFile );
- intrepret( grammar, antlrGrammars.nextElement() );
- }
- }
-
-
-
- private void intrepret(Grammar grammar, Object antlrGrammarDef) {
- // antlr.preprocessor.Grammar is defined as package-protected, ugh...
- final Class antlrGrammarClass = loadAntlrClass( "antlr.preprocessor.Grammar" );
- final Class antlrOptionClass = loadAntlrClass( "antlr.preprocessor.Option" );
-
- try {
- final Method getNameMethod = antlrGrammarClass.getDeclaredMethod( "getName", NO_ARG_SIGNATURE );
- getNameMethod.setAccessible( true );
- final String name = ( String ) getNameMethod.invoke( antlrGrammarDef, NO_ARGS );
- grammar.setClassName( name );
-
- final Method getSuperGrammarNameMethod = antlrGrammarClass.getMethod( "getSuperGrammarName", NO_ARG_SIGNATURE );
- getSuperGrammarNameMethod.setAccessible( true );
- final String superGrammarName = ( String ) getSuperGrammarNameMethod.invoke( antlrGrammarDef, NO_ARGS );
- grammar.setSuperGrammarName( superGrammarName );
-
- Method getOptionsMethod = antlrGrammarClass.getMethod( "getOptions", NO_ARG_SIGNATURE );
- getOptionsMethod.setAccessible( true );
- IndexedVector options = ( IndexedVector ) getOptionsMethod.invoke( antlrGrammarDef, NO_ARGS );
-
- Method getRHSMethod = antlrOptionClass.getMethod( "getRHS", NO_ARG_SIGNATURE );
- getRHSMethod.setAccessible( true );
-
- Object importVocabOption = options.getElement( "importVocab" );
- if ( importVocabOption != null ) {
- String importVocab = ( String ) getRHSMethod.invoke( importVocabOption, NO_ARGS );
- if ( importVocab != null ) {
- importVocab = importVocab.trim();
- if ( importVocab.endsWith( ";" ) ) {
- importVocab = importVocab.substring( 0, importVocab.length() - 1 );
- }
- grammar.setImportVocab( importVocab );
- }
- }
-
- Object exportVocabOption = options.getElement( "exportVocab" );
- if ( exportVocabOption != null ) {
- String exportVocab = ( String ) getRHSMethod.invoke( exportVocabOption, NO_ARGS );
- if ( exportVocab != null ) {
- exportVocab = exportVocab.trim();
- if ( exportVocab.endsWith( ";" ) ) {
- exportVocab = exportVocab.substring( 0, exportVocab.length() -1 );
- }
- }
- grammar.setExportVocab( exportVocab );
- }
- }
- catch ( Throwable t ) {
- throw new IllegalStateException( "Error accessing Antlr grammar metadata", t );
- }
- }
-
- public static final Class[] NO_ARG_SIGNATURE = new Class[0];
- public static final Object[] NO_ARGS = new Object[0];
-
- private Class loadAntlrClass(String className) {
- try {
- return Class.forName( className, true, ANTLR_CLASSLOADER );
- }
- catch ( ClassNotFoundException e ) {
- throw new IllegalStateException( "Unable to locate Antlr class [" + className + "]", e );
- }
- }
-
- private static ClassLoader ANTLR_CLASSLOADER = determineAntlrClassLoader();
-
- private static ClassLoader determineAntlrClassLoader() {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if ( cl == null ) {
- cl = MetadataExtracter.class.getClassLoader();
- }
- return cl;
- }
}
Modified: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/XRef.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/XRef.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/metadata/XRef.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -30,17 +30,17 @@
import antlr.preprocessor.Hierarchy;
/**
- * TODO : javadoc
+ * Models cross-reference (x-ref) info about {@link GrammarFileMetadata grammar files} such as {@link #filesByPath},
+ * {@link #filesByExportVocab} and {@link #filesByClassName}.
*
* @author Steve Ebersole
*/
public class XRef {
private final Hierarchy antlrHierarchy;
-// private LinkedHashMap<String, GrammarFile> filesById = new LinkedHashMap<String, GrammarFile>();
- private LinkedHashMap<String, GrammarFile> filesByPath = new LinkedHashMap<String, GrammarFile>();
- private HashMap<String, GrammarFile> filesByExportVocab = new HashMap<String, GrammarFile>();
- private HashMap<String, GrammarFile> filesByClassName = new HashMap<String, GrammarFile>();
+ private LinkedHashMap<String, GrammarFileMetadata> filesByPath = new LinkedHashMap<String, GrammarFileMetadata>();
+ private HashMap<String, GrammarFileMetadata> filesByExportVocab = new HashMap<String, GrammarFileMetadata>();
+ private HashMap<String, GrammarFileMetadata> filesByClassName = new HashMap<String, GrammarFileMetadata>();
public XRef(Hierarchy antlrHierarchy) {
this.antlrHierarchy = antlrHierarchy;
@@ -50,40 +50,56 @@
return antlrHierarchy;
}
- void addGrammarFile(GrammarFile grammarFile) {
-// filesById.put( grammarFile.getId(), grammarFile );
- filesByPath.put( grammarFile.getFileName(), grammarFile );
- for ( Grammar grammar : grammarFile.getGrammars() ) {
- filesByClassName.put( grammar.getClassName(), grammarFile );
- if ( grammar.getExportVocab() != null ) {
- GrammarFile old = filesByExportVocab.put( grammar.getExportVocab(), grammarFile );
- if ( old != null && old != grammarFile ) {
- System.out.println( "[WARNING] : multiple grammars defined the same exportVocab : " + grammar.getExportVocab() );
+ /**
+ * Adds a grammar file to this cross-reference.
+ *
+ * @param grammarFileMetadata The grammar file to add (and to be cross referenced).
+ */
+ void addGrammarFile(GrammarFileMetadata grammarFileMetadata) {
+ filesByPath.put( grammarFileMetadata.getFilePath().getPath(), grammarFileMetadata );
+ for ( GrammarMetadata grammarMetadata : grammarFileMetadata.getGrammars() ) {
+ filesByClassName.put( grammarMetadata.getClassName(), grammarFileMetadata );
+ if ( grammarMetadata.getExportVocab() != null ) {
+ GrammarFileMetadata old = filesByExportVocab.put( grammarMetadata.getExportVocab(), grammarFileMetadata );
+ if ( old != null && old != grammarFileMetadata ) {
+ System.out.println( "[WARNING] : multiple grammars defined the same exportVocab : " + grammarMetadata
+ .getExportVocab() );
}
}
}
}
-// public Iterator iterateGrammarFiles() {
-// return filesById.values().iterator();
-// }
-//
-// public GrammarFile getGrammarFileById(String id) {
-// return filesById.get( id );
-// }
- public Iterator<GrammarFile> iterateGrammarFiles() {
+ public Iterator<GrammarFileMetadata> iterateGrammarFiles() {
return filesByPath.values().iterator();
}
- public GrammarFile getGrammarFileByPath(String path) {
+ /**
+ * Locate the grammar file metadata by grammar file path.
+ *
+ * @param path The grammar file path.
+ * @return The grammar file metadata. May be null if none found.
+ */
+ public GrammarFileMetadata getGrammarFileByPath(String path) {
return filesByPath.get( path );
}
- public GrammarFile getGrammarFileByClassName(String className) {
+ /**
+ * Locate the grammar file metadata by the name of a class generated from one of its included grammars.
+ *
+ * @param className The generated class name.
+ * @return The grammar file metadata. May be null if none found.
+ */
+ public GrammarFileMetadata getGrammarFileByClassName(String className) {
return filesByClassName.get( className );
}
- public GrammarFile getGrammarFileByExportVocab(String exportVocab) {
- return filesByExportVocab.get( exportVocab );
+ /**
+ * Locate the grammar file metadata by the name of a vocabulary exported from one of its included grammars.
+ *
+ * @param vocabName The vocabulary name
+ * @return The grammar file metadata. May be null if none found.
+ */
+ public GrammarFileMetadata getGrammarFileByExportVocab(String vocabName) {
+ return filesByExportVocab.get( vocabName );
}
}
Modified: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/plan/GenerationPlan.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/plan/GenerationPlan.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/plan/GenerationPlan.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -24,36 +24,33 @@
package org.gradle.plugin.antlr.plan;
import java.io.File;
-import java.util.LinkedHashSet;
/**
- * TODO : javadoc
+ * Models information relevant to generation of a particular Antlr grammar file.
*
* @author Steve Ebersole
*/
public class GenerationPlan {
- private final String id;
private final File source;
private final File generationDirectory;
private File importVocabTokenTypesDirectory;
private boolean outOfDate;
- private LinkedHashSet<String> collectedSuperGrammarIds = new LinkedHashSet<String>();
-
- GenerationPlan(String id, File source, File generationDirectory, String[] glibIds) {
- this.id = id;
+ /**
+ * Instantiates a generation plan.
+ *
+ * @param source The grammar file.
+ * @param generationDirectory The directory into which generated lexers and parsers should be written, accounting
+ * for delared package.
+ */
+ GenerationPlan(File source, File generationDirectory) {
this.source = source;
this.generationDirectory = generationDirectory;
- if ( glibIds != null ) {
- for ( String glibId : glibIds ) {
- addSuperGrammarId( glibId );
- }
- }
}
public String getId() {
- return id;
+ return getSource().getPath();
}
public File getSource() {
@@ -64,14 +61,6 @@
return generationDirectory;
}
- void addSuperGrammarId(String id) {
- collectedSuperGrammarIds.add( id );
- }
-
- public LinkedHashSet<String> getCollectedSuperGrammarIds() {
- return collectedSuperGrammarIds;
- }
-
public File getImportVocabTokenTypesDirectory() {
return importVocabTokenTypesDirectory;
}
@@ -80,10 +69,18 @@
this.importVocabTokenTypesDirectory = importVocabTokenTypesDirectory;
}
+ /**
+ * Is the grammar file modeled by this plan out of considered out of date?
+ *
+ * @return True if the grammar generation is out of date (needs regen); false otherwise.
+ */
public boolean isOutOfDate() {
return outOfDate;
}
+ /**
+ * Marks the plan as out of date.
+ */
void markOutOfDate() {
this.outOfDate = true;
}
Modified: core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/plan/GenerationPlanBuilder.java
===================================================================
--- core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/plan/GenerationPlanBuilder.java 2009-10-21 22:01:02 UTC (rev 17815)
+++ core/branches/gradle/buildSrc/src/main/java/org/gradle/plugin/antlr/plan/GenerationPlanBuilder.java 2009-10-22 00:59:53 UTC (rev 17816)
@@ -30,13 +30,15 @@
import java.util.ArrayList;
import org.gradle.plugin.antlr.metadata.XRef;
-import org.gradle.plugin.antlr.metadata.GrammarFile;
-import org.gradle.plugin.antlr.metadata.Grammar;
+import org.gradle.plugin.antlr.metadata.GrammarFileMetadata;
+import org.gradle.plugin.antlr.metadata.GrammarMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * TODO : javadoc
+ * Builder for the properly order list of {@link GenerationPlan generation plans}.
+ * <p/>
+ * IMPL NOTE : Uses recursive calls to achieve ordering.
*
* @author Steve Ebersole
*/
@@ -55,54 +57,38 @@
public synchronized List<GenerationPlan> buildGenerationPlans(XRef metadataXRef) {
this.metadataXRef = metadataXRef;
- Iterator<GrammarFile> grammarFiles = metadataXRef.iterateGrammarFiles();
+ Iterator<GrammarFileMetadata> grammarFiles = metadataXRef.iterateGrammarFiles();
while ( grammarFiles.hasNext() ) {
- final GrammarFile grammarFile = grammarFiles.next();
+ final GrammarFileMetadata grammarFileMetadata = grammarFiles.next();
// NOTE : loacteOrBuildGenerationPlan populates the generationPlans map
- loacteOrBuildGenerationPlan( grammarFile );
+ loacteOrBuildGenerationPlan( grammarFileMetadata );
}
return new ArrayList<GenerationPlan>( generationPlans.values() );
}
- private GenerationPlan loacteOrBuildGenerationPlan(GrammarFile grammarFile) {
- GenerationPlan generationPlan = generationPlans.get( grammarFile.getFileName() );
+ private GenerationPlan loacteOrBuildGenerationPlan(GrammarFileMetadata grammarFileMetadata) {
+ GenerationPlan generationPlan = generationPlans.get( grammarFileMetadata.getFilePath().getPath() );
if ( generationPlan == null ) {
- generationPlan = buildGenerationPlan( grammarFile );
+ generationPlan = buildGenerationPlan( grammarFileMetadata );
}
return generationPlan;
}
- private GenerationPlan buildGenerationPlan(GrammarFile grammarFile) {
- File generationDirectory = isEmpty( grammarFile.getPackageName() )
+ private GenerationPlan buildGenerationPlan(GrammarFileMetadata grammarFileMetadata) {
+ File generationDirectory = isEmpty( grammarFileMetadata.getPackageName() )
? outputDirectory
- : new File( outputDirectory, grammarFile.getPackageName().replace( '.', File.separatorChar ) );
+ : new File( outputDirectory, grammarFileMetadata.getPackageName().replace( '.', File.separatorChar ) );
GenerationPlan generationPlan = new GenerationPlan(
- grammarFile.getFileName(),
- new File( grammarFile.getFileName() ),
- generationDirectory,
- grammarFile.getGlibs()
+ grammarFileMetadata.getFilePath(),
+ generationDirectory
);
- File leastRecentGrammarOutput = locateLeastRecentlyModifiedOutputFile( generationDirectory );
-
- // see if the grammar is out-of-date by way super-grammars from user defined glib options
- for ( int i = 0; i < grammarFile.getGlibs().length; i++ ) {
- final GrammarFile superGrammarGrammarFile = metadataXRef.getGrammarFileByPath( grammarFile.getGlibs()[i] );
- final GenerationPlan superGrammarGenerationPlan = loacteOrBuildGenerationPlan( superGrammarGrammarFile );
- if ( superGrammarGenerationPlan.isOutOfDate() ) {
- generationPlan.markOutOfDate();
- }
- else if ( superGrammarGenerationPlan.getSource().lastModified() > leastRecentGrammarOutput.lastModified() ) {
- generationPlan.markOutOfDate();
- }
- }
-
- for ( Grammar grammar : grammarFile.getGrammars() ) {
+ for ( GrammarMetadata grammarMetadata : grammarFileMetadata.getGrammars() ) {
final File generatedParserFile = new File(
outputDirectory,
- grammar.determineGeneratedParserPath()
+ grammarMetadata.determineGeneratedParserPath()
);
if ( !generatedParserFile.exists() ) {
@@ -113,35 +99,36 @@
}
// see if the grammar if out-of-date by way of its super-grammar(s) as gleaned from parsing the grammar file
- if ( isNotEmpty( grammar.getSuperGrammarName() ) ) {
- final GrammarFile superGrammarGrammarFile = metadataXRef.getGrammarFileByClassName( grammar.getSuperGrammarName() );
- if ( superGrammarGrammarFile != null ) {
+ if ( !grammarMetadata.extendsStandardGrammar() ) {
+ final GrammarFileMetadata superGrammarGrammarFileMetadata = grammarMetadata.getSuperGrammarDelegate()
+ .getAssociatedGrammarMetadata()
+ .getGrammarFile();
+ if ( superGrammarGrammarFileMetadata != null ) {
final GenerationPlan superGrammarGenerationPlan = loacteOrBuildGenerationPlan(
- superGrammarGrammarFile
+ superGrammarGrammarFileMetadata
);
- generationPlan.addSuperGrammarId( superGrammarGenerationPlan.getId() );
if ( superGrammarGenerationPlan.isOutOfDate() ) {
generationPlan.markOutOfDate();
}
- else if ( superGrammarGenerationPlan.getSource()
- .lastModified() > generatedParserFile.lastModified() ) {
+ else if ( superGrammarGenerationPlan.getSource().lastModified()
+ > generatedParserFile.lastModified() ) {
generationPlan.markOutOfDate();
}
}
}
// see if the grammar if out-of-date by way of its importVocab
- if ( isNotEmpty( grammar.getImportVocab() ) ) {
- final GrammarFile importVocabGrammarFile = metadataXRef.getGrammarFileByExportVocab( grammar.getImportVocab() );
- if ( importVocabGrammarFile == null ) {
- log.warn( "unable to locate grammar exporting specifcied import vocab [" + grammar.getImportVocab() + "]" );
+ if ( isNotEmpty( grammarMetadata.getImportVocab() ) ) {
+ final GrammarFileMetadata importVocabGrammarFileMetadata = metadataXRef.getGrammarFileByExportVocab( grammarMetadata.getImportVocab() );
+ if ( importVocabGrammarFileMetadata == null ) {
+ log.warn( "unable to locate grammar exporting specifcied import vocab [" + grammarMetadata.getImportVocab() + "]" );
}
- else if ( importVocabGrammarFile.getFileName().equals( grammarFile.getFileName() ) ) {
+ else if ( importVocabGrammarFileMetadata.getFilePath().equals( grammarFileMetadata.getFilePath() ) ) {
}
else {
final GenerationPlan importVocabGrammarGenerationPlan = loacteOrBuildGenerationPlan(
- importVocabGrammarFile
+ importVocabGrammarFileMetadata
);
generationPlan.setImportVocabTokenTypesDirectory(
importVocabGrammarGenerationPlan.getGenerationDirectory()
@@ -169,25 +156,4 @@
return ! isEmpty( string );
}
- private static File locateLeastRecentlyModifiedOutputFile(File directory) {
- if ( !directory.exists() ) {
- return null;
- }
-
- File[] contents = directory.listFiles();
- if ( contents.length == 0 ) {
- return null;
- }
-
- File oldest = contents[0];
- for ( int i = 1; i < contents.length; i++ ) {
- if ( contents[i].lastModified() < oldest.lastModified() ) {
- oldest = contents[i];
- }
- }
-
- return oldest;
- }
-
-
}
14 years, 6 months
Hibernate SVN: r17814 - in core/trunk/annotations/src: main/java/org/hibernate/cfg and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: sharathjreddy
Date: 2009-10-21 13:16:57 -0400 (Wed, 21 Oct 2009)
New Revision: 17814
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/LocalContactDetails.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumber.java
Removed:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumberType.java
Modified:
core/trunk/annotations/src/main/java/org/hibernate/annotations/TypeDef.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/ContactDetails.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java
Log:
HHH-4512 TypeDef annotation should support both 'name' and 'defaultForType' attributes
Modified: core/trunk/annotations/src/main/java/org/hibernate/annotations/TypeDef.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/annotations/TypeDef.java 2009-10-21 08:54:18 UTC (rev 17813)
+++ core/trunk/annotations/src/main/java/org/hibernate/annotations/TypeDef.java 2009-10-21 17:16:57 UTC (rev 17814)
@@ -38,8 +38,7 @@
@Retention(RUNTIME)
public @interface TypeDef {
String name() default "";
- Class<?> typeClass();
Class<?> defaultForType() default void.class;
-
+ Class<?> typeClass();
Parameter[] parameters() default {};
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2009-10-21 08:54:18 UTC (rev 17813)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2009-10-21 17:16:57 UTC (rev 17814)
@@ -1006,19 +1006,20 @@
}
if (BinderHelper.isDefault(defAnn.name()) && defAnn.defaultForType().equals(void.class)) {
- throw new AnnotationException("Both name and defaultForType attributes cannot be set in a TypeDef");
+ throw new AnnotationException(
+ "Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass " +
+ defAnn.typeClass().getName());
}
+
if (!BinderHelper.isDefault(defAnn.name())) {
log.info( "Binding type definition: {}", defAnn.name() );
mappings.addTypeDef( defAnn.name(), defAnn.typeClass().getName(), params );
}
- else if (!defAnn.defaultForType().equals(void.class)) {
+ if (!defAnn.defaultForType().equals(void.class)) {
log.info( "Binding type definition: {}", defAnn.defaultForType().getName() );
mappings.addTypeDef( defAnn.defaultForType().getName(), defAnn.typeClass().getName(), params );
}
- else {
- throw new AnnotationException("Either name or defaultForType attribute should be set in a TypeDef");
- }
+
}
Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java 2009-10-21 08:54:18 UTC (rev 17813)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java 2009-10-21 17:16:57 UTC (rev 17814)
@@ -28,11 +28,13 @@
import java.util.Currency;
import java.util.Date;
+import org.hibernate.AnnotationException;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
+import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.test.annotations.TestCase;
/**
@@ -403,18 +405,12 @@
}
- /**
- * We persist and retrieve properties of type 'PhoneNumber'. We set this type to delegate to
- * the Hibernate UserType 'PhoneNumberType' for persistence and retrieval (with the 'defaultForType' attribute).
- * However, we can also use the @TypeDef 'name' attribute and @Type annotation to over-ride this and
- * delegate to OverseasPhoneNumberType.
- *
- */
- public void testTypeDefsUsingNameAndDefaultForType() {
+ public void testTypeDefNameAndDefaultForTypeAttributes() {
ContactDetails contactDetails = new ContactDetails();
contactDetails.setLocalPhoneNumber(new PhoneNumber("999999"));
- contactDetails.setOverseasPhoneNumber(new PhoneNumber("111111"));
+ contactDetails.setOverseasPhoneNumber(
+ new OverseasPhoneNumber("041", "111111"));
Session s = openSession();
Transaction tx = s.beginTransaction();
@@ -432,13 +428,26 @@
s.delete(contactDetails);
tx.commit();
s.close();
+
+ }
+
+ public void testTypeDefWithoutNameAndDefaultForTypeAttributes() {
+ try {
+ AnnotationConfiguration config = new AnnotationConfiguration();
+ config.addAnnotatedClass(LocalContactDetails.class);
+ config.buildSessionFactory();
+ fail("Did not throw expected exception");
+ }
+ catch( AnnotationException ex ) {
+ assertEquals(
+ "Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass org.hibernate.test.annotations.entity.PhoneNumberType",
+ ex.getMessage());
+ }
-
}
+
-
-
/**
* A custom type is used in the base class, but defined in the derived class.
* This would have caused an exception, because the base class is processed
Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/ContactDetails.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/ContactDetails.java 2009-10-21 08:54:18 UTC (rev 17813)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/ContactDetails.java 2009-10-21 17:16:57 UTC (rev 17814)
@@ -26,25 +26,13 @@
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
-
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
-import org.hibernate.annotations.TypeDefs;
-
-@TypeDefs(
- {
- @TypeDef(
- name = "overseasPhoneNumber",
- typeClass = OverseasPhoneNumberType.class
-
- ),
- @TypeDef(
- defaultForType = PhoneNumber.class,
- typeClass = PhoneNumberType.class
-
- )
- }
+@TypeDef(
+ name = "phoneNumber",
+ defaultForType = PhoneNumber.class,
+ typeClass = PhoneNumberType.class
)
/**
@@ -59,8 +47,8 @@
private int id;
private PhoneNumber localPhoneNumber;
- @Type(type="overseasPhoneNumber")
- private PhoneNumber overseasPhoneNumber;
+ @Type(type="phoneNumber")
+ private OverseasPhoneNumber overseasPhoneNumber;
public int getId() {
return id;
@@ -74,16 +62,11 @@
public void setLocalPhoneNumber(PhoneNumber localPhoneNumber) {
this.localPhoneNumber = localPhoneNumber;
}
- public PhoneNumber getOverseasPhoneNumber() {
+ public OverseasPhoneNumber getOverseasPhoneNumber() {
return overseasPhoneNumber;
}
- public void setOverseasPhoneNumber(PhoneNumber overseasPhoneNumber) {
+ public void setOverseasPhoneNumber(OverseasPhoneNumber overseasPhoneNumber) {
this.overseasPhoneNumber = overseasPhoneNumber;
}
-
-
-
-
-
}
Added: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/LocalContactDetails.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/LocalContactDetails.java (rev 0)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/LocalContactDetails.java 2009-10-21 17:16:57 UTC (rev 17814)
@@ -0,0 +1,70 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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, Inc.
+ *
+ * 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.test.annotations.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
+
+@TypeDef(
+ typeClass = PhoneNumberType.class
+)
+
+/**
+ * @author Sharath Reddy
+ *
+ */
+@Entity
+public class LocalContactDetails {
+
+ @Id
+ @GeneratedValue
+ private int id;
+
+ private PhoneNumber localPhoneNumber;
+ @Type(type="phoneNumber")
+ private OverseasPhoneNumber overseasPhoneNumber;
+
+ public int getId() {
+ return id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+ public PhoneNumber getLocalPhoneNumber() {
+ return localPhoneNumber;
+ }
+ public void setLocalPhoneNumber(PhoneNumber localPhoneNumber) {
+ this.localPhoneNumber = localPhoneNumber;
+ }
+ public OverseasPhoneNumber getOverseasPhoneNumber() {
+ return overseasPhoneNumber;
+ }
+ public void setOverseasPhoneNumber(OverseasPhoneNumber overseasPhoneNumber) {
+ this.overseasPhoneNumber = overseasPhoneNumber;
+ }
+
+}
Added: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumber.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumber.java (rev 0)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumber.java 2009-10-21 17:16:57 UTC (rev 17814)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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, Inc.
+ *
+ * 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.test.annotations.entity;
+
+/**
+ * @author Sharath Reddy
+ */
+public class OverseasPhoneNumber extends PhoneNumber {
+
+ public OverseasPhoneNumber(String areaCode, String val) {
+ super(areaCode + val);
+ }
+
+ public OverseasPhoneNumber(String val) {
+ super(val);
+ }
+
+}
Deleted: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumberType.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumberType.java 2009-10-21 08:54:18 UTC (rev 17813)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumberType.java 2009-10-21 17:16:57 UTC (rev 17814)
@@ -1,98 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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.test.annotations.entity;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import org.hibernate.HibernateException;
-import org.hibernate.usertype.UserType;
-
-/**
- * Used to persist and retrieve objects of type 'PhoneNumber'
- *
- * @author Sharath Reddy
- */
-public class OverseasPhoneNumberType implements UserType {
-
- public int[] sqlTypes() {
- return new int[]{Types.VARCHAR};
- }
-
- public Class returnedClass() {
- return PhoneNumber.class;
- }
-
- public boolean equals(Object x, Object y) throws HibernateException {
- return ( x == y ) || ( x != null && x.equals( y ) );
- }
-
- public int hashCode(Object x) throws HibernateException {
- return x.hashCode();
- }
-
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
- String result = rs.getString( names[0] );
- if ( rs.wasNull() ) return null;
- return new PhoneNumber(result);
- }
-
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
- if ( value == null ) {
- st.setNull( index, sqlTypes()[0] );
- }
- else {
- PhoneNumber phoneNumber = (PhoneNumber) value;
- st.setString( index, getCountryCode() + phoneNumber.getNumber() );
- }
- }
-
-
- private String getCountryCode() {
- return "041";
- }
-
- public Object deepCopy(Object value) throws HibernateException {
- return value;
- }
-
- public boolean isMutable() {
- return false;
- }
-
- public Serializable disassemble(Object value) throws HibernateException {
- return (Serializable) value;
- }
-
- public Object assemble(Serializable cached, Object owner) throws HibernateException {
- return cached;
- }
-
- public Object replace(Object original, Object target, Object owner) throws HibernateException {
- return original;
- }
-
-}
Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java 2009-10-21 08:54:18 UTC (rev 17813)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java 2009-10-21 17:16:57 UTC (rev 17814)
@@ -42,7 +42,7 @@
return new int[]{Types.VARCHAR};
}
- public Class returnedClass() {
+ public Class<?> returnedClass() {
return PhoneNumber.class;
}
@@ -57,17 +57,24 @@
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
String result = rs.getString( names[0] );
if ( rs.wasNull() ) return null;
- return new PhoneNumber(result);
+
+ if (result.length() <= 6) {
+ return new PhoneNumber(result);
+ }
+ else {
+ return new OverseasPhoneNumber(result);
+ }
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
if ( value == null ) {
st.setNull( index, sqlTypes()[0] );
+ return;
}
- else {
- PhoneNumber phoneNumber = (PhoneNumber) value;
- st.setString( index, phoneNumber.getNumber() );
- }
+
+ PhoneNumber phoneNumber = (PhoneNumber) value;
+ String number = phoneNumber.getNumber();
+ st.setString( index, number);
}
public Object deepCopy(Object value) throws HibernateException {
14 years, 6 months
Hibernate SVN: r17813 - core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver.
by hibernate-commits@lists.jboss.org
Author: jcosta(a)redhat.com
Date: 2009-10-21 04:54:18 -0400 (Wed, 21 Oct 2009)
New Revision: 17813
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
Log:
HHH-4508 - Restored original version in CP branch
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java 2009-10-21 08:46:47 UTC (rev 17812)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java 2009-10-21 08:54:18 UTC (rev 17813)
@@ -104,7 +104,7 @@
public static Dialect buildDialect(Properties properties) {
String dialectName = properties.getProperty( Environment.DIALECT );
if ( dialectName == null ) {
- throw new HibernateException( "'hibernate.dialect' must be set when no Connection available" );
+ throw new HibernateException( "'hibernate.dialect' must be set when no Connection avalable" );
}
return constructDialect( dialectName );
}
14 years, 6 months
Hibernate SVN: r17812 - core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver.
by hibernate-commits@lists.jboss.org
Author: jcosta(a)redhat.com
Date: 2009-10-21 04:46:47 -0400 (Wed, 21 Oct 2009)
New Revision: 17812
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
Log:
HHH-4508 - An extra char was wrongly included in the commit
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java 2009-10-21 04:03:22 UTC (rev 17811)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java 2009-10-21 08:46:47 UTC (rev 17812)
@@ -1,4 +1,4 @@
-a/*
+/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
14 years, 6 months
Hibernate SVN: r17811 - in core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src: main/java/org/hibernate/cache/jbc2/access and 9 other directories.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2009-10-21 00:03:22 -0400 (Wed, 21 Oct 2009)
New Revision: 17811
Modified:
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractGeneralDataRegionTestCase.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractJBossCacheTestCase.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractTransactionalAccessTestCase.java
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/bulk/PessimisticBulkOperationsTest.java
Log:
JBPAPP-2957 HHH-3818 Hibernate/JBC integration doesn't property handle Entity/CollectionRegionAccessStrategy evict
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -23,9 +23,13 @@
*/
package org.hibernate.cache.jbc2;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
@@ -42,7 +46,12 @@
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Option;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
-import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeInvalidated;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.ViewChanged;
+import org.jboss.cache.notifications.event.NodeInvalidatedEvent;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.ViewChangedEvent;
import org.jboss.cache.optimistic.DataVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,30 +62,52 @@
*
* @author Steve Ebersole
*/
-@CacheListener
public abstract class BasicRegionAdapter implements Region {
+ private enum InvalidateState { INVALID, CLEARING, VALID };
public static final String ITEM = CacheHelper.ITEM;
protected final Cache jbcCache;
protected final String regionName;
protected final Fqn regionFqn;
+ protected final Fqn internalFqn;
protected Node regionRoot;
protected final boolean optimistic;
protected final TransactionManager transactionManager;
protected final Logger log;
protected final Object regionRootMutex = new Object();
+ protected final Object memberId;
+ protected final boolean replication;
+ protected final Object invalidationMutex = new Object();
+ protected final AtomicReference<InvalidateState> invalidateState =
+ new AtomicReference<InvalidateState>(InvalidateState.VALID);
+ protected final Set<Object> currentView = new HashSet<Object>();
// protected RegionRootListener listener;
public BasicRegionAdapter(Cache jbcCache, String regionName, String regionPrefix) {
+
+ this.log = LoggerFactory.getLogger(getClass());
+
this.jbcCache = jbcCache;
this.transactionManager = jbcCache.getConfiguration().getRuntimeConfig().getTransactionManager();
this.regionName = regionName;
this.regionFqn = createRegionFqn(regionName, regionPrefix);
- optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
- log = LoggerFactory.getLogger(getClass());
+ this.internalFqn = CacheHelper.getInternalFqn(regionFqn);
+ this.optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
+ this.memberId = jbcCache.getLocalAddress();
+ this.replication = CacheHelper.isClusteredReplication(jbcCache);
+
+ this.jbcCache.addCacheListener(this);
+
+ synchronized (currentView) {
+ List view = jbcCache.getMembers();
+ if (view != null) {
+ currentView.addAll(view);
+ }
+ }
+
activateLocalClusterNode();
log.debug("Created Region for " + regionName + " -- regionPrefix is " + regionPrefix);
@@ -129,13 +160,13 @@
if (!regionRoot.isResident()) {
regionRoot.setResident(true);
}
+ establishInternalNodes();
}
catch (Exception e) {
throw new CacheException(e.getMessage(), e);
}
finally {
- if (tx != null)
- resume(tx);
+ resume(tx);
}
}
@@ -154,6 +185,7 @@
// For pessimistic locking, we just want to toss out our ref
// to any old invalid root node and get the latest (may be null)
if (!optimistic) {
+ establishInternalNodes();
regionRoot = jbcCache.getRoot().getChild( regionFqn );
return;
}
@@ -181,6 +213,7 @@
}
// Never evict this node
newRoot.setResident(true);
+ establishInternalNodes();
}
finally {
resume(tx);
@@ -189,6 +222,24 @@
}
}
+ private void establishInternalNodes()
+ {
+ synchronized (currentView) {
+ Transaction tx = suspend();
+ try {
+ for (Object member : currentView) {
+ DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null;
+ Fqn f = Fqn.fromRelativeElements(internalFqn, member);
+ CacheHelper.addNode(jbcCache, f, true, false, version);
+ }
+ }
+ finally {
+ resume(tx);
+ }
+ }
+
+ }
+
public String getName() {
return regionName;
}
@@ -201,6 +252,11 @@
return regionFqn;
}
+ public Object getMemberId()
+ {
+ return this.memberId;
+ }
+
/**
* Checks for the validity of the root cache node for this region,
* creating a new one if it does not exist or is invalid, and also
@@ -219,6 +275,37 @@
if (regionRoot != null && regionRoot.isValid() && !regionRoot.isResident())
regionRoot.setResident(true);
}
+
+ public boolean checkValid()
+ {
+ boolean valid = invalidateState.get() == InvalidateState.VALID;
+
+ if (!valid) {
+ synchronized (invalidationMutex) {
+ if (invalidateState.compareAndSet(InvalidateState.INVALID, InvalidateState.CLEARING)) {
+ Transaction tx = suspend();
+ try {
+ Option opt = new Option();
+ opt.setLockAcquisitionTimeout(1);
+ opt.setCacheModeLocal(true);
+ CacheHelper.removeAll(jbcCache, regionFqn, opt);
+ invalidateState.compareAndSet(InvalidateState.CLEARING, InvalidateState.VALID);
+ }
+ catch (Exception e) {
+ if (log.isTraceEnabled()) {
+ log.trace("Could not invalidate region: " + e.getLocalizedMessage());
+ }
+ }
+ finally {
+ resume(tx);
+ }
+ }
+ }
+ valid = invalidateState.get() == InvalidateState.VALID;
+ }
+
+ return valid;
+ }
public void destroy() throws CacheException {
try {
@@ -242,10 +329,9 @@
} catch (Exception e) {
throw new CacheException(e);
}
-// finally {
-// if (listener != null)
-// jbcCache.removeCacheListener(listener);
-// }
+ finally {
+ jbcCache.removeCacheListener(this);
+ }
}
protected void deactivateLocalNode() {
@@ -256,18 +342,50 @@
}
}
+ public boolean contains(Object key) {
+ if ( !checkValid() ) {
+ return false;
+ }
+
+ try {
+ Option opt = new Option();
+ opt.setLockAcquisitionTimeout(100);
+ CacheHelper.setInvocationOption( jbcCache, opt );
+ return CacheHelper.getAllowingTimeout( jbcCache, regionFqn, key ) != null;
+ }
+ catch ( CacheException ce ) {
+ throw ce;
+ }
+ catch ( Throwable t ) {
+ throw new CacheException( t );
+ }
+ }
+
public long getSizeInMemory() {
// not supported
return -1;
}
public long getElementCountInMemory() {
- try {
- Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
- return childrenNames.size();
- } catch (Exception e) {
- throw new CacheException(e);
+ if (checkValid()) {
+ try {
+ Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
+ int size = childrenNames.size();
+ if (childrenNames.contains(CacheHelper.Internal.NODE)) {
+ size--;
+ }
+ return size;
+ }
+ catch ( CacheException ce ) {
+ throw ce;
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
}
+ else {
+ return 0;
+ }
}
public long getElementCountOnDisk() {
@@ -275,18 +393,25 @@
}
public Map toMap() {
- try {
- Map result = new HashMap();
- Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
- for (Object childName : childrenNames) {
- result.put(childName, CacheHelper.get(jbcCache,regionFqn, childName));
- }
- return result;
- } catch (CacheException e) {
- throw e;
- } catch (Exception e) {
- throw new CacheException(e);
+ if (checkValid()) {
+ try {
+ Map result = new HashMap();
+ Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
+ for (Object childName : childrenNames) {
+ if (CacheHelper.Internal.NODE != childName) {
+ result.put(childName, CacheHelper.get(jbcCache,regionFqn, childName));
+ }
+ }
+ return result;
+ } catch (CacheException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new CacheException(e);
+ }
}
+ else {
+ return Collections.emptyMap();
+ }
}
public long nextTimestamp() {
@@ -327,7 +452,7 @@
* @return the transaction that was suspended, or <code>null</code> if
* there wasn't one
*/
- protected Transaction suspend() {
+ public Transaction suspend() {
Transaction tx = null;
try {
if (transactionManager != null) {
@@ -345,7 +470,7 @@
* @param tx
* the transaction to suspend. May be <code>null</code>.
*/
- protected void resume(Transaction tx) {
+ public void resume(Transaction tx) {
try {
if (tx != null)
transactionManager.resume(tx);
@@ -404,17 +529,52 @@
return escaped;
}
-// @CacheListener
-// public class RegionRootListener {
-//
-// @NodeCreated
-// public void nodeCreated(NodeCreatedEvent event) {
-// if (!event.isPre() && event.getFqn().equals(getRegionFqn())) {
-// log.debug("Node created for " + getRegionFqn());
-// Node regionRoot = jbcCache.getRoot().getChild(getRegionFqn());
-// regionRoot.setResident(true);
-// }
-// }
-//
-// }
+ @NodeModified
+ public void nodeModified(NodeModifiedEvent event)
+ {
+ handleEvictAllModification(event);
+ }
+
+ protected boolean handleEvictAllModification(NodeModifiedEvent event) {
+
+ if (!event.isPre() && (replication || event.isOriginLocal()) && event.getData().containsKey(ITEM))
+ {
+ if (event.getFqn().isChildOf(internalFqn))
+ {
+ invalidateState.set(InvalidateState.INVALID);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @NodeInvalidated
+ public void nodeInvalidated(NodeInvalidatedEvent event)
+ {
+ handleEvictAllInvalidation(event);
+ }
+
+ protected boolean handleEvictAllInvalidation(NodeInvalidatedEvent event)
+ {
+ if (!event.isPre() && event.getFqn().isChildOf(internalFqn))
+ {
+ invalidateState.set(InvalidateState.INVALID);
+ return true;
+ }
+ return false;
+ }
+
+ @ViewChanged
+ public void viewChanged(ViewChangedEvent event) {
+
+ synchronized (currentView) {
+ List view = event.getNewView().getMembers();
+ if (view != null) {
+ currentView.addAll(view);
+ establishInternalNodes();
+ }
+ }
+
+ }
+
}
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -23,11 +23,12 @@
*/
package org.hibernate.cache.jbc2.access;
+import javax.transaction.Transaction;
+
import org.hibernate.cache.CacheDataDescription;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.jbc2.BasicRegionAdapter;
import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
import org.hibernate.cache.jbc2.util.CacheHelper;
import org.hibernate.cache.jbc2.util.DataVersionAdapter;
@@ -75,22 +76,17 @@
* by adding a {@link NonLockingDataVersion} to the invocation.
*/
@Override
- public void evictAll() throws CacheException {
-
- evictOrRemoveAll();
- }
-
- /**
- * Overrides the {@link TransactionalAccessDelegate#get(Object, long) superclass}
- * by {@link BasicRegionAdapter#ensureRegionRootExists() ensuring the root
- * node for the region exists} before making the call.
- */
- @Override
- public Object get(Object key, long txTimestamp) throws CacheException
+ public void evictAll() throws CacheException
{
- region.ensureRegionRootExists();
-
- return CacheHelper.get(cache, regionFqn, key);
+ Transaction tx = region.suspend();
+ try {
+ region.ensureRegionRootExists();
+ Option opt = NonLockingDataVersion.getInvocationOption();
+ CacheHelper.sendEvictAllNotification(cache, regionFqn, region.getMemberId(), opt);
+ }
+ finally {
+ region.resume(tx);
+ }
}
/**
@@ -100,6 +96,9 @@
*/
@Override
public boolean insert(Object key, Object value, Object version) throws CacheException {
+
+ if (!region.checkValid())
+ return false;
region.ensureRegionRootExists();
@@ -111,6 +110,9 @@
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
+
+ if (!region.checkValid())
+ return false;
region.ensureRegionRootExists();
@@ -123,6 +125,9 @@
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+
+ if (!region.checkValid())
+ return false;
region.ensureRegionRootExists();
@@ -132,6 +137,10 @@
@Override
public void remove(Object key) throws CacheException {
+
+ // We remove whether or not the region is valid. Other nodes
+ // may have already restored the region so they need to
+ // be informed of the change.
region.ensureRegionRootExists();
@@ -141,14 +150,18 @@
@Override
public void removeAll() throws CacheException {
-
- evictOrRemoveAll();
+ Option opt = NonLockingDataVersion.getInvocationOption();
+ CacheHelper.removeAll(cache, regionFqn, opt);
}
@Override
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
+ // We update whether or not the region is valid. Other nodes
+ // may have already restored the region so they need to
+ // be informed of the change.
+
region.ensureRegionRootExists();
Option opt = getDataVersionOption(currentVersion, previousVersion);
@@ -166,10 +179,4 @@
return opt;
}
- private void evictOrRemoveAll() {
-
- Option opt = NonLockingDataVersion.getInvocationOption();
- CacheHelper.removeAll(cache, regionFqn, opt);
- }
-
}
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -23,6 +23,8 @@
*/
package org.hibernate.cache.jbc2.access;
+import javax.transaction.Transaction;
+
import org.hibernate.cache.CacheException;
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.access.EntityRegionAccessStrategy;
@@ -56,14 +58,20 @@
}
public Object get(Object key, long txTimestamp) throws CacheException {
-
+
+ if (!region.checkValid())
+ return null;
+
region.ensureRegionRootExists();
return CacheHelper.get(cache, regionFqn, key);
}
- public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+ if (!region.checkValid())
+ return false;
+
region.ensureRegionRootExists();
return CacheHelper.putForExternalRead(cache, regionFqn, key, value);
@@ -72,6 +80,9 @@
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
+ if (!region.checkValid())
+ return false;
+
region.ensureRegionRootExists();
// We ignore minimalPutOverride. JBossCache putForExternalRead is
@@ -96,6 +107,9 @@
public boolean insert(Object key, Object value, Object version) throws CacheException {
+ if (!region.checkValid())
+ return false;
+
region.ensureRegionRootExists();
CacheHelper.put(cache, regionFqn, key, value);
@@ -109,6 +123,10 @@
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
+ // We update whether or not the region is valid. Other nodes
+ // may have already restored the region so they need to
+ // be informed of the change.
+
region.ensureRegionRootExists();
CacheHelper.put(cache, regionFqn, key, value);
@@ -122,13 +140,17 @@
public void remove(Object key) throws CacheException {
+ // We remove whether or not the region is valid. Other nodes
+ // may have already restored the region so they need to
+ // be informed of the change.
+
region.ensureRegionRootExists();
CacheHelper.remove(cache, regionFqn, key);
}
public void removeAll() throws CacheException {
- evictOrRemoveAll();
+ CacheHelper.removeAll(cache, regionFqn);
}
public void evict(Object key) throws CacheException {
@@ -139,10 +161,15 @@
}
public void evictAll() throws CacheException {
- evictOrRemoveAll();
+ Transaction tx = region.suspend();
+ try {
+ region.ensureRegionRootExists();
+
+ CacheHelper.sendEvictAllNotification(cache, regionFqn, region.getMemberId(), null);
+ }
+ finally {
+ region.resume(tx);
+ }
}
- private void evictOrRemoveAll() throws CacheException {
- CacheHelper.removeAll(cache, regionFqn);
- }
}
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -26,6 +26,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.notifications.annotation.CacheListener;
import org.hibernate.cache.CacheDataDescription;
import org.hibernate.cache.CacheException;
@@ -39,6 +40,7 @@
*
* @author Steve Ebersole
*/
+@CacheListener
public class CollectionRegionImpl extends TransactionalDataRegionAdapter implements CollectionRegion {
public static final String TYPE = "COLL";
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -26,6 +26,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.notifications.annotation.CacheListener;
import org.hibernate.cache.CacheDataDescription;
import org.hibernate.cache.CacheException;
@@ -39,6 +40,7 @@
*
* @author Steve Ebersole
*/
+@CacheListener
public class EntityRegionImpl extends TransactionalDataRegionAdapter implements EntityRegion {
public static final String TYPE = "ENTITY";
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -25,6 +25,8 @@
import java.util.Properties;
+import javax.transaction.Transaction;
+
import org.hibernate.cache.CacheException;
import org.hibernate.cache.QueryResultsRegion;
import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
@@ -33,6 +35,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Option;
+import org.jboss.cache.notifications.annotation.CacheListener;
/**
* Defines the behavior of the query cache regions for JBossCache 2.x.
@@ -40,6 +43,7 @@
* @author Brian Stansberry
* @version $Revision$
*/
+@CacheListener
public class QueryResultsRegionImpl extends TransactionalDataRegionAdapter implements QueryResultsRegion {
public static final String QUERY_CACHE_LOCAL_ONLY_PROP = "hibernate.cache.region.jbc2.query.localonly";
@@ -85,14 +89,22 @@
}
public void evictAll() throws CacheException {
- Option opt = getNonLockingDataVersionOption(false);
- if (localOnly)
- opt.setCacheModeLocal(true);
- CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
+ Transaction tx = suspend();
+ try {
+ ensureRegionRootExists();
+ Option opt = getNonLockingDataVersionOption(true);
+ CacheHelper.sendEvictAllNotification(jbcCache, regionFqn, getMemberId(), opt);
+ }
+ finally {
+ resume(tx);
+ }
}
public Object get(Object key) throws CacheException {
+ if (!checkValid())
+ return null;
+
ensureRegionRootExists();
// Don't hold the JBC node lock throughout the tx, as that
@@ -106,28 +118,30 @@
public void put(Object key, Object value) throws CacheException {
- ensureRegionRootExists();
-
- // Here we don't want to suspend the tx. If we do:
- // 1) We might be caching query results that reflect uncommitted
- // changes. No tx == no WL on cache node, so other threads
- // can prematurely see those query results
- // 2) No tx == immediate replication. More overhead, plus we
- // spread issue #1 above around the cluster
-
- // Add a zero (or quite low) timeout option so we don't block.
- // Ignore any TimeoutException. Basically we forego caching the
- // query result in order to avoid blocking.
- // Reads are done with suspended tx, so they should not hold the
- // lock for long. Not caching the query result is OK, since
- // any subsequent read will just see the old result with its
- // out-of-date timestamp; that result will be discarded and the
- // db query performed again.
- Option opt = getNonLockingDataVersionOption(false);
- opt.setLockAcquisitionTimeout(2);
- if (localOnly)
- opt.setCacheModeLocal(true);
- CacheHelper.putAllowingTimeout(getCacheInstance(), getRegionFqn(), key, value, opt);
+ if (checkValid()) {
+ ensureRegionRootExists();
+
+ // Here we don't want to suspend the tx. If we do:
+ // 1) We might be caching query results that reflect uncommitted
+ // changes. No tx == no WL on cache node, so other threads
+ // can prematurely see those query results
+ // 2) No tx == immediate replication. More overhead, plus we
+ // spread issue #1 above around the cluster
+
+ // Add a zero (or quite low) timeout option so we don't block.
+ // Ignore any TimeoutException. Basically we forego caching the
+ // query result in order to avoid blocking.
+ // Reads are done with suspended tx, so they should not hold the
+ // lock for long. Not caching the query result is OK, since
+ // any subsequent read will just see the old result with its
+ // out-of-date timestamp; that result will be discarded and the
+ // db query performed again.
+ Option opt = getNonLockingDataVersionOption(false);
+ opt.setLockAcquisitionTimeout(2);
+ if (localOnly)
+ opt.setCacheModeLocal(true);
+ CacheHelper.putAllowingTimeout(getCacheInstance(), getRegionFqn(), key, value, opt);
+ }
}
@Override
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -41,6 +41,7 @@
import org.jboss.cache.notifications.annotation.CacheListener;
import org.jboss.cache.notifications.annotation.NodeModified;
import org.jboss.cache.notifications.annotation.NodeRemoved;
+import org.jboss.cache.notifications.event.NodeInvalidatedEvent;
import org.jboss.cache.notifications.event.NodeModifiedEvent;
import org.jboss.cache.notifications.event.NodeRemovedEvent;
@@ -95,14 +96,21 @@
public void evictAll() throws CacheException {
// TODO Is this a valid operation on a timestamps cache?
- Option opt = getNonLockingDataVersionOption(true);
- CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
+ Transaction tx = suspend();
+ try {
+ ensureRegionRootExists();
+ Option opt = getNonLockingDataVersionOption(true);
+ CacheHelper.sendEvictAllNotification(jbcCache, regionFqn, getMemberId(), opt);
+ }
+ finally {
+ resume(tx);
+ }
}
public Object get(Object key) throws CacheException {
Object value = localCache.get(key);
- if (value == null) {
+ if (value == null && checkValid()) {
ensureRegionRootExists();
@@ -147,14 +155,15 @@
*/
@NodeModified
public void nodeModified(NodeModifiedEvent event) {
- if (event.isPre())
- return;
-
- Fqn fqn = event.getFqn();
- Fqn regFqn = getRegionFqn();
- if (fqn.size() == regFqn.size() + 1 && fqn.isChildOf(regFqn)) {
- Object key = fqn.get(regFqn.size());
- localCache.put(key, event.getData().get(ITEM));
+
+ if (!handleEvictAllModification(event) && !event.isPre()) {
+
+ Fqn fqn = event.getFqn();
+ Fqn regFqn = getRegionFqn();
+ if (fqn.size() == regFqn.size() + 1 && fqn.isChildOf(regFqn)) {
+ Object key = fqn.get(regFqn.size());
+ localCache.put(key, event.getData().get(ITEM));
+ }
}
}
@@ -178,8 +187,30 @@
localCache.clear();
}
}
+
+
- /**
+ @Override
+ protected boolean handleEvictAllInvalidation(NodeInvalidatedEvent event)
+ {
+ boolean result = super.handleEvictAllInvalidation(event);
+ if (result) {
+ localCache.clear();
+ }
+ return result;
+ }
+
+ @Override
+ protected boolean handleEvictAllModification(NodeModifiedEvent event)
+ {
+ boolean result = super.handleEvictAllModification(event);
+ if (result) {
+ localCache.clear();
+ }
+ return result;
+ }
+
+ /**
* Brings all data from the distributed cache into our local cache.
*/
private void populateLocalCache() {
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -46,6 +46,8 @@
*/
public class CacheHelper {
+ public static enum Internal { NODE, LOCAL };
+
/** Key under which items are cached */
public static final String ITEM = "item";
/** Key and value used in a hack to create region root nodes */
@@ -467,4 +469,23 @@
option.setDataVersion(version);
setInvocationOption(cache, option);
}
+
+ public static Fqn getInternalFqn(Fqn region)
+ {
+ return Fqn.fromRelativeElements(region, Internal.NODE);
+ }
+
+ public static void sendEvictNotification(Cache cache, Fqn region, Object member, Object key, Option option)
+ {
+ setInvocationOption(cache, option);
+ Fqn f = Fqn.fromRelativeElements(region, Internal.NODE, member == null ? Internal.LOCAL : member, key);
+ cache.put(f, ITEM, DUMMY);
+ }
+
+ public static void sendEvictAllNotification(Cache cache, Fqn region, Object member, Option option)
+ {
+ setInvocationOption(cache, option);
+ Fqn f = Fqn.fromRelativeElements(region, Internal.NODE, member == null ? Internal.LOCAL : member);
+ cache.put(f, ITEM, DUMMY);
+ }
}
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractGeneralDataRegionTestCase.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractGeneralDataRegionTestCase.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractGeneralDataRegionTestCase.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -24,9 +24,7 @@
package org.hibernate.test.cache.jbc2;
import java.util.Iterator;
-import java.util.Set;
-import org.hibernate.cache.CacheException;
import org.hibernate.cache.GeneralDataRegion;
import org.hibernate.cache.QueryResultsRegion;
import org.hibernate.cache.Region;
@@ -171,8 +169,7 @@
Node regionRoot = localCache.getRoot().getChild(regionFqn);
assertFalse(regionRoot == null);
- Set children = regionRoot.getChildrenNames();
- assertEquals("No children in " + children, 0, children.size());
+ assertEquals("No children in " + regionRoot, 0, getValidChildrenCount(regionRoot));
assertTrue(regionRoot.isResident());
if (optimistic) {
@@ -181,7 +178,7 @@
regionRoot = remoteCache.getRoot().getChild(regionFqn);
assertFalse(regionRoot == null);
- assertEquals(0, regionRoot.getChildrenNames().size());
+ assertEquals(0, getValidChildrenCount(regionRoot));
assertTrue(regionRoot.isResident());
if (optimistic) {
@@ -212,35 +209,24 @@
localRegion.evictAll();
- // This should re-establish the region root node in the optimistic case
+ // This should re-establish the region root node
assertNull(localRegion.get(KEY));
regionRoot = localCache.getRoot().getChild(regionFqn);
- if (optimistic) {
- assertFalse(regionRoot == null);
- assertEquals(0, regionRoot.getChildrenNames().size());
- assertTrue(regionRoot.isValid());
- assertTrue(regionRoot.isResident());
- }
- else {
- assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
- }
+ assertFalse(regionRoot == null);
+ assertEquals(0, getValidChildrenCount(regionRoot));
+ assertTrue(regionRoot.isValid());
+ assertTrue(regionRoot.isResident());
// Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish
- // This only adds a node in the case of optimistic locking
assertEquals(null, remoteRegion.get(KEY));
regionRoot = remoteCache.getRoot().getChild(regionFqn);
- if (optimistic) {
- assertFalse(regionRoot == null);
- assertEquals(0, regionRoot.getChildrenNames().size());
- assertTrue(regionRoot.isValid());
- assertTrue(regionRoot.isResident());
- }
- else {
- assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
- }
+ assertFalse(regionRoot == null);
+ assertEquals(0, getValidChildrenCount(regionRoot));
+ assertTrue(regionRoot.isValid());
+ assertTrue(regionRoot.isResident());
assertEquals("local is clean", null, localRegion.get(KEY));
assertEquals("remote is clean", null, remoteRegion.get(KEY));
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractJBossCacheTestCase.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractJBossCacheTestCase.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractJBossCacheTestCase.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -25,10 +25,14 @@
+import java.util.Set;
+
import org.hibernate.cache.RegionFactory;
+import org.hibernate.cache.jbc2.util.CacheHelper;
import org.hibernate.junit.UnitTestCase;
import org.hibernate.test.util.CacheTestSupport;
import org.jboss.cache.Cache;
+import org.jboss.cache.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -96,4 +100,15 @@
protected void avoidConcurrentFlush() {
testSupport.avoidConcurrentFlush();
}
+
+ protected int getValidChildrenCount(Node node) {
+ int result = 0;
+ Set<Node> children = node.getChildren();
+ for (Node child : children) {
+ if (node.isValid() && CacheHelper.Internal.NODE.equals(child.getFqn().getLastElement()) == false) {
+ result++;
+ }
+ }
+ return result;
+ }
}
\ No newline at end of file
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -471,38 +471,27 @@
localAccessStrategy.evictAll();
else
localAccessStrategy.removeAll();
-
- // This should re-establish the region root node in the optimistic case
+
+ // This should re-establish the region root node
assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis()));
regionRoot = localCache.getRoot().getChild(regionFqn);
- if (isUsingOptimisticLocking()) {
- assertFalse(regionRoot == null);
- assertEquals(0, getValidChildrenCount(regionRoot));
- assertTrue(regionRoot.isValid());
- assertTrue(regionRoot.isResident());
- }
- else {
- assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
- }
+ assertFalse(regionRoot == null);
+ assertEquals(0, getValidChildrenCount(regionRoot));
+ assertTrue(regionRoot.isValid());
+ assertTrue(regionRoot.isResident());
// Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish
- // This only adds a node in the case of optimistic locking
assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
regionRoot = remoteCache.getRoot().getChild(regionFqn);
- if (isUsingOptimisticLocking()) {
- assertFalse(regionRoot == null);
- assertTrue(regionRoot.isValid());
- assertTrue(regionRoot.isResident());
- // Not invalidation, so we didn't insert a child above
- assertEquals(0, getValidChildrenCount(regionRoot));
- }
- else {
- assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
- }
-
+ assertFalse(regionRoot == null);
+ assertTrue(regionRoot.isValid());
+ assertTrue(regionRoot.isResident());
+ // Not invalidation, so we didn't insert a child above
+ assertEquals(0, getValidChildrenCount(regionRoot));
+
// Test whether the get above messes up the optimistic version
remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
@@ -521,17 +510,7 @@
assertEquals("local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(KEY, System.currentTimeMillis()));
assertEquals("remote is correct", VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
}
-
- private int getValidChildrenCount(Node node) {
- int result = 0;
- for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) {
- if (((Node) it.next()).isValid()) {
- result++;
- }
- }
- return result;
- }
-
+
private void rollback() {
try {
BatchModeTransactionManager.getInstance().rollback();
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -682,36 +682,26 @@
else
localAccessStrategy.removeAll();
- // This should re-establish the region root node in the optimistic case
+ // This should re-establish the region root node
assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis()));
regionRoot = localCache.getRoot().getChild(regionFqn);
- if (isUsingOptimisticLocking()) {
- assertFalse(regionRoot == null);
- assertEquals(0, getValidChildrenCount(regionRoot));
- assertTrue(regionRoot.isValid());
- assertTrue(regionRoot.isResident());
- }
- else {
- assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
- }
+ assertFalse(regionRoot == null);
+ assertEquals(0, getValidChildrenCount(regionRoot));
+ assertTrue(regionRoot.isValid());
+ assertTrue(regionRoot.isResident());
// Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish
assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
regionRoot = remoteCache.getRoot().getChild(regionFqn);
- if (isUsingOptimisticLocking()) {
- assertFalse(regionRoot == null);
- assertTrue(regionRoot.isValid());
- assertTrue(regionRoot.isResident());
- // Not invalidation, so we didn't insert a child above
- assertEquals(0, getValidChildrenCount(regionRoot));
- }
- else {
- assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
- }
-
+ assertFalse(regionRoot == null);
+ assertTrue(regionRoot.isValid());
+ assertTrue(regionRoot.isResident());
+ // Not invalidation, so we didn't insert a child above
+ assertEquals(0, getValidChildrenCount(regionRoot));
+
// Test whether the get above messes up the optimistic version
remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
@@ -730,17 +720,7 @@
assertEquals("local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(KEY, System.currentTimeMillis()));
assertEquals("remote is correct", VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
}
-
- private int getValidChildrenCount(Node node) {
- int result = 0;
- for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) {
- if (((Node) it.next()).isValid()) {
- result++;
- }
- }
- return result;
- }
-
+
protected void rollback() {
try {
BatchModeTransactionManager.getInstance().rollback();
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractTransactionalAccessTestCase.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractTransactionalAccessTestCase.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractTransactionalAccessTestCase.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -63,7 +63,7 @@
final CountDownLatch commitLatch = new CountDownLatch(1);
final CountDownLatch completionLatch = new CountDownLatch(1);
- Thread blocker = new Thread() {
+ Thread blocker = new Thread("Blocker") {
public void run() {
@@ -95,7 +95,7 @@
}
};
- Thread putter = new Thread() {
+ Thread putter = new Thread("Putter") {
public void run() {
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/bulk/PessimisticBulkOperationsTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/bulk/PessimisticBulkOperationsTest.java 2009-10-21 03:19:20 UTC (rev 17810)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/bulk/PessimisticBulkOperationsTest.java 2009-10-21 04:03:22 UTC (rev 17811)
@@ -26,11 +26,11 @@
import java.util.Set;
import org.hibernate.FlushMode;
-import org.hibernate.cache.RegionFactory;
import org.hibernate.cache.jbc2.MultiplexedJBossCacheRegionFactory;
import org.hibernate.cache.jbc2.builder.MultiplexingCacheInstanceManager;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
+import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.test.cache.jbc2.functional.CacheTestCaseBase;
import org.hibernate.test.cache.jbc2.functional.Contact;
import org.hibernate.test.cache.jbc2.functional.Customer;
@@ -90,7 +90,12 @@
assertNotNull("Red Hat contacts exist", rhContacts);
assertEquals("Created expected number of Red Hat contacts", 10, rhContacts.size());
+ SecondLevelCacheStatistics contactSlcs = getEnvironment().getSessionFactory().getStatistics().getSecondLevelCacheStatistics(
+ getPrefixedRegionName(Contact.class.getName()));
+ assertEquals(contactSlcs.getElementCountInMemory(), 20);
+
assertEquals("Deleted all Red Hat contacts", 10, deleteContacts());
+ assertEquals(0, contactSlcs.getElementCountInMemory());
List<Integer> jbContacts = getContactsByCustomer("JBoss");
assertNotNull("JBoss contacts exist", jbContacts);
@@ -108,6 +113,7 @@
}
updateContacts("Kabir", "Updated");
+ assertEquals(contactSlcs.getElementCountInMemory(), 0);
for (Integer id : jbContacts)
{
Contact contact = getContact(id);
@@ -120,6 +126,21 @@
List<Integer> updated = getContactsByTLF("Updated");
assertNotNull("Got updated contacts", updated);
assertEquals("Updated contacts", 5, updated.size());
+
+ updateContactsWithOneManual("Kabir", "UpdatedAgain");
+ assertEquals(contactSlcs.getElementCountInMemory(), 0);
+ for (Integer id : jbContacts)
+ {
+ Contact contact = getContact(id);
+ assertNotNull("JBoss contact " + id + " exists", contact);
+ String expected = ("Kabir".equals(contact.getName())) ? "UpdatedAgain" : "2222";
+ assertEquals("JBoss contact " + id + " has correct TLF",
+ expected, contact.getTlf());
+ }
+
+ updated = getContactsByTLF("UpdatedAgain");
+ assertNotNull("Got updated contacts", updated);
+ assertEquals("Updated contacts", 5, updated.size());
}
finally
{
@@ -231,6 +252,34 @@
throw e;
}
}
+
+ public int updateContactsWithOneManual(String name, String newTLF) throws Exception
+ {
+ String queryHQL = "from Contact c where c.name = :cName";
+ String updateHQL = "update Contact set tlf = :cNewTLF where name = :cName";
+
+ SimpleJtaTransactionManagerImpl.getInstance().begin();
+ try {
+
+ Session session = getSessions().getCurrentSession();
+
+ @SuppressWarnings("unchecked")
+ List<Contact> list = session.createQuery(queryHQL).setParameter("cName", name).list();
+ list.get(0).setTlf(newTLF);
+
+ int rowsAffected = session.createQuery(updateHQL)
+ .setFlushMode(FlushMode.AUTO)
+ .setParameter("cNewTLF", newTLF)
+ .setParameter("cName", name)
+ .executeUpdate();
+ SimpleJtaTransactionManagerImpl.getInstance().commit();
+ return rowsAffected;
+ }
+ catch (Exception e) {
+ SimpleJtaTransactionManagerImpl.getInstance().rollback();
+ throw e;
+ }
+ }
public Contact getContact(Integer id) throws Exception
{
14 years, 6 months
Hibernate SVN: r17810 - core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2009-10-20 23:19:20 -0400 (Tue, 20 Oct 2009)
New Revision: 17810
Modified:
core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/DataVersionAdapter.java
Log:
JBPAPP-2892 HHH-4435 DataVersioningException when using EJB3 entities with OPTIMISTIC caching
Modified: core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/DataVersionAdapter.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/DataVersionAdapter.java 2009-10-21 02:03:44 UTC (rev 17809)
+++ core/branches/Branch_3_3_2_GA_CP/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/DataVersionAdapter.java 2009-10-21 03:19:20 UTC (rev 17810)
@@ -116,6 +116,10 @@
// treat as us being newer
return (other.previousVersion != null);
}
+ // Can't be newer than itself
+ if ( this == dataVersion ) {
+ return false;
+ }
return versionComparator.compare(currentVersion, other.previousVersion) >= 1;
}
14 years, 6 months