Package org.hibernate.metamodel.source.annotations.global

Source Code of org.hibernate.metamodel.source.annotations.global.QueryBinder

/*
* 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.NamedQueryDefinitionBuilder;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinitionBuilder;
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<AnnotationInstance> 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 NamedQueryDefinitionBuilder().setName( name ).setQuery( query ).setCacheable(
            getBoolean(
                hints,
                QueryHints.CACHEABLE,
                name
            )
        ).setCacheRegion( cacheRegion ).setTimeout( timeout ).setFetchSize( fetchSize ).setFlushMode(
            getFlushMode( hints, QueryHints.FLUSH_MODE, name )
        ).setCacheMode( getCacheMode( hints, QueryHints.CACHE_MODE, name ) ).setReadOnly(
            getBoolean(
                hints,
                QueryHints.READ_ONLY,
                name
            )
        ).setComment( comment ).setParameterTypes( null ).createNamedQueryDefinition()
    );
    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 NamedSQLQueryDefinitionBuilder().setName( name )
          .setQuery( query )
          .setResultSetRef(
              resultSetMapping
          )
          .setQuerySpaces( null )
          .setCacheable( cacheable )
          .setCacheRegion( cacheRegion )
          .setTimeout( timeout )
          .setFetchSize( fetchSize )
          .setFlushMode( flushMode )
          .setCacheMode( cacheMode )
          .setReadOnly( readOnly )
          .setComment( comment )
          .setParameterTypes( null )
          .setCallable( callable )
          .createNamedQueryDefinition();
    }
    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<String, String[]>(),
              LockMode.READ
          )
      };
      def = new NamedSQLQueryDefinitionBuilder().setName( name )
          .setQuery( query )
          .setQueryReturns( queryRoots )
          .setQuerySpaces( null )
          .setCacheable( cacheable )
          .setCacheRegion( cacheRegion )
          .setTimeout( timeout )
          .setFetchSize( fetchSize )
          .setFlushMode( flushMode )
          .setCacheMode( cacheMode )
          .setReadOnly( readOnly )
          .setComment( comment )
          .setParameterTypes( null )
          .setCallable( callable )
          .createNamedQueryDefinition();
    }
    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)
  }
}
TOP

Related Classes of org.hibernate.metamodel.source.annotations.global.QueryBinder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.