/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2010, 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.hbm;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.MappingException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadeStyles;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.internal.jaxb.mapping.hbm.CustomSqlElement;
import org.hibernate.internal.jaxb.mapping.hbm.EntityElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbColumnElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbJoinedSubclassElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbMetaElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbParamElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbSubclassElement;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbUnionSubclassElement;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.binding.CustomSQL;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.binding.MetaAttribute;
import org.hibernate.metamodel.relational.Identifier;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.service.ServiceRegistry;

Author:Steve Ebersole, Gail Badner
/** * @author Steve Ebersole * @author Gail Badner */
public class Helper { public static final ExplicitHibernateTypeSource TO_ONE_ATTRIBUTE_TYPE_SOURCE = new ExplicitHibernateTypeSource() { @Override public String getName() { return null; } @Override public Map<String, String> getParameters() { return null; } }; public static InheritanceType interpretInheritanceType(EntityElement entityElement) { if ( JaxbSubclassElement.class.isInstance( entityElement ) ) { return InheritanceType.SINGLE_TABLE; } else if ( JaxbJoinedSubclassElement.class.isInstance( entityElement ) ) { return InheritanceType.JOINED; } else if ( JaxbUnionSubclassElement.class.isInstance( entityElement ) ) { return InheritanceType.TABLE_PER_CLASS; } else { return InheritanceType.NO_INHERITANCE; } }
Given a user-specified description of how to perform custom SQL, build the CustomSQL representation.
Params:
  • customSqlElement – User-specified description of how to perform custom SQL
Returns:The CustomSQL representation
/** * Given a user-specified description of how to perform custom SQL, build the {@link CustomSQL} representation. * * @param customSqlElement User-specified description of how to perform custom SQL * * @return The {@link CustomSQL} representation */
public static CustomSQL buildCustomSql(CustomSqlElement customSqlElement) { if ( customSqlElement == null ) { return null; } final ExecuteUpdateResultCheckStyle checkStyle = customSqlElement.getCheck() == null ? customSqlElement.isCallable() ? ExecuteUpdateResultCheckStyle.NONE : ExecuteUpdateResultCheckStyle.COUNT : ExecuteUpdateResultCheckStyle.fromExternalName( customSqlElement.getCheck().value() ); return new CustomSQL( customSqlElement.getValue(), customSqlElement.isCallable(), checkStyle ); }
Given the user-specified entity mapping, determine the appropriate entity name
Params:
  • entityElement – The user-specified entity mapping
  • unqualifiedClassPackage – The package to use for unqualified class names
Returns:The appropriate entity name
/** * Given the user-specified entity mapping, determine the appropriate entity name * * @param entityElement The user-specified entity mapping * @param unqualifiedClassPackage The package to use for unqualified class names * * @return The appropriate entity name */
public static String determineEntityName(EntityElement entityElement, String unqualifiedClassPackage) { return entityElement.getEntityName() != null ? entityElement.getEntityName() : qualifyIfNeeded( entityElement.getName(), unqualifiedClassPackage ); }
Qualify a (supposed class) name with the unqualified-class package name if it is not already qualified
Params:
  • name – The name
  • unqualifiedClassPackage – The unqualified-class package name
Returns:null if the incoming name was null; or the qualified name.
/** * Qualify a (supposed class) name with the unqualified-class package name if it is not already qualified * * @param name The name * @param unqualifiedClassPackage The unqualified-class package name * * @return {@code null} if the incoming name was {@code null}; or the qualified name. */
public static String qualifyIfNeeded(String name, String unqualifiedClassPackage) { if ( name == null ) { return null; } if ( name.indexOf( '.' ) < 0 && unqualifiedClassPackage != null ) { return unqualifiedClassPackage + '.' + name; } return name; } public static String getPropertyAccessorName(String access, boolean isEmbedded, String defaultAccess) { return getStringValue( access, isEmbedded ? "embedded" : defaultAccess ); } public static MetaAttributeContext extractMetaAttributeContext( List<JaxbMetaElement> metaElementList, boolean onlyInheritable, MetaAttributeContext parentContext) { final MetaAttributeContext subContext = new MetaAttributeContext( parentContext ); for ( JaxbMetaElement metaElement : metaElementList ) { if ( onlyInheritable & !metaElement.isInherit() ) { continue; } final String name = metaElement.getAttribute(); final MetaAttribute inheritedMetaAttribute = parentContext.getMetaAttribute( name ); MetaAttribute metaAttribute = subContext.getLocalMetaAttribute( name ); if ( metaAttribute == null || metaAttribute == inheritedMetaAttribute ) { metaAttribute = new MetaAttribute( name ); subContext.add( metaAttribute ); } metaAttribute.addValue( metaElement.getValue() ); } return subContext; } public static String getStringValue(String value, String defaultValue) { return value == null ? defaultValue : value; } public static int getIntValue(String value, int defaultValue) { return value == null ? defaultValue : Integer.parseInt( value ); } public static long getLongValue(String value, long defaultValue) { return value == null ? defaultValue : Long.parseLong( value ); } public static boolean getBooleanValue(Boolean value, boolean defaultValue) { return value == null ? defaultValue : value; } public static Iterable<CascadeStyle> interpretCascadeStyles(String cascades, LocalBindingContext bindingContext) { final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>(); if ( StringHelper.isEmpty( cascades ) ) { cascades = bindingContext.getMappingDefaults().getCascadeStyle(); } for ( String cascade : StringHelper.split( ",", cascades ) ) { cascadeStyles.add( CascadeStyles.getCascadeStyle( cascade ) ); } return cascadeStyles; } public static Map<String, String> extractParameters(List<JaxbParamElement> xmlParamElements) { if ( xmlParamElements == null || xmlParamElements.isEmpty() ) { return null; } final HashMap<String,String> params = new HashMap<String, String>(); for ( JaxbParamElement paramElement : xmlParamElements ) { params.put( paramElement.getName(), paramElement.getValue() ); } return params; } public static Iterable<MetaAttributeSource> buildMetaAttributeSources(List<JaxbMetaElement> metaElements) { ArrayList<MetaAttributeSource> result = new ArrayList<MetaAttributeSource>(); if ( metaElements == null || metaElements.isEmpty() ) { // do nothing } else { for ( final JaxbMetaElement metaElement : metaElements ) { result.add( new MetaAttributeSource() { @Override public String getName() { return metaElement.getAttribute(); } @Override public String getValue() { return metaElement.getValue(); } @Override public boolean isInheritable() { return metaElement.isInherit(); } } ); } } return result; } public static Schema.Name determineDatabaseSchemaName( String explicitSchemaName, String explicitCatalogName, LocalBindingContext bindingContext) { return new Schema.Name( resolveIdentifier( explicitSchemaName, bindingContext.getMappingDefaults().getSchemaName(), bindingContext.isGloballyQuotedIdentifiers() ), resolveIdentifier( explicitCatalogName, bindingContext.getMappingDefaults().getCatalogName(), bindingContext.isGloballyQuotedIdentifiers() ) ); } public static Identifier resolveIdentifier(String explicitName, String defaultName, boolean globalQuoting) { String name = StringHelper.isNotEmpty( explicitName ) ? explicitName : defaultName; if ( globalQuoting ) { name = StringHelper.quote( name ); } return Identifier.toIdentifier( name ); } public static class ValueSourcesAdapter { public String getContainingTableName() { return null; } public boolean isIncludedInInsertByDefault() { return false; } public boolean isIncludedInUpdateByDefault() { return false; } public String getColumnAttribute() { return null; } public String getFormulaAttribute() { return null; } public List getColumnOrFormulaElements() { return null; } public boolean isForceNotNull() { return false; } } public static List<RelationalValueSource> buildValueSources( ValueSourcesAdapter valueSourcesAdapter, LocalBindingContext bindingContext) { List<RelationalValueSource> result = new ArrayList<RelationalValueSource>(); if ( StringHelper.isNotEmpty( valueSourcesAdapter.getColumnAttribute() ) ) { if ( valueSourcesAdapter.getColumnOrFormulaElements() != null && ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) { throw new org.hibernate.metamodel.source.MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement", bindingContext.getOrigin() ); } if ( StringHelper.isNotEmpty( valueSourcesAdapter.getFormulaAttribute() ) ) { throw new org.hibernate.metamodel.source.MappingException( "column and formula attributes may not be used together", bindingContext.getOrigin() ); } result.add( new ColumnAttributeSourceImpl( valueSourcesAdapter.getContainingTableName(), valueSourcesAdapter.getColumnAttribute(), valueSourcesAdapter.isIncludedInInsertByDefault(), valueSourcesAdapter.isIncludedInUpdateByDefault(), valueSourcesAdapter.isForceNotNull() ) ); } else if ( StringHelper.isNotEmpty( valueSourcesAdapter.getFormulaAttribute() ) ) { if ( valueSourcesAdapter.getColumnOrFormulaElements() != null && ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) { throw new org.hibernate.metamodel.source.MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement", bindingContext.getOrigin() ); } // column/formula attribute combo checked already result.add( new FormulaImpl( valueSourcesAdapter.getContainingTableName(), valueSourcesAdapter.getFormulaAttribute() ) ); } else if ( valueSourcesAdapter.getColumnOrFormulaElements() != null && ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) { for ( Object columnOrFormulaElement : valueSourcesAdapter.getColumnOrFormulaElements() ) { if ( JaxbColumnElement.class.isInstance( columnOrFormulaElement ) ) { result.add( new ColumnSourceImpl( valueSourcesAdapter.getContainingTableName(), (JaxbColumnElement) columnOrFormulaElement, valueSourcesAdapter.isIncludedInInsertByDefault(), valueSourcesAdapter.isIncludedInUpdateByDefault(), valueSourcesAdapter.isForceNotNull() ) ); } else { result.add( new FormulaImpl( valueSourcesAdapter.getContainingTableName(), (String) columnOrFormulaElement ) ); } } } return result; } // todo : remove this once the state objects are cleaned up public static Class classForName(String className, ServiceRegistry serviceRegistry) { ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class ); try { return classLoaderService.classForName( className ); } catch ( ClassLoadingException e ) { throw new MappingException( "Could not find class: " + className ); } } }