/**
  * For each DataBindingSource provided by collectionBindingSource a new instance of targetType is
  * created, data binding is imposed on that instance with the DataBindingSource and the instance
  * is added to the end of collectionToPopulate
  *
  * @param targetType The type of objects to create, must be a concrete class
  * @param collectionToPopulate A collection to populate with new instances of targetType
  * @param collectionBindingSource A CollectionDataBindingSource
  * @since 2.3
  */
 public static <T> void bindToCollection(
     final Class<T> targetType,
     final Collection<T> collectionToPopulate,
     final CollectionDataBindingSource collectionBindingSource)
     throws InstantiationException, IllegalAccessException {
   final GrailsApplication application = Holders.findApplication();
   GrailsDomainClass domain = null;
   if (application != null) {
     domain =
         (GrailsDomainClass)
             application.getArtefact(DomainClassArtefactHandler.TYPE, targetType.getName());
   }
   final List<DataBindingSource> dataBindingSources =
       collectionBindingSource.getDataBindingSources();
   for (final DataBindingSource dataBindingSource : dataBindingSources) {
     final T newObject = targetType.newInstance();
     bindObjectToDomainInstance(
         domain,
         newObject,
         dataBindingSource,
         getBindingIncludeList(newObject),
         Collections.emptyList(),
         null);
     collectionToPopulate.add(newObject);
   }
 }
  /**
   * Sets custom naming strategy specified in configuration or the default {@link
   * ImprovedNamingStrategy}.
   */
  private void configureNamingStrategy() {
    NamingStrategy strategy = null;
    Object customStrategy = grailsApplication.getFlatConfig().get("hibernate.naming_strategy");
    if (customStrategy != null) {
      Class<?> namingStrategyClass = null;
      if (customStrategy instanceof Class<?>) {
        namingStrategyClass = (Class<?>) customStrategy;
      } else {
        try {
          namingStrategyClass =
              grailsApplication.getClassLoader().loadClass(customStrategy.toString());
        } catch (ClassNotFoundException e) {
          // ignore
        }
      }

      if (namingStrategyClass != null) {
        try {
          strategy = (NamingStrategy) namingStrategyClass.newInstance();
        } catch (InstantiationException e) {
          // ignore
        } catch (IllegalAccessException e) {
          // ignore
        }
      }
    }

    if (strategy == null) {
      strategy = ImprovedNamingStrategy.INSTANCE;
    }

    setNamingStrategy(strategy);
  }
 /**
  * Binds the given source object to the given target object performing type conversion if
  * necessary
  *
  * @param object The object to bind to
  * @param source The source object
  * @param include The list of properties to include
  * @param exclude The list of properties to exclude
  * @param filter The prefix to filter by
  * @return A BindingResult or null if it wasn't successful
  */
 public static BindingResult bindObjectToInstance(
     Object object, Object source, List include, List exclude, String filter) {
   if (include == null && exclude == null) {
     include = getBindingIncludeList(object);
   }
   GrailsApplication application = Holders.findApplication();
   GrailsDomainClass domain = null;
   if (application != null) {
     domain =
         (GrailsDomainClass)
             application.getArtefact(DomainClassArtefactHandler.TYPE, object.getClass().getName());
   }
   return bindObjectToDomainInstance(domain, object, source, include, exclude, filter);
 }
  /** Overrides the default behaviour to including binding of Grails domain classes. */
  @Override
  protected void secondPassCompile() throws MappingException {
    if (configLocked) {
      return;
    }

    // set the class loader to load Groovy classes
    if (grailsApplication != null) {
      Thread.currentThread().setContextClassLoader(grailsApplication.getClassLoader());
    }

    configureDomainBinder(grailsApplication, domainClasses);

    for (GrailsDomainClass domainClass : domainClasses) {
      if (!GrailsHibernateUtil.usesDatasource(domainClass, dataSourceName)) {
        continue;
      }
      final Mappings mappings = super.createMappings();
      Mapping m = binder.getMapping(domainClass);
      mappings.setAutoImport(m == null || m.getAutoImport());
      binder.bindClass(domainClass, mappings, sessionFactoryBeanName);
    }

    super.secondPassCompile();
    configLocked = true;
  }
 /**
  * Return whether the constraint is valid for the owning class
  *
  * @return true if it is
  */
 public boolean isValid() {
   if (applicationContext.containsBean("sessionFactory")) {
     GrailsApplication grailsApplication =
         applicationContext.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class);
     GrailsDomainClass domainClass =
         (GrailsDomainClass)
             grailsApplication.getArtefact(
                 DomainClassArtefactHandler.TYPE, constraintOwningClass.getName());
     if (domainClass != null) {
       String mappingStrategy = domainClass.getMappingStrategy();
       return mappingStrategy.equals(GrailsDomainClass.GORM)
           || mappingStrategy.equals(AbstractGrailsHibernateDomainClass.HIBERNATE);
     }
   }
   return false;
 }
  public void afterPropertiesSet() throws Exception {
    if (grailsApplication == null) {
      return;
    }

    String dsName =
        Mapping.DEFAULT_DATA_SOURCE.equals(dataSourceName)
            ? "dataSource"
            : "dataSource_" + dataSourceName;
    getProperties().put(Environment.DATASOURCE, applicationContext.getBean(dsName));
    getProperties()
        .put(Environment.CURRENT_SESSION_CONTEXT_CLASS, GrailsSessionContext.class.getName());
    getProperties().put(AvailableSettings.CLASSLOADERS, grailsApplication.getClassLoader());
    resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(applicationContext);

    configureNamingStrategy();
    GrailsClass[] existingDomainClasses =
        grailsApplication.getArtefacts(DomainClassArtefactHandler.TYPE);
    for (GrailsClass existingDomainClass : existingDomainClasses) {
      addDomainClass((GrailsDomainClass) existingDomainClass);
    }

    ArtefactHandler handler = grailsApplication.getArtefactHandler(DomainClassArtefactHandler.TYPE);
    if (!(handler instanceof AnnotationDomainClassArtefactHandler)) {
      return;
    }

    Set<String> jpaDomainNames =
        ((AnnotationDomainClassArtefactHandler) handler).getJpaClassNames();
    if (jpaDomainNames == null) {
      return;
    }

    final ClassLoader loader = grailsApplication.getClassLoader();
    for (String jpaDomainName : jpaDomainNames) {
      try {
        addAnnotatedClass(loader.loadClass(jpaDomainName));
      } catch (ClassNotFoundException e) {
        // impossible condition
      }
    }
  }
  /* (non-Javadoc)
   * @see org.grails.orm.hibernate.cfg.GrailsDomainConfiguration#setGrailsApplication(org.codehaus.groovy.grails.commons.GrailsApplication)
   */
  public void setGrailsApplication(GrailsApplication application) {
    grailsApplication = application;
    if (grailsApplication == null) {
      return;
    }

    GrailsClass[] existingDomainClasses =
        grailsApplication.getArtefacts(DomainClassArtefactHandler.TYPE);
    for (GrailsClass existingDomainClass : existingDomainClasses) {
      addDomainClass((GrailsDomainClass) existingDomainClass);
    }
  }
 public static MimeTypeResolver getMimeTypeResolver(GrailsApplication grailsApplication) {
   MimeTypeResolver mimeTypeResolver = null;
   if (grailsApplication != null) {
     ApplicationContext context = grailsApplication.getMainContext();
     if (context != null) {
       if (context.containsBean(MimeTypeResolver.BEAN_NAME)) {
         mimeTypeResolver = context.getBean(MimeTypeResolver.BEAN_NAME, MimeTypeResolver.class);
       }
     }
   }
   return mimeTypeResolver;
 }
 private static DataBinder getGrailsWebDataBinder(final GrailsApplication grailsApplication) {
   DataBinder dataBinder = null;
   if (grailsApplication != null) {
     final ApplicationContext mainContext = grailsApplication.getMainContext();
     if (mainContext != null && mainContext.containsBean(DATA_BINDER_BEAN_NAME)) {
       dataBinder = mainContext.getBean(DATA_BINDER_BEAN_NAME, DataBinder.class);
     }
   }
   if (dataBinder == null) {
     // this should really never happen in the running app as the binder
     // should always be found in the context
     dataBinder = new GrailsWebDataBinder(grailsApplication);
   }
   return dataBinder;
 }
 public static void configureDomainBinder(
     GrailsApplication grailsApplication, Set<GrailsDomainClass> domainClasses) {
   Closure defaultMapping =
       grailsApplication.getConfig().getProperty(DEFAULT_MAPPING, Closure.class);
   if (defaultMapping != null) {
     binder.setDefaultMapping(defaultMapping);
   }
   // do Grails class configuration
   for (GrailsDomainClass domainClass : domainClasses) {
     if (defaultMapping != null) {
       binder.evaluateMapping(domainClass, defaultMapping);
     } else {
       binder.evaluateMapping(domainClass);
     }
   }
 }
  /** Overrides the default behaviour to including binding of Grails domain classes. */
  @Override
  protected void secondPassCompile() throws MappingException {
    final Thread currentThread = Thread.currentThread();
    final ClassLoader originalContextLoader = currentThread.getContextClassLoader();
    if (!configLocked) {
      if (LOG.isDebugEnabled())
        LOG.debug(
            "[GrailsAnnotationConfiguration] ["
                + domainClasses.size()
                + "] Grails domain classes to bind to persistence runtime");

      // do Grails class configuration
      configureDomainBinder(binder, grailsApplication, domainClasses);

      for (GrailsDomainClass domainClass : domainClasses) {

        final String fullClassName = domainClass.getFullName();

        String hibernateConfig = fullClassName.replace('.', '/') + ".hbm.xml";
        final ClassLoader loader = originalContextLoader;
        // don't configure Hibernate mapped classes
        if (loader.getResource(hibernateConfig) != null) continue;

        final Mappings mappings = super.createMappings();
        if (!GrailsHibernateUtil.usesDatasource(domainClass, dataSourceName)) {
          continue;
        }

        LOG.debug(
            "[GrailsAnnotationConfiguration] Binding persistent class [" + fullClassName + "]");

        Mapping m = binder.getMapping(domainClass);
        mappings.setAutoImport(m == null || m.getAutoImport());
        binder.bindClass(domainClass, mappings, sessionFactoryBeanName);
      }
    }

    try {
      currentThread.setContextClassLoader(grailsApplication.getClassLoader());
      super.secondPassCompile();
      createSubclassForeignKeys();
    } finally {
      currentThread.setContextClassLoader(originalContextLoader);
    }

    configLocked = true;
  }
  public static DataBindingSourceRegistry getDataBindingSourceRegistry(
      GrailsApplication grailsApplication) {
    DataBindingSourceRegistry registry = null;
    if (grailsApplication != null) {
      ApplicationContext context = grailsApplication.getMainContext();
      if (context != null) {
        if (context.containsBean(DataBindingSourceRegistry.BEAN_NAME)) {
          registry =
              context.getBean(DataBindingSourceRegistry.BEAN_NAME, DataBindingSourceRegistry.class);
        }
      }
    }
    if (registry == null) {
      registry = new DefaultDataBindingSourceRegistry();
    }

    return registry;
  }
 public void configureDomainBinder(
     GrailsDomainBinder binder,
     GrailsApplication grailsApplication,
     Set<GrailsDomainClass> domainClasses) {
   GrailsHibernateUtil.setDomainBinder(binder);
   Closure defaultMapping =
       grailsApplication
           .getConfig()
           .getProperty(GrailsDomainConfiguration.DEFAULT_MAPPING, Closure.class);
   // do Grails class configuration
   if (defaultMapping != null) {
     binder.setDefaultMapping(defaultMapping);
   }
   for (GrailsDomainClass domainClass : domainClasses) {
     if (defaultMapping != null) {
       binder.evaluateMapping(domainClass, defaultMapping);
     } else {
       binder.evaluateMapping(domainClass);
     }
   }
 }
  @Override
  public SessionFactory buildSessionFactory() throws HibernateException {

    // set the class loader to load Groovy classes
    if (grailsApplication != null) {
      LOG.debug(
          "[GrailsAnnotationConfiguration] Setting context class loader to Grails GroovyClassLoader");
      Thread.currentThread().setContextClassLoader(grailsApplication.getClassLoader());
    }

    // work around for HHH-2624
    Map<String, Type> empty = new HashMap<String, Type>();
    addFilterDefinition(new FilterDefinition("dynamicFilterEnabler", "1=1", empty));

    SessionFactory sessionFactory = null;

    ClassLoader appClassLoader =
        (ClassLoader) getProperties().get(AvailableSettings.APP_CLASSLOADER);
    Thread currentThread = Thread.currentThread();
    ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
    boolean overrideClassLoader =
        (appClassLoader != null && !appClassLoader.equals(threadContextClassLoader));
    if (overrideClassLoader) {
      currentThread.setContextClassLoader(appClassLoader);
    }

    try {
      ConfigurationHelper.resolvePlaceHolders(getProperties());

      EventListenerIntegrator eventListenerIntegrator =
          new EventListenerIntegrator(hibernateEventListeners, eventListeners);
      BootstrapServiceRegistry bootstrapServiceRegistry =
          new BootstrapServiceRegistryBuilder().with(eventListenerIntegrator).build();

      setSessionFactoryObserver(
          new SessionFactoryObserver() {
            private static final long serialVersionUID = 1;

            public void sessionFactoryCreated(SessionFactory factory) {}

            public void sessionFactoryClosed(SessionFactory factory) {
              ((ServiceRegistryImplementor) serviceRegistry).destroy();
            }
          });

      StandardServiceRegistryBuilder standardServiceRegistryBuilder =
          new StandardServiceRegistryBuilder(bootstrapServiceRegistry)
              .applySettings(getProperties());
      sessionFactory = super.buildSessionFactory(standardServiceRegistryBuilder.build());
      serviceRegistry = ((SessionFactoryImplementor) sessionFactory).getServiceRegistry();
    } finally {
      if (overrideClassLoader) {
        currentThread.setContextClassLoader(threadContextClassLoader);
      }
    }

    if (grailsApplication != null) {
      GrailsHibernateUtil.configureHibernateDomainClasses(
          sessionFactory, sessionFactoryBeanName, grailsApplication);
    }

    return sessionFactory;
  }