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 javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import java.util.HashMap;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
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.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.spi.MetadataImplementor;

public class QueryBinder {

  private static final CoreMessageLogger LOG = Logger.getMessageLogger(
      CoreMessageLogger.class,
      QueryBinder.class.getName()
  );

  /**
   * 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 metadata the global metadata
   * @param jandex the jandex index
   */
  public static void bind(MetadataImplementor metadata, Index jandex) {
    for ( AnnotationInstance query : jandex.getAnnotations( JPADotNames.NAMED_QUERY ) ) {
      bindNamedQuery( metadata, query );
    }
    for ( AnnotationInstance queries : jandex.getAnnotations( JPADotNames.NAMED_QUERIES ) ) {
      for ( AnnotationInstance query : JandexHelper.getValueAsArray( queries, "value" ) ) {
        bindNamedQuery( metadata, query );
      }
    }
    for ( AnnotationInstance query : jandex.getAnnotations( JPADotNames.NAMED_NATIVE_QUERY ) ) {
      bindNamedNativeQuery( metadata, query );
    }
    for ( AnnotationInstance queries : jandex.getAnnotations( JPADotNames.NAMED_NATIVE_QUERIES ) ) {
      for ( AnnotationInstance query : JandexHelper.getValueAsArray( queries, "value" ) ) {
        bindNamedNativeQuery( metadata, query );
      }
    }
    for ( AnnotationInstance query : jandex.getAnnotations( HibernateDotNames.NAMED_QUERY ) ) {
      bindNamedQuery( metadata, query );
    }
    for ( AnnotationInstance queries : jandex.getAnnotations( HibernateDotNames.NAMED_QUERIES ) ) {
      for ( AnnotationInstance query : JandexHelper.getValueAsArray( queries, "value" ) ) {
        bindNamedQuery( metadata, query );
      }
    }
    for ( AnnotationInstance query : jandex.getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERY ) ) {
      bindNamedNativeQuery( metadata, query );
    }
    for ( AnnotationInstance queries : jandex.getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERIES ) ) {
      for ( AnnotationInstance query : JandexHelper.getValueAsArray( queries, "value" ) ) {
        bindNamedNativeQuery( metadata, query );
      }
    }
  }

  private static void bindNamedQuery(MetadataImplementor metadata, AnnotationInstance annotation) {
    String name = JandexHelper.getValueAsString( annotation, "name" );
    if ( StringHelper.isEmpty( name ) ) {
      throw new AnnotationException( "A named query must have a name when used in class or package level" );
    }
    String query = JandexHelper.getValueAsString( annotation, "query" );
    AnnotationInstance[] hints = JandexHelper.getValueAsArray( annotation, "hints" );
    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.getValueAsString( annotation, "name" );
    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.getValueAsString( annotation, "query" );
    String resultSetMapping = JandexHelper.getValueAsString( annotation, "resultSetMapping" );
    AnnotationInstance[] hints = JandexHelper.getValueAsArray( annotation, "hints" );
    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 {
      String resultClass = JandexHelper.getValueAsString( annotation, "resultClass" );
      if ( void.class.equals( resultClass ) ) {
        throw new NotYetImplementedException( "Pure native scalar queries are not yet supported" );
      }
      def = new NamedSQLQueryDefinition(
          name,
          query, new NativeSQLQueryRootReturn[] {
          new NativeSQLQueryRootReturn(
              "alias1",
              resultClass,
              new HashMap(),
              LockMode.READ
          )
      },
          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" ) ) ) {
        return JandexHelper.getValueAsString( hint, "value" );
      }
    }
    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 new Integer( (int) Math.round( timeout.doubleValue() / 1000.0 ) ); // convert milliseconds to seconds
  }

  private QueryBinder() {
  }
}
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.