View Javadoc
1   /*
2    * Hibernate, Relational Persistence for Idiomatic Java
3    *
4    * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
5    * indicated by the @author tags or express copyright attribution
6    * statements applied by the authors.  All third-party contributions are
7    * distributed under license by Red Hat Inc.
8    *
9    * This copyrighted material is made available to anyone wishing to use, modify,
10   * copy, or redistribute it subject to the terms and conditions of the GNU
11   * Lesser General Public License, as published by the Free Software Foundation.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15   * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
16   * for more details.
17   *
18   * You should have received a copy of the GNU Lesser General Public License
19   * along with this distribution; if not, write to:
20   * Free Software Foundation, Inc.
21   * 51 Franklin Street, Fifth Floor
22   * Boston, MA  02110-1301  USA
23   */
24  package org.hibernate.id.factory;
25  
26  import java.util.Properties;
27  import java.io.Serializable;
28  import java.util.concurrent.ConcurrentHashMap;
29  
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  import org.hibernate.id.IdentifierGenerator;
34  import org.hibernate.id.UUIDGenerator;
35  import org.hibernate.id.UUIDHexGenerator;
36  import org.hibernate.id.TableHiLoGenerator;
37  import org.hibernate.id.Assigned;
38  import org.hibernate.id.IdentityGenerator;
39  import org.hibernate.id.SelectGenerator;
40  import org.hibernate.id.SequenceGenerator;
41  import org.hibernate.id.SequenceHiLoGenerator;
42  import org.hibernate.id.IncrementGenerator;
43  import org.hibernate.id.ForeignGenerator;
44  import org.hibernate.id.GUIDGenerator;
45  import org.hibernate.id.SequenceIdentityGenerator;
46  import org.hibernate.id.Configurable;
47  import org.hibernate.id.enhanced.SequenceStyleGenerator;
48  import org.hibernate.id.enhanced.TableGenerator;
49  import org.hibernate.type.Type;
50  import org.hibernate.util.ReflectHelper;
51  import org.hibernate.dialect.Dialect;
52  import org.hibernate.MappingException;
53  
54  /**
55   * Basic <tt>templated</tt> support for {@link IdentifierGeneratorFactory} implementations.
56   *
57   * @author Steve Ebersole
58   */
59  public class DefaultIdentifierGeneratorFactory implements IdentifierGeneratorFactory, Serializable {
60  	private static final Logger log = LoggerFactory.getLogger( DefaultIdentifierGeneratorFactory.class );
61  
62  	private transient Dialect dialect;
63  	private ConcurrentHashMap<String, Class> generatorStrategyToClassNameMap = new ConcurrentHashMap<String, Class>();
64  
65  	/**
66  	 * Constructs a new DefaultIdentifierGeneratorFactory.
67  	 */
68  	public DefaultIdentifierGeneratorFactory() {
69  		register( "uuid2", UUIDGenerator.class );
70  		register( "guid", GUIDGenerator.class );			// can be done with UUIDGenerator + strategy
71  		register( "uuid", UUIDHexGenerator.class );			// "deprecated" for new use
72  		register( "uuid.hex", UUIDHexGenerator.class ); 	// uuid.hex is deprecated
73  		register( "hilo", TableHiLoGenerator.class );
74  		register( "assigned", Assigned.class );
75  		register( "identity", IdentityGenerator.class );
76  		register( "select", SelectGenerator.class );
77  		register( "sequence", SequenceGenerator.class );
78  		register( "seqhilo", SequenceHiLoGenerator.class );
79  		register( "increment", IncrementGenerator.class );
80  		register( "foreign", ForeignGenerator.class );
81  		register( "sequence-identity", SequenceIdentityGenerator.class );
82  		register( "enhanced-sequence", SequenceStyleGenerator.class );
83  		register( "enhanced-table", TableGenerator.class );
84  	}
85  
86  	/**
87  	 * {@inheritDoc}
88  	 */
89  	public void setDialect(Dialect dialect) {
90  		log.debug( "Setting dialect [" + dialect + "]" );
91  		this.dialect = dialect;
92  	}
93  
94  	public void register(String strategy, Class generatorClass) {
95  		String msg = "Registering IdentifierGenerator strategy [" + strategy + "] -> [" + generatorClass + "]";
96  		Object old = generatorStrategyToClassNameMap.put( strategy, generatorClass );
97  		if ( old != null ) {
98  			msg += ", overriding [" + old + "]";
99  		}
100 		log.debug( msg );
101 	}
102 
103 	/**
104 	 * {@inheritDoc}
105 	 */
106 	public IdentifierGenerator createIdentifierGenerator(String strategy, Type type, Properties config) {
107 		try {
108 			Class clazz = getIdentifierGeneratorClass( strategy );
109 			IdentifierGenerator idgen = ( IdentifierGenerator ) clazz.newInstance();
110 			if ( idgen instanceof Configurable ) {
111 				( ( Configurable ) idgen ).configure( type, config, dialect );
112 			}
113 			return idgen;
114 		}
115 		catch ( Exception e ) {
116 			String msg = "Could not instantiate id generator [entity-name="
117 					+ config.get( IdentifierGenerator.ENTITY_NAME ) + "]";
118 			throw new MappingException( msg, e );
119 		}
120 	}
121 
122 	/**
123 	 * {@inheritDoc}
124 	 */
125 	public Class getIdentifierGeneratorClass(String strategy) {
126 		if ( "native".equals( strategy ) ) {
127 			return dialect.getNativeIdentifierGeneratorClass();
128 		}
129 
130 		Class generatorClass = generatorStrategyToClassNameMap.get( strategy );
131 		try {
132 			if ( generatorClass == null ) {
133 				generatorClass = ReflectHelper.classForName( strategy );
134 			}
135 		}
136 		catch ( ClassNotFoundException e ) {
137 			throw new MappingException( "Could not interpret id generator strategy [" + strategy + "]" );
138 		}
139 		return generatorClass;
140 	}
141 }