Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.hibernate.metamodel.source.annotations.global.QueryBinder Maven / Gradle / Ivy
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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.metamodel.source.annotations.global;
import java.util.HashMap;
import java.util.List;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.logging.Logger;
import org.hibernate.AnnotationException;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.LockMode;
import org.hibernate.annotations.QueryHints;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.JandexHelper;
/**
* Binds {@link NamedQuery}, {@link NamedQueries}, {@link NamedNativeQuery}, {@link NamedNativeQueries},
* {@link org.hibernate.annotations.NamedQuery}, {@link org.hibernate.annotations.NamedQueries},
* {@link org.hibernate.annotations.NamedNativeQuery}, and {@link org.hibernate.annotations.NamedNativeQueries}.
*
* @author Hardy Ferentschik
*/
public class QueryBinder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
QueryBinder.class.getName()
);
private QueryBinder() {
}
/**
* Binds all {@link NamedQuery}, {@link NamedQueries}, {@link NamedNativeQuery}, {@link NamedNativeQueries},
* {@link org.hibernate.annotations.NamedQuery}, {@link org.hibernate.annotations.NamedQueries},
* {@link org.hibernate.annotations.NamedNativeQuery}, and {@link org.hibernate.annotations.NamedNativeQueries}
* annotations to the supplied metadata.
*
* @param bindingContext the context for annotation binding
*/
public static void bind(AnnotationBindingContext bindingContext) {
List annotations = bindingContext.getIndex().getAnnotations( JPADotNames.NAMED_QUERY );
for ( AnnotationInstance query : annotations ) {
bindNamedQuery( bindingContext.getMetadataImplementor(), query );
}
annotations = bindingContext.getIndex().getAnnotations( JPADotNames.NAMED_QUERIES );
for ( AnnotationInstance queries : annotations ) {
for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) {
bindNamedQuery( bindingContext.getMetadataImplementor(), query );
}
}
annotations = bindingContext.getIndex().getAnnotations( JPADotNames.NAMED_NATIVE_QUERY );
for ( AnnotationInstance query : annotations ) {
bindNamedNativeQuery( bindingContext.getMetadataImplementor(), query );
}
annotations = bindingContext.getIndex().getAnnotations( JPADotNames.NAMED_NATIVE_QUERIES );
for ( AnnotationInstance queries : annotations ) {
for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) {
bindNamedNativeQuery( bindingContext.getMetadataImplementor(), query );
}
}
annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.NAMED_QUERY );
for ( AnnotationInstance query : annotations ) {
bindNamedQuery( bindingContext.getMetadataImplementor(), query );
}
annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.NAMED_QUERIES );
for ( AnnotationInstance queries : annotations ) {
for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) {
bindNamedQuery( bindingContext.getMetadataImplementor(), query );
}
}
annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERY );
for ( AnnotationInstance query : annotations ) {
bindNamedNativeQuery( bindingContext.getMetadataImplementor(), query );
}
annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERIES );
for ( AnnotationInstance queries : annotations ) {
for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) {
bindNamedNativeQuery( bindingContext.getMetadataImplementor(), query );
}
}
}
/**
* Binds {@link javax.persistence.NamedQuery} as well as {@link org.hibernate.annotations.NamedQuery}.
*
* @param metadata the current metadata
* @param annotation the named query annotation
*/
private static void bindNamedQuery(MetadataImplementor metadata, AnnotationInstance annotation) {
String name = JandexHelper.getValue( annotation, "name", String.class );
if ( StringHelper.isEmpty( name ) ) {
throw new AnnotationException( "A named query must have a name when used in class or package level" );
}
String query = JandexHelper.getValue( annotation, "query", String.class );
AnnotationInstance[] hints = JandexHelper.getValue( annotation, "hints", AnnotationInstance[].class );
String cacheRegion = getString( hints, QueryHints.CACHE_REGION );
if ( StringHelper.isEmpty( cacheRegion ) ) {
cacheRegion = null;
}
Integer timeout = getTimeout( hints, query );
if ( timeout != null && timeout < 0 ) {
timeout = null;
}
Integer fetchSize = getInteger( hints, QueryHints.FETCH_SIZE, name );
if ( fetchSize != null && fetchSize < 0 ) {
fetchSize = null;
}
String comment = getString( hints, QueryHints.COMMENT );
if ( StringHelper.isEmpty( comment ) ) {
comment = null;
}
metadata.addNamedQuery(
new NamedQueryDefinition(
name,
query, getBoolean( hints, QueryHints.CACHEABLE, name ), cacheRegion,
timeout, fetchSize, getFlushMode( hints, QueryHints.FLUSH_MODE, name ),
getCacheMode( hints, QueryHints.CACHE_MODE, name ),
getBoolean( hints, QueryHints.READ_ONLY, name ), comment, null
)
);
LOG.debugf( "Binding named query: %s => %s", name, query );
}
private static void bindNamedNativeQuery(MetadataImplementor metadata, AnnotationInstance annotation) {
String name = JandexHelper.getValue( annotation, "name", String.class );
if ( StringHelper.isEmpty( name ) ) {
throw new AnnotationException( "A named native query must have a name when used in class or package level" );
}
String query = JandexHelper.getValue( annotation, "query", String.class );
String resultSetMapping = JandexHelper.getValue( annotation, "resultSetMapping", String.class );
AnnotationInstance[] hints = JandexHelper.getValue( annotation, "hints", AnnotationInstance[].class );
boolean cacheable = getBoolean( hints, "org.hibernate.cacheable", name );
String cacheRegion = getString( hints, QueryHints.CACHE_REGION );
if ( StringHelper.isEmpty( cacheRegion ) ) {
cacheRegion = null;
}
Integer timeout = getTimeout( hints, query );
if ( timeout != null && timeout < 0 ) {
timeout = null;
}
Integer fetchSize = getInteger( hints, QueryHints.FETCH_SIZE, name );
if ( fetchSize != null && fetchSize < 0 ) {
fetchSize = null;
}
FlushMode flushMode = getFlushMode( hints, QueryHints.FLUSH_MODE, name );
CacheMode cacheMode = getCacheMode( hints, QueryHints.CACHE_MODE, name );
boolean readOnly = getBoolean( hints, QueryHints.READ_ONLY, name );
String comment = getString( hints, QueryHints.COMMENT );
if ( StringHelper.isEmpty( comment ) ) {
comment = null;
}
boolean callable = getBoolean( hints, QueryHints.CALLABLE, name );
NamedSQLQueryDefinition def;
if ( StringHelper.isNotEmpty( resultSetMapping ) ) {
def = new NamedSQLQueryDefinition(
name,
query, resultSetMapping, null, cacheable,
cacheRegion, timeout, fetchSize,
flushMode, cacheMode, readOnly, comment,
null, callable
);
}
else {
AnnotationValue annotationValue = annotation.value( "resultClass" );
if ( annotationValue == null ) {
throw new NotYetImplementedException( "Pure native scalar queries are not yet supported" );
}
NativeSQLQueryRootReturn queryRoots[] = new NativeSQLQueryRootReturn[] {
new NativeSQLQueryRootReturn(
"alias1",
annotationValue.asString(),
new HashMap(),
LockMode.READ
)
};
def = new NamedSQLQueryDefinition(
name,
query,
queryRoots,
null,
cacheable,
cacheRegion,
timeout,
fetchSize,
flushMode,
cacheMode,
readOnly,
comment,
null,
callable
);
}
metadata.addNamedNativeQuery( def );
LOG.debugf( "Binding named native query: %s => %s", name, query );
}
private static boolean getBoolean(AnnotationInstance[] hints, String element, String query) {
String val = getString( hints, element );
if ( val == null || val.equalsIgnoreCase( "false" ) ) {
return false;
}
if ( val.equalsIgnoreCase( "true" ) ) {
return true;
}
throw new AnnotationException( "Not a boolean in hint: " + query + ":" + element );
}
private static CacheMode getCacheMode(AnnotationInstance[] hints, String element, String query) {
String val = getString( hints, element );
if ( val == null ) {
return null;
}
if ( val.equalsIgnoreCase( CacheMode.GET.toString() ) ) {
return CacheMode.GET;
}
if ( val.equalsIgnoreCase( CacheMode.IGNORE.toString() ) ) {
return CacheMode.IGNORE;
}
if ( val.equalsIgnoreCase( CacheMode.NORMAL.toString() ) ) {
return CacheMode.NORMAL;
}
if ( val.equalsIgnoreCase( CacheMode.PUT.toString() ) ) {
return CacheMode.PUT;
}
if ( val.equalsIgnoreCase( CacheMode.REFRESH.toString() ) ) {
return CacheMode.REFRESH;
}
throw new AnnotationException( "Unknown CacheMode in hint: " + query + ":" + element );
}
private static FlushMode getFlushMode(AnnotationInstance[] hints, String element, String query) {
String val = getString( hints, element );
if ( val == null ) {
return null;
}
if ( val.equalsIgnoreCase( FlushMode.ALWAYS.toString() ) ) {
return FlushMode.ALWAYS;
}
else if ( val.equalsIgnoreCase( FlushMode.AUTO.toString() ) ) {
return FlushMode.AUTO;
}
else if ( val.equalsIgnoreCase( FlushMode.COMMIT.toString() ) ) {
return FlushMode.COMMIT;
}
else if ( val.equalsIgnoreCase( FlushMode.NEVER.toString() ) ) {
return FlushMode.MANUAL;
}
else if ( val.equalsIgnoreCase( FlushMode.MANUAL.toString() ) ) {
return FlushMode.MANUAL;
}
else {
throw new AnnotationException( "Unknown FlushMode in hint: " + query + ":" + element );
}
}
private static Integer getInteger(AnnotationInstance[] hints, String element, String query) {
String val = getString( hints, element );
if ( val == null ) {
return null;
}
try {
return Integer.decode( val );
}
catch ( NumberFormatException nfe ) {
throw new AnnotationException( "Not an integer in hint: " + query + ":" + element, nfe );
}
}
private static String getString(AnnotationInstance[] hints, String element) {
for ( AnnotationInstance hint : hints ) {
if ( element.equals( JandexHelper.getValue( hint, "name", String.class ) ) ) {
return JandexHelper.getValue( hint, "value", String.class );
}
}
return null;
}
private static Integer getTimeout(AnnotationInstance[] hints, String query) {
Integer timeout = getInteger( hints, QueryHints.TIMEOUT_JPA, query );
if ( timeout == null ) {
return getInteger( hints, QueryHints.TIMEOUT_HIBERNATE, query ); // timeout is already in seconds
}
return ( ( timeout + 500 ) / 1000 ); // convert milliseconds to seconds (rounded)
}
}