HHH-5672 - Develop the binding model (binding between logical and relational)

This commit is contained in:
Steve Ebersole 2011-03-17 15:07:08 -05:00
parent 394211b42f
commit 819f8da9ea
79 changed files with 5556 additions and 418 deletions

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008-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 Middleware LLC.
* 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
@ -20,32 +20,46 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate;
/**
* Raised whenever a duplicate for a certain type occurs.
* Duplicate class, table, property name etc.
*
* @author Max Rydahl Andersen
*
* @author Steve Ebersole
*/
public class DuplicateMappingException extends MappingException {
public static enum Type {
ENTITY,
TABLE,
PROPERTY,
COLUMN
}
private final String name;
private final String type;
public DuplicateMappingException(Type type, String name) {
this( type.name(), name );
}
@Deprecated
public DuplicateMappingException(String type, String name) {
this( "Duplicate " + type + " mapping " + name, type, name );
}
public DuplicateMappingException(String customMessage, Type type, String name) {
this( customMessage, type.name(), name );
}
@Deprecated
public DuplicateMappingException(String customMessage, String type, String name) {
super(customMessage);
super( customMessage );
this.type=type;
this.name=name;
}
public DuplicateMappingException(String type, String name) {
this("Duplicate " + type + " mapping " + name, type, name);
}
public String getType() {
return type;

View File

@ -1,67 +1,74 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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
*
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 20082011, 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;
/**
* Thrown when a mapping is found to be invalid.
* Similar to MappingException, but this contains more info about the path and type of mapping (e.g. file, resource or url)
*
* @author Max Rydahl Andersen
*
*/
public class InvalidMappingException extends MappingException {
private final String path;
private final String type;
public InvalidMappingException(String customMessage, String type, String path, Throwable cause) {
super(customMessage, cause);
this.type=type;
this.path=path;
}
public InvalidMappingException(String customMessage, String type, String path) {
super(customMessage);
this.type=type;
this.path=path;
}
public InvalidMappingException(String type, String path) {
this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path);
}
public InvalidMappingException(String type, String path, Throwable cause) {
this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause);
}
public String getType() {
return type;
}
public String getPath() {
return path;
}
}
import org.hibernate.internal.util.xml.XmlDocument;
/**
* Thrown when a mapping is found to be invalid.
* Similar to MappingException, but this contains more info about the path and type of mapping (e.g. file, resource or url)
*
* @author Max Rydahl Andersen
* @author Steve Ebersole
*/
public class InvalidMappingException extends MappingException {
private final String path;
private final String type;
public InvalidMappingException(String customMessage, String type, String path, Throwable cause) {
super(customMessage, cause);
this.type=type;
this.path=path;
}
public InvalidMappingException(String customMessage, String type, String path) {
super(customMessage);
this.type=type;
this.path=path;
}
public InvalidMappingException(String customMessage, XmlDocument xmlDocument, Throwable cause) {
this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName(), cause );
}
public InvalidMappingException(String customMessage, XmlDocument xmlDocument) {
this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName() );
}
public InvalidMappingException(String type, String path) {
this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path);
}
public InvalidMappingException(String type, String path, Throwable cause) {
this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause);
}
public String getType() {
return type;
}
public String getPath() {
return path;
}
}

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008-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 Middleware LLC.
* 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
@ -20,18 +20,15 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate;
/**
* An exception that usually occurs at configuration time, rather
* than runtime, as a result of something screwy in the O-R mappings.
*
* @author Gavin King
*/
public class MappingException extends HibernateException {
public MappingException(String msg, Throwable root) {

View File

@ -0,0 +1,41 @@
/*
* 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;
import org.hibernate.HibernateException;
/**
* Indicates a problem validating the metamodel.
*
* @author Steve Ebersole
*/
public class ValidationException extends HibernateException {
public ValidationException(String s) {
super( s );
}
public ValidationException(String string, Throwable root) {
super( string, root );
}
}

View File

@ -0,0 +1,177 @@
/*
* 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.binding;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.hibernate.FetchMode;
import org.hibernate.mapping.MetaAttribute;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.DerivedValue;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.Tuple;
import org.hibernate.metamodel.relational.Value;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public abstract class AbstractAttributeBinding implements AttributeBinding {
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final EntityBinding entityBinding;
private Attribute attribute;
private Value value;
private FetchMode fetchMode;
private boolean alternateUniqueKey;
private Map<String, MetaAttribute> metaAttributes;
protected AbstractAttributeBinding(EntityBinding entityBinding) {
this.entityBinding = entityBinding;
}
@Override
public EntityBinding getEntityBinding() {
return entityBinding;
}
@Override
public Attribute getAttribute() {
return attribute;
}
@Override
public void setAttribute(Attribute attribute) {
this.attribute = attribute;
}
@Override
public Value getValue() {
return value;
}
@Override
public void setValue(Value value) {
this.value = value;
}
@Override
public HibernateTypeDescriptor getHibernateTypeDescriptor() {
return hibernateTypeDescriptor;
}
@Override
public Map<String, MetaAttribute> getMetaAttributes() {
return metaAttributes;
}
@Override
public void setMetaAttributes(Map<String, MetaAttribute> metaAttributes) {
this.metaAttributes = metaAttributes;
}
@Override
public Iterable<SimpleValue> getValues() {
return value == null
? Collections.<SimpleValue>emptyList()
: value instanceof Tuple
? ( (Tuple) value ).values()
: Collections.singletonList( (SimpleValue) value );
}
@Override
public TableSpecification getTable() {
return getValue().getTable();
}
@Override
public FetchMode getFetchMode() {
return fetchMode;
}
@Override
public void setFetchMode(FetchMode fetchMode) {
this.fetchMode = fetchMode;
}
@Override
public boolean hasFormula() {
for ( SimpleValue simpleValue : getValues() ) {
if ( simpleValue instanceof DerivedValue ) {
return true;
}
}
return false;
}
@Override
public boolean isAlternateUniqueKey() {
return alternateUniqueKey;
}
public void setAlternateUniqueKey(boolean alternateUniqueKey) {
this.alternateUniqueKey = alternateUniqueKey;
}
@Override
public boolean isNullable() {
for ( SimpleValue simpleValue : getValues() ) {
if ( simpleValue instanceof DerivedValue ) {
return true;
}
Column column = (Column) simpleValue;
if ( column.isNullable() ) {
return true;
}
}
return false;
}
@Override
public boolean[] getColumnInsertability() {
List<Boolean> tmp = new ArrayList<Boolean>();
for ( SimpleValue simpleValue : getValues() ) {
tmp.add( ! ( simpleValue instanceof DerivedValue ) );
}
boolean[] rtn = new boolean[ tmp.size() ];
int i = 0;
for ( Boolean insertable : tmp ) {
rtn[i++] = insertable.booleanValue();
}
return rtn;
}
@Override
public boolean[] getColumnUpdateability() {
return getColumnInsertability();
}
}

View File

@ -0,0 +1,127 @@
/*
* 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.binding;
import java.util.Map;
import org.hibernate.FetchMode;
import org.hibernate.mapping.MetaAttribute;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.Value;
/**
* The basic contract for binding between an {@link #getAttribute() attribute} and a {@link #getValue() value}
*
* @author Steve Ebersole
*/
public interface AttributeBinding {
/**
* Obtain the entity binding to which this attribute binding exists.
*
* @return The entity binding.
*/
public EntityBinding getEntityBinding();
/**
* Obtain the attribute bound.
*
* @return The attribute.
*/
public Attribute getAttribute();
/**
* Set the attribute being bound.
*
* @param attribute The attribute
*/
public void setAttribute(Attribute attribute);
/**
* Obtain the value bound
*
* @return The value
*/
public Value getValue();
/**
* Set the value being bound.
*
* @param value The value
*/
public void setValue(Value value);
/**
* Obtain the descriptor for the Hibernate Type for this binding.
*
* @return The type descriptor
*/
public HibernateTypeDescriptor getHibernateTypeDescriptor();
/**
* Obtain the map of meta attributes associated with this binding
*
* @return The meta attributes
*/
public Map<String, MetaAttribute> getMetaAttributes();
/**
* Set the meta attribute map associated with this binding
*
* @param metaAttributes The meta attributes
*/
public void setMetaAttributes(Map<String, MetaAttribute> metaAttributes);
/**
* In the case that {@link #getValue()} represnets a {@link org.hibernate.metamodel.relational.Tuple} this method
* gives access to its compound values. In the case of {@link org.hibernate.metamodel.relational.SimpleValue},
* we return an Iterable over that single simple value.
*
* @return
*/
public Iterable<SimpleValue> getValues();
/**
* @deprecated Use {@link #getValue()}.{@link Value#getTable() getTable()} instead; to be removed on completion of new metamodel code
* @return
*/
@Deprecated
public TableSpecification getTable();
public FetchMode getFetchMode();
public void setFetchMode(FetchMode fetchMode);
/**
*
* @return
*/
public boolean hasFormula();
public boolean isAlternateUniqueKey();
public boolean isNullable();
public boolean[] getColumnUpdateability();
public boolean[] getColumnInsertability();
public boolean isSimpleValue();
}

View File

@ -0,0 +1,35 @@
/*
* 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.binding;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class BagBinding extends PluralAttributeBinding {
protected BagBinding(EntityBinding entityBinding) {
super( entityBinding );
}
}

View File

@ -0,0 +1,68 @@
/*
* 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.binding;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class Caching {
private String region;
private String strategy;
private boolean cacheLazyProperties;
public Caching() {
}
public Caching(String region, String strategy, boolean cacheLazyProperties) {
this.region = region;
this.strategy = strategy;
this.cacheLazyProperties = cacheLazyProperties;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getStrategy() {
return strategy;
}
public void setStrategy(String strategy) {
this.strategy = strategy;
}
public boolean isCacheLazyProperties() {
return cacheLazyProperties;
}
public void setCacheLazyProperties(boolean cacheLazyProperties) {
this.cacheLazyProperties = cacheLazyProperties;
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.binding;
import org.hibernate.mapping.Value;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class CollectionElement {
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final PluralAttributeBinding collectionBinding;
private Value elementValue;
CollectionElement(PluralAttributeBinding collectionBinding) {
this.collectionBinding = collectionBinding;
}
}

View File

@ -0,0 +1,46 @@
/*
* 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.binding;
import org.hibernate.metamodel.relational.ForeignKey;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class CollectionKey {
private final PluralAttributeBinding collection;
private ForeignKey foreignKey;
private boolean inverse;
private HibernateTypeDescriptor hibernateTypeDescriptor;
// todo : this would be nice to have but we do not always know it, especially in HBM case.
// private SimpleAttributeBinding otherSide;
public CollectionKey(PluralAttributeBinding collection) {
this.collection = collection;
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.binding;
import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class CustomSQL {
private final String sql;
private final boolean isCallable;
private final ExecuteUpdateResultCheckStyle checkStyle;
public CustomSQL(String sql, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
this.sql = sql;
isCallable = callable;
this.checkStyle = checkStyle;
}
public String getSql() {
return sql;
}
public boolean isCallable() {
return isCallable;
}
public ExecuteUpdateResultCheckStyle getCheckStyle() {
return checkStyle;
}
}

View File

@ -0,0 +1,300 @@
/*
* 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.binding;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
import org.hibernate.mapping.MetaAttribute;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.relational.TableSpecification;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class EntityBinding {
private final EntityIdentifier entityIdentifier = new EntityIdentifier( this );
private EntityDiscriminator entityDiscriminator;
private SimpleAttributeBinding versionBinding;
private Entity entity;
private TableSpecification baseTable;
private Map<String,AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
private Caching caching;
private Map<String, MetaAttribute> metaAttributes;
private boolean lazy;
private boolean mutable;
private boolean explicitPolymorphism;
private String whereFilter;
private String rowId;
private String discriminatorValue;
private boolean dynamicUpdate;
private boolean dynamicInsert;
private int batchSize;
private boolean selectBeforeUpdate;
private int optimisticLockMode;
private Class entityPersisterClass;
private Boolean isAbstract;
private List<String> synchronizedTableNames;
public Entity getEntity() {
return entity;
}
public void setEntity(Entity entity) {
this.entity = entity;
}
public TableSpecification getBaseTable() {
return baseTable;
}
public void setBaseTable(TableSpecification baseTable) {
this.baseTable = baseTable;
}
public EntityIdentifier getEntityIdentifier() {
return entityIdentifier;
}
public EntityDiscriminator makeEntityDiscriminator() {
entityDiscriminator = new EntityDiscriminator( this );
return entityDiscriminator;
}
public EntityDiscriminator getEntityDiscriminator() {
return entityDiscriminator;
}
public SimpleAttributeBinding getVersioningValueBinding() {
return versionBinding;
}
public void setVersioningValueBinding(SimpleAttributeBinding versionBinding) {
this.versionBinding = versionBinding;
}
public Iterable<AttributeBinding> getAttributeBindings() {
return attributeBindingMap.values();
}
public AttributeBinding getAttributeBinding(String name) {
return attributeBindingMap.get( name );
}
public SimpleAttributeBinding makeSimpleAttributeBinding(String name) {
final SimpleAttributeBinding binding = new SimpleAttributeBinding( this );
attributeBindingMap.put( name, binding );
binding.setAttribute( entity.getAttribute( name ) );
return binding;
}
public BagBinding makeBagAttributeBinding(String name) {
final BagBinding binding = new BagBinding( this );
attributeBindingMap.put( name, binding );
binding.setAttribute( entity.getAttribute( name ) );
return binding;
}
public Caching getCaching() {
return caching;
}
public void setCaching(Caching caching) {
this.caching = caching;
}
public Map<String, MetaAttribute> getMetaAttributes() {
return metaAttributes;
}
public void setMetaAttributes(Map<String, MetaAttribute> metaAttributes) {
this.metaAttributes = metaAttributes;
}
public boolean isMutable() {
return mutable;
}
public void setMutable(boolean mutable) {
this.mutable = mutable;
}
public boolean isLazy() {
return lazy;
}
public void setLazy(boolean lazy) {
this.lazy = lazy;
}
public String getWhereFilter() {
return whereFilter;
}
public void setWhereFilter(String whereFilter) {
this.whereFilter = whereFilter;
}
public boolean isExplicitPolymorphism() {
return explicitPolymorphism;
}
public void setExplicitPolymorphism(boolean explicitPolymorphism) {
this.explicitPolymorphism = explicitPolymorphism;
}
public String getRowId() {
return rowId;
}
public void setRowId(String rowId) {
this.rowId = rowId;
}
public String getDiscriminatorValue() {
return discriminatorValue;
}
public void setDiscriminatorValue(String discriminatorValue) {
this.discriminatorValue = discriminatorValue;
}
public boolean isDynamicUpdate() {
return dynamicUpdate;
}
public void setDynamicUpdate(boolean dynamicUpdate) {
this.dynamicUpdate = dynamicUpdate;
}
public boolean isDynamicInsert() {
return dynamicInsert;
}
public void setDynamicInsert(boolean dynamicInsert) {
this.dynamicInsert = dynamicInsert;
}
public int getBatchSize() {
return batchSize;
}
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
public boolean isSelectBeforeUpdate() {
return selectBeforeUpdate;
}
public void setSelectBeforeUpdate(Boolean selectBeforeUpdate) {
this.selectBeforeUpdate = selectBeforeUpdate;
}
public int getOptimisticLockMode() {
return optimisticLockMode;
}
public void setOptimisticLockMode(int optimisticLockMode) {
this.optimisticLockMode = optimisticLockMode;
}
public Class getEntityPersisterClass() {
return entityPersisterClass;
}
public void setEntityPersisterClass(Class entityPersisterClass) {
this.entityPersisterClass = entityPersisterClass;
}
public Boolean isAbstract() {
return isAbstract;
}
public void setAbstract(Boolean isAbstract) {
this.isAbstract = isAbstract;
}
public void addSynchronizedTable(String tablename) {
if ( synchronizedTableNames == null ) {
synchronizedTableNames = new ArrayList<String>();
}
synchronizedTableNames.add( tablename );
}
// Custom SQL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private String loaderName;
public String getLoaderName() {
return loaderName;
}
public void setLoaderName(String loaderName) {
this.loaderName = loaderName;
}
private CustomSQL customInsert;
private CustomSQL customUpdate;
private CustomSQL customDelete;
public CustomSQL getCustomInsert() {
return customInsert;
}
public void setCustomSqlInsert(String sql, boolean callable, ExecuteUpdateResultCheckStyle resultCheckStyle) {
customInsert = new CustomSQL( sql, callable, resultCheckStyle );
}
public CustomSQL getCustomUpdate() {
return customUpdate;
}
public void setCustomSqlUpdate(String sql, boolean callable, ExecuteUpdateResultCheckStyle resultCheckStyle) {
customUpdate = new CustomSQL( sql, callable, resultCheckStyle );
}
public CustomSQL getCustomDelete() {
return customDelete;
}
public void setCustomSqlDelete(String sql, boolean callable, ExecuteUpdateResultCheckStyle resultCheckStyle) {
customDelete = new CustomSQL( sql, callable, resultCheckStyle );
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.binding;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class EntityDiscriminator {
private final EntityBinding entityBinding;
private SimpleAttributeBinding valueBinding;
private boolean forced;
private boolean inserted = true;
public EntityDiscriminator(EntityBinding entityBinding) {
this.entityBinding = entityBinding;
}
public SimpleAttributeBinding getValueBinding() {
return valueBinding;
}
public void setValueBinding(SimpleAttributeBinding valueBinding) {
this.valueBinding = valueBinding;
}
public boolean isForced() {
return forced;
}
public void setForced(boolean forced) {
this.forced = forced;
}
public boolean isInserted() {
return inserted;
}
public void setInserted(boolean inserted) {
this.inserted = inserted;
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.binding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class EntityIdentifier {
private static final Logger log = LoggerFactory.getLogger( EntityIdentifier.class );
private final EntityBinding entityBinding;
private AttributeBinding attributeBinding;
// todo : generator, mappers, etc
/**
* Create an identifier
* @param entityBinding
*/
public EntityIdentifier(EntityBinding entityBinding) {
this.entityBinding = entityBinding;
}
public AttributeBinding getValueBinding() {
return attributeBinding;
}
public void setValueBinding(AttributeBinding attributeBinding) {
if ( this.attributeBinding != null ) {
// todo : error? or just log? for now just log
log.warn( "setting entity-identifier value binding where one already existed : {}.", entityBinding.getEntity().getName() );
}
this.attributeBinding = attributeBinding;
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.binding;
import java.util.Properties;
import org.hibernate.type.Type;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class HibernateTypeDescriptor {
private String typeName;
private Type explicitType;
private Properties typeParameters;
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public Type getExplicitType() {
return explicitType;
}
public void setExplicitType(Type explicitType) {
this.explicitType = explicitType;
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.binding;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public interface KeyValueBinding extends AttributeBinding {
public boolean isKeyCasadeDeleteEnabled();
public String getUnsavedValue();
public boolean isUpdateable();
}

View File

@ -0,0 +1,344 @@
/*
* 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.binding;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import org.hibernate.FetchMode;
import org.hibernate.metamodel.relational.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public abstract class PluralAttributeBinding extends AbstractAttributeBinding implements AttributeBinding {
private Table collectionTable;
private CollectionKey collectionKey;
private CollectionElement collectionElement;
// private String role;
private boolean lazy;
private boolean extraLazy;
private boolean inverse;
private boolean mutable = true;
private boolean subselectLoadable;
private String cacheConcurrencyStrategy;
private String cacheRegionName;
private String orderBy;
private String where;
private String manyToManyWhere;
private String manyToManyOrderBy;
private String referencedPropertyName;
private String nodeName;
private String elementNodeName;
private boolean sorted;
private Comparator comparator;
private String comparatorClassName;
private boolean orphanDelete;
private int batchSize = -1;
private FetchMode fetchMode;
private boolean embedded = true;
private boolean optimisticLocked = true;
private Class collectionPersisterClass;
private String typeName;
private final java.util.Map filters = new HashMap();
private final java.util.Map manyToManyFilters = new HashMap();
private final java.util.Set synchronizedTables = new HashSet();
private CustomSQL customSQLInsert;
private CustomSQL customSQLUpdate;
private CustomSQL customSQLDelete;
private CustomSQL customSQLDeleteAll;
private String loaderName;
protected PluralAttributeBinding(EntityBinding entityBinding) {
super( entityBinding );
}
@Override
public boolean isSimpleValue() {
return false;
}
public Table getCollectionTable() {
return collectionTable;
}
public void setCollectionTable(Table collectionTable) {
this.collectionTable = collectionTable;
}
public CollectionKey getCollectionKey() {
return collectionKey;
}
public void setCollectionKey(CollectionKey collectionKey) {
this.collectionKey = collectionKey;
}
public CollectionElement getCollectionElement() {
return collectionElement;
}
public void setCollectionElement(CollectionElement collectionElement) {
this.collectionElement = collectionElement;
}
public boolean isLazy() {
return lazy;
}
public void setLazy(boolean lazy) {
this.lazy = lazy;
}
public boolean isExtraLazy() {
return extraLazy;
}
public void setExtraLazy(boolean extraLazy) {
this.extraLazy = extraLazy;
}
public boolean isInverse() {
return inverse;
}
public void setInverse(boolean inverse) {
this.inverse = inverse;
}
public boolean isMutable() {
return mutable;
}
public void setMutable(boolean mutable) {
this.mutable = mutable;
}
public boolean isSubselectLoadable() {
return subselectLoadable;
}
public void setSubselectLoadable(boolean subselectLoadable) {
this.subselectLoadable = subselectLoadable;
}
public String getCacheConcurrencyStrategy() {
return cacheConcurrencyStrategy;
}
public void setCacheConcurrencyStrategy(String cacheConcurrencyStrategy) {
this.cacheConcurrencyStrategy = cacheConcurrencyStrategy;
}
public String getCacheRegionName() {
return cacheRegionName;
}
public void setCacheRegionName(String cacheRegionName) {
this.cacheRegionName = cacheRegionName;
}
public String getOrderBy() {
return orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public String getWhere() {
return where;
}
public void setWhere(String where) {
this.where = where;
}
public String getManyToManyWhere() {
return manyToManyWhere;
}
public void setManyToManyWhere(String manyToManyWhere) {
this.manyToManyWhere = manyToManyWhere;
}
public String getManyToManyOrderBy() {
return manyToManyOrderBy;
}
public void setManyToManyOrderBy(String manyToManyOrderBy) {
this.manyToManyOrderBy = manyToManyOrderBy;
}
public String getReferencedPropertyName() {
return referencedPropertyName;
}
public void setReferencedPropertyName(String referencedPropertyName) {
this.referencedPropertyName = referencedPropertyName;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
public String getElementNodeName() {
return elementNodeName;
}
public void setElementNodeName(String elementNodeName) {
this.elementNodeName = elementNodeName;
}
public boolean isSorted() {
return sorted;
}
public void setSorted(boolean sorted) {
this.sorted = sorted;
}
public Comparator getComparator() {
return comparator;
}
public void setComparator(Comparator comparator) {
this.comparator = comparator;
}
public String getComparatorClassName() {
return comparatorClassName;
}
public void setComparatorClassName(String comparatorClassName) {
this.comparatorClassName = comparatorClassName;
}
public boolean isOrphanDelete() {
return orphanDelete;
}
public void setOrphanDelete(boolean orphanDelete) {
this.orphanDelete = orphanDelete;
}
public int getBatchSize() {
return batchSize;
}
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
public FetchMode getFetchMode() {
return fetchMode;
}
public void setFetchMode(FetchMode fetchMode) {
this.fetchMode = fetchMode;
}
public boolean isEmbedded() {
return embedded;
}
public void setEmbedded(boolean embedded) {
this.embedded = embedded;
}
public boolean isOptimisticLocked() {
return optimisticLocked;
}
public void setOptimisticLocked(boolean optimisticLocked) {
this.optimisticLocked = optimisticLocked;
}
public Class getCollectionPersisterClass() {
return collectionPersisterClass;
}
public void setCollectionPersisterClass(Class collectionPersisterClass) {
this.collectionPersisterClass = collectionPersisterClass;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public CustomSQL getCustomSQLInsert() {
return customSQLInsert;
}
public void setCustomSQLInsert(CustomSQL customSQLInsert) {
this.customSQLInsert = customSQLInsert;
}
public CustomSQL getCustomSQLUpdate() {
return customSQLUpdate;
}
public void setCustomSQLUpdate(CustomSQL customSQLUpdate) {
this.customSQLUpdate = customSQLUpdate;
}
public CustomSQL getCustomSQLDelete() {
return customSQLDelete;
}
public void setCustomSQLDelete(CustomSQL customSQLDelete) {
this.customSQLDelete = customSQLDelete;
}
public CustomSQL getCustomSQLDeleteAll() {
return customSQLDeleteAll;
}
public void setCustomSQLDeleteAll(CustomSQL customSQLDeleteAll) {
this.customSQLDeleteAll = customSQLDeleteAll;
}
public String getLoaderName() {
return loaderName;
}
public void setLoaderName(String loaderName) {
this.loaderName = loaderName;
}
}

View File

@ -0,0 +1,137 @@
/*
* 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.binding;
import org.hibernate.mapping.PropertyGeneration;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class SimpleAttributeBinding extends AbstractAttributeBinding implements KeyValueBinding {
private String propertyAccessorName;
private String cascade;
private PropertyGeneration generation;
private boolean insertable;
private boolean updateable;
private boolean optimisticLockable;
private boolean isLazy;
private boolean keyCasadeDeleteEnabled;
private String unsaveValue;
// DOM4J specific...
private String nodeName;
SimpleAttributeBinding(EntityBinding entityBinding) {
super( entityBinding );
}
@Override
public boolean isSimpleValue() {
return true;
}
public String getPropertyAccessorName() {
return propertyAccessorName;
}
public void setPropertyAccessorName(String propertyAccessorName) {
this.propertyAccessorName = propertyAccessorName;
}
public String getCascade() {
return cascade;
}
public void setCascade(String cascade) {
this.cascade = cascade;
}
public PropertyGeneration getGeneration() {
return generation;
}
public void setGeneration(PropertyGeneration generation) {
this.generation = generation;
}
public boolean isInsertable() {
return insertable;
}
public void setInsertable(boolean insertable) {
this.insertable = insertable;
}
@Override
public boolean isKeyCasadeDeleteEnabled() {
return keyCasadeDeleteEnabled;
}
public void setKeyCasadeDeleteEnabled(boolean keyCasadeDeleteEnabled) {
this.keyCasadeDeleteEnabled = keyCasadeDeleteEnabled;
}
@Override
public String getUnsavedValue() {
return unsaveValue;
}
public void setUnsaveValue(String unsaveValue) {
this.unsaveValue = unsaveValue;
}
public boolean isUpdateable() {
return updateable;
}
public void setUpdateable(boolean updateable) {
this.updateable = updateable;
}
public boolean isOptimisticLockable() {
return optimisticLockable;
}
public void setOptimisticLockable(boolean optimisticLockable) {
this.optimisticLockable = optimisticLockable;
}
public boolean isLazy() {
return isLazy;
}
public void setLazy(boolean lazy) {
isLazy = lazy;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
}

View File

@ -0,0 +1,212 @@
/*
* 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.domain;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Convenient base class for {@link AttributeContainer}. Because in our model all
* {@link AttributeContainer AttributeContainers} are also {@link Hierarchical} we also implement that here
* as well.
*
* @author Steve Ebersole
*/
public abstract class AbstractAttributeContainer implements AttributeContainer, Hierarchical {
private final String name;
private final Hierarchical superType;
private LinkedHashSet<Attribute> attributeSet = new LinkedHashSet<Attribute>();
private HashMap<String,Attribute> attributeMap = new HashMap<String,Attribute>();
public AbstractAttributeContainer(String name, Hierarchical superType) {
this.name = name;
this.superType = superType;
}
@Override
public String getName() {
return name;
}
@Override
public Hierarchical getSuperType() {
return superType;
}
@Override
public Set<Attribute> getAttributes() {
return Collections.unmodifiableSet( attributeSet );
}
@Override
public Attribute getAttribute(String name) {
return attributeMap.get( name );
}
@Override
public SingularAttribute getOrCreateSingularAttribute(String name) {
SingularAttribute attribute = (SingularAttribute) getAttribute( name );
if ( attribute == null ) {
attribute = new SingularAttributeImpl( name, this );
addAttribute( attribute );
}
return attribute;
}
@Override
public PluralAttribute getOrCreateBag(String name) {
return getOrCreatePluralAttribute( name, PluralAttributeNature.BAG );
}
@Override
public PluralAttribute getOrCreateSet(String name) {
return getOrCreatePluralAttribute( name, PluralAttributeNature.SET );
}
@Override
public IndexedPluralAttribute getOrCreateList(String name) {
return (IndexedPluralAttribute) getOrCreatePluralAttribute( name, PluralAttributeNature.LIST );
}
@Override
public IndexedPluralAttribute getOrCreateMap(String name) {
return (IndexedPluralAttribute) getOrCreatePluralAttribute( name, PluralAttributeNature.MAP );
}
@Override
public PluralAttribute getOrCreatePluralAttribute(String name, PluralAttributeNature nature) {
PluralAttribute attribute = (PluralAttribute) getAttribute( name );
if ( attribute == null ) {
attribute = nature.isIndexed()
? new IndexedPluralAttributeImpl( name, nature, this )
: new PluralAttributeImpl( name, nature, this );
addAttribute( attribute );
}
return attribute;
}
protected void addAttribute(Attribute attribute) {
// todo : how to best "secure" this?
if ( attributeMap.put( attribute.getName(), attribute ) != null ) {
throw new IllegalArgumentException( "Attrtibute with name [" + attribute.getName() + "] already registered" );
}
attributeSet.add( attribute );
}
// todo : inner classes for now..
public static class SingularAttributeImpl implements SingularAttribute {
private final AttributeContainer attributeContainer;
private final String name;
public SingularAttributeImpl(String name, AttributeContainer attributeContainer) {
this.name = name;
this.attributeContainer = attributeContainer;
}
@Override
public Type getSingularAttributeType() {
return null;
}
@Override
public String getName() {
return name;
}
@Override
public AttributeContainer getAttributeContainer() {
return attributeContainer;
}
@Override
public boolean isSingular() {
return true;
}
}
public static class PluralAttributeImpl implements PluralAttribute {
private final AttributeContainer attributeContainer;
private final PluralAttributeNature nature;
private final String name;
private Type elementType;
public PluralAttributeImpl(String name, PluralAttributeNature nature, AttributeContainer attributeContainer) {
this.name = name;
this.nature = nature;
this.attributeContainer = attributeContainer;
}
@Override
public AttributeContainer getAttributeContainer() {
return attributeContainer;
}
@Override
public boolean isSingular() {
return false;
}
@Override
public PluralAttributeNature getNature() {
return nature;
}
@Override
public String getName() {
return name;
}
@Override
public Type getElementType() {
return elementType;
}
@Override
public void setElementType(Type elementType) {
this.elementType = elementType;
}
}
public static class IndexedPluralAttributeImpl extends PluralAttributeImpl implements IndexedPluralAttribute {
private Type indexType;
public IndexedPluralAttributeImpl(String name, PluralAttributeNature nature, AttributeContainer attributeContainer) {
super( name, nature, attributeContainer );
}
@Override
public Type getIndexType() {
return indexType;
}
@Override
public void setIndexType(Type indexType) {
this.indexType = indexType;
}
}
}

View File

@ -21,8 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
import javax.persistence.metamodel.PluralAttribute;
package org.hibernate.metamodel.domain;
/**
* Desribes an attribute.

View File

@ -21,7 +21,8 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
import java.util.Set;
/**
@ -38,6 +39,13 @@ public interface AttributeContainer extends Type {
*/
public Set<Attribute> getAttributes();
public SingularAttribute getOrCreateSingularAttribute(String name);
public PluralAttribute getOrCreatePluralAttribute(String name, PluralAttributeNature nature);
public PluralAttribute getOrCreateBag(String name);
public PluralAttribute getOrCreateSet(String name);
public IndexedPluralAttribute getOrCreateList(String name);
public IndexedPluralAttribute getOrCreateMap(String name);
/**
* Retrieve an attribute by name.
*

View File

@ -21,8 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
/**
* Models a basic type, a simple value.

View File

@ -21,8 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
/**
* Models the notion of a component (what JPA calls an Embeddable).

View File

@ -0,0 +1,145 @@
/*
* 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.domain;
import org.hibernate.EntityMode;
/**
* Models the notion of an entity
*
* @author Steve Ebersole
*/
public class Entity extends AbstractAttributeContainer {
private final PojoEntitySpecifics pojoEntitySpecifics = new PojoEntitySpecifics();
private final Dom4jEntitySpecifics dom4jEntitySpecifics = new Dom4jEntitySpecifics();
private final MapEntitySpecifics mapEntitySpecifics = new MapEntitySpecifics();
public Entity(String name, Hierarchical superType) {
super( name, superType );
}
/**
* {@inheritDoc}
*/
public TypeNature getNature() {
return TypeNature.ENTITY;
}
public PojoEntitySpecifics getPojoEntitySpecifics() {
return pojoEntitySpecifics;
}
public Dom4jEntitySpecifics getDom4jEntitySpecifics() {
return dom4jEntitySpecifics;
}
public MapEntitySpecifics getMapEntitySpecifics() {
return mapEntitySpecifics;
}
public static interface EntityModeEntitySpecifics {
public EntityMode getEntityMode();
public String getTuplizerClassName();
}
public static class PojoEntitySpecifics implements EntityModeEntitySpecifics {
private String tuplizerClassName;
private String className;
private String proxyInterfaceName;
@Override
public EntityMode getEntityMode() {
return EntityMode.POJO;
}
public String getTuplizerClassName() {
return tuplizerClassName;
}
public void setTuplizerClassName(String tuplizerClassName) {
this.tuplizerClassName = tuplizerClassName;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getProxyInterfaceName() {
return proxyInterfaceName;
}
public void setProxyInterfaceName(String proxyInterfaceName) {
this.proxyInterfaceName = proxyInterfaceName;
}
}
public static class Dom4jEntitySpecifics implements EntityModeEntitySpecifics {
private String tuplizerClassName;
private String nodeName;
@Override
public EntityMode getEntityMode() {
return EntityMode.DOM4J;
}
public String getTuplizerClassName() {
return tuplizerClassName;
}
public void setTuplizerClassName(String tuplizerClassName) {
this.tuplizerClassName = tuplizerClassName;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
}
public static class MapEntitySpecifics implements EntityModeEntitySpecifics {
private String tuplizerClassName;
@Override
public EntityMode getEntityMode() {
return EntityMode.MAP;
}
public String getTuplizerClassName() {
return tuplizerClassName;
}
public void setTuplizerClassName(String tuplizerClassName) {
this.tuplizerClassName = tuplizerClassName;
}
}
}

View File

@ -21,8 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
/**
* Additional contract for things that can occur in an inheritance hierarchy (specifically ones we would

View File

@ -0,0 +1,34 @@
/*
* 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.domain;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public interface IndexedPluralAttribute extends PluralAttribute {
public Type getIndexType();
public void setIndexType(Type indexType);
}

View File

@ -0,0 +1,35 @@
/*
* 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.domain;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public interface PluralAttribute extends Attribute {
public PluralAttributeNature getNature();
public Type getElementType();
public void setElementType(Type elementType);
}

View File

@ -21,7 +21,8 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -40,10 +41,12 @@ public enum PluralAttributeNature {
private final String name;
private final Class javaContract;
private final boolean indexed;
PluralAttributeNature(String name, Class javaContract) {
this.name = name;
this.javaContract = javaContract;
this.indexed = Map.class.isAssignableFrom( javaContract ) || List.class.isAssignableFrom( javaContract );
}
public String getName() {
@ -53,4 +56,8 @@ public enum PluralAttributeNature {
public Class getJavaContract() {
return javaContract;
}
public boolean isIndexed() {
return indexed;
}
}

View File

@ -21,8 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
/**
* A single valued (non-collection) attribute

View File

@ -21,8 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
/**
* Models the concept of a (intermediate) superclass

View File

@ -21,8 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
/**
* Basic information about a Java type, in regards to its role in particular set of mappings.

View File

@ -21,8 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.domain;
/**
* Describes the type of a type :/

View File

@ -1,75 +0,0 @@
/*
* 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.logical;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Convenient base class for {@link AttributeContainer}. Because in our model all
* {@link AttributeContainer AttributeContainers} are also {@link Hierarchical} we also implement that here
* as well.
*
* @author Steve Ebersole
*/
public abstract class AbstractAttributeContainer implements AttributeContainer, Hierarchical {
private final String name;
private final Hierarchical superType;
private LinkedHashSet<Attribute> attributeSet = new LinkedHashSet<Attribute>();
private HashMap<String,Attribute> attributeMap = new HashMap<String,Attribute>();
public AbstractAttributeContainer(String name, Hierarchical superType) {
this.name = name;
this.superType = superType;
}
@Override
public String getName() {
return name;
}
@Override
public Hierarchical getSuperType() {
return superType;
}
@Override
public Set<Attribute> getAttributes() {
return Collections.unmodifiableSet( attributeSet );
}
@Override
public Attribute getAttribute(String name) {
return attributeMap.get( name );
}
public void addAttribute(Attribute attribute) {
// todo : how to best "secure" this?
if ( attributeMap.put( attribute.getName(), attribute ) != null ) {
throw new IllegalArgumentException( "Attrtibute with name [" + attribute.getName() + "] already registered" );
}
attributeSet.add( attribute );
}
}

View File

@ -22,8 +22,9 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.List;
import java.util.ArrayList;
/**
* Support for writing {@link Constraint} implementations
@ -59,7 +60,7 @@ public abstract class AbstractConstraint implements Constraint {
}
public void addColumn(Column column) {
if ( column.getValueContainer() != getTable() ) {
if ( column.getTable() != getTable() ) {
throw new IllegalArgumentException( "Unable to add column to constraint; tables did not match" );
}
columns.add( column );

View File

@ -22,8 +22,11 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import org.hibernate.HibernateLogger;
import org.jboss.logging.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.metamodel.ValidationException;
/**
* Basic support for {@link SimpleValue} implementations.
@ -31,36 +34,45 @@ import org.jboss.logging.Logger;
* @author Steve Ebersole
*/
public abstract class AbstractSimpleValue implements SimpleValue {
private static final Logger log = LoggerFactory.getLogger( AbstractSimpleValue.class );
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, AbstractSimpleValue.class.getName());
private final ValueContainer container;
private final TableSpecification table;
private final int position;
private Datatype datatype;
protected AbstractSimpleValue(ValueContainer container) {
this.container = container;
protected AbstractSimpleValue(TableSpecification table, int position) {
this.table = table;
this.position = position;
}
/**
* {@inheritDoc}
*/
public ValueContainer getValueContainer() {
return container;
@Override
public TableSpecification getTable() {
return table;
}
/**
* {@inheritDoc}
*/
public int getPosition() {
return position;
}
@Override
public Datatype getDatatype() {
return datatype;
}
/**
* {@inheritDoc}
*/
@Override
public void setDatatype(Datatype datatype) {
LOG.debugf("Setting datatype for column %s : %s", toLoggableString(), datatype);
if (this.datatype != null && !this.datatype.equals(datatype)) LOG.debugf("Overriding previous datatype : %s", this.datatype);
log.debug( "setting datatype for column {} : {}", toLoggableString(), datatype );
if ( this.datatype != null && ! this.datatype.equals( datatype ) ) {
log.debug( "overriding previous datatype : {}", this.datatype );
}
this.datatype = datatype;
}
@Override
public void validateJdbcTypes(JdbcCodes typeCodes) {
// todo : better compatibility testing...
if ( datatype.getTypeCode() != typeCodes.nextJdbcCde() ) {
throw new ValidationException( "Mismatched types" );
}
}
}

View File

@ -22,7 +22,9 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
/**
@ -31,10 +33,35 @@ import java.util.List;
*
* @author Steve Ebersole
*/
public abstract class AbstractTableSpecification extends AbstractValueContainer implements TableSpecification {
public abstract class AbstractTableSpecification implements TableSpecification, ValueContainer {
private final LinkedHashSet<SimpleValue> values = new LinkedHashSet<SimpleValue>();
private PrimaryKey primaryKey = new PrimaryKey( this );
private List<ForeignKey> foreignKeys = new ArrayList<ForeignKey>();
@Override
public Iterable<SimpleValue> values() {
return values;
}
@Override
public Column createColumn(String name) {
final Column column = new Column( this, values.size(), name );
values.add( column );
return column;
}
@Override
public DerivedValue createDerivedValue(String fragment) {
final DerivedValue value = new DerivedValue( this, values.size(), fragment );
values.add( value );
return value;
}
@Override
public Tuple createTuple(String name) {
return new Tuple( this, name );
}
@Override
public Iterable<ForeignKey> getForeignKeys() {
return foreignKeys;

View File

@ -1,60 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @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.relational;
import java.util.LinkedHashSet;
/**
* Convenience base class for implementing the {@link ValueContainer} contract
*
* @author Steve Ebersole
*/
public abstract class AbstractValueContainer implements ValueContainer {
private final LinkedHashSet<Value> values = new LinkedHashSet<Value>();
@Override
public Iterable<Value> values() {
return values;
}
@Override
public Column createColumn(String name) {
final Column column = new Column( this, name );
values.add( column );
return column;
}
@Override
public DerivedValue createDerivedValue(String fragment) {
final DerivedValue value = new DerivedValue( this, fragment );
values.add( value );
return value;
}
@Override
public Tuple createTuple(String name) {
final Tuple tuple = new Tuple( this, name );
values.add( tuple );
return tuple;
}
}

View File

@ -0,0 +1,71 @@
/*
* 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.relational;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class CheckConstraint {
private final Table table;
private String name;
private String condition;
public CheckConstraint(Table table) {
this.table = table;
}
public CheckConstraint(Table table, String name, String condition) {
this.table = table;
this.name = name;
this.condition = condition;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
/**
* Obtain the table to which this constraint applies.
*
* @return The constrained table.
*/
public Table getTable() {
return table;
}
/**
* Obtain the constraint name.
*
* @return the name.
*/
public String getName() {
return name;
}
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a physical column
*
@ -32,10 +31,22 @@ package org.hibernate.metamodel.relational;
*/
public class Column extends AbstractSimpleValue implements SimpleValue {
private final String name;
private Size size;
private boolean nullable;
private boolean unique;
protected Column(ValueContainer table, String name) {
super( table );
private String defaultValue;
private String checkCondition;
private String sqlType;
private String readFragment;
private String writeFragment;
private String comment;
private Size size = new Size();
protected Column(TableSpecification table, int position, String name) {
super( table, position );
this.name = name;
}
@ -43,6 +54,70 @@ public class Column extends AbstractSimpleValue implements SimpleValue {
return name;
}
public boolean isNullable() {
return nullable;
}
public void setNullable(boolean nullable) {
this.nullable = nullable;
}
public boolean isUnique() {
return unique;
}
public void setUnique(boolean unique) {
this.unique = unique;
}
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
public String getCheckCondition() {
return checkCondition;
}
public void setCheckCondition(String checkCondition) {
this.checkCondition = checkCondition;
}
public String getSqlType() {
return sqlType;
}
public void setSqlType(String sqlType) {
this.sqlType = sqlType;
}
public String getReadFragment() {
return readFragment;
}
public void setReadFragment(String readFragment) {
this.readFragment = readFragment;
}
public String getWriteFragment() {
return writeFragment;
}
public void setWriteFragment(String writeFragment) {
this.writeFragment = writeFragment;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Size getSize() {
return size;
}
@ -53,7 +128,7 @@ public class Column extends AbstractSimpleValue implements SimpleValue {
@Override
public String toLoggableString() {
return getValueContainer().getLoggableValueQualifier() + '.' + getName();
return getTable().getLoggableValueQualifier() + '.' + getName();
}
/**
@ -64,12 +139,30 @@ public class Column extends AbstractSimpleValue implements SimpleValue {
* definitions, by standard, are allowed a "multiplier" consisting of 'K' (Kb), 'M' (Mb) or 'G' (Gb).
*/
public static class Size {
private static enum LobMultiplier { K, M, G }
private static enum LobMultiplier {
NONE( 1 ),
K( NONE.factor * 1024 ),
M( K.factor * 1024 ),
G( M.factor * 1024 );
private final int precision;
private final int scale;
private final long length;
private final LobMultiplier lobMultiplier;
private long factor;
private LobMultiplier(long factor) {
this.factor = factor;
}
public long getFactor() {
return factor;
}
}
private int precision = - 1;
private int scale = -1;
private long length = -1;
private LobMultiplier lobMultiplier = LobMultiplier.NONE;
public Size() {
}
/**
* Complete constructor.
@ -117,5 +210,21 @@ public class Column extends AbstractSimpleValue implements SimpleValue {
public LobMultiplier getLobMultiplier() {
return lobMultiplier;
}
public void setPrecision(int precision) {
this.precision = precision;
}
public void setScale(int scale) {
this.scale = scale;
}
public void setLength(long length) {
this.length = length;
}
public void setLobMultiplier(LobMultiplier lobMultiplier) {
this.lobMultiplier = lobMultiplier;
}
}
}

View File

@ -23,7 +23,7 @@
*/
package org.hibernate.metamodel.relational;
import java.util.List;
/**
* Basic contract for the types of constraints we fully support as metadata constructs:<ul>

View File

@ -0,0 +1,53 @@
/*
* 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.relational;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a database and manages the named schema/catalog pairs defined within.
*
* @author Steve Ebersole
*/
public class Database {
private Map<Schema.Name,Schema> schemaMap = new HashMap<Schema.Name, Schema>();
public Schema getSchema(Schema.Name name) {
Schema schema = schemaMap.get( name );
if ( schema == null ) {
schema = new Schema( name );
schemaMap.put( name, schema );
}
return schema;
}
public Schema getSchema(Identifier schema, Identifier catalog) {
return getSchema( new Schema.Name( schema, catalog ) );
}
public Schema getSchema(String schema, String catalog) {
return getSchema( new Schema.Name( Identifier.toIdentifier( schema ), Identifier.toIdentifier( catalog ) ) );
}
}

View File

@ -23,11 +23,10 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a JDBC {@link java.sql.Types DATATYPE}
*
* @todo Do we somehow link this in with {@link org.hibernate.engine.jdbc.internal.TypeInfo} ?
* @todo Do we somehow link this in with {@link org.hibernate.internal.util.jdbc.TypeInfo} ?
*
* @author Steve Ebersole
*/

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a value expression. It is the result of a <tt>formula</tt> mapping.
*
@ -32,8 +31,8 @@ package org.hibernate.metamodel.relational;
public class DerivedValue extends AbstractSimpleValue implements SimpleValue {
private final String expression;
public DerivedValue(ValueContainer table, String expression) {
super( table );
public DerivedValue(TableSpecification table, int position, String expression) {
super( table, position );
this.expression = expression;
}
@ -41,6 +40,6 @@ public class DerivedValue extends AbstractSimpleValue implements SimpleValue {
* {@inheritDoc}
*/
public String toLoggableString() {
return getValueContainer().toLoggableString() + ".{derived-column}";
return getTable().toLoggableString() + ".{derived-column}";
}
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Contract for entities (in the ERD sense) which can be exported via {@code CREATE}, {@code ALTER}, etc
*

View File

@ -22,10 +22,12 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.HibernateLogger;
import org.jboss.logging.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Models the notion of a foreign key.
@ -37,11 +39,12 @@ import org.jboss.logging.Logger;
* @author Steve Ebersole
*/
public class ForeignKey extends AbstractConstraint implements Constraint, Exportable {
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, ForeignKey.class.getName());
private static final Logger log = LoggerFactory.getLogger( ForeignKey.class );
private final TableSpecification targetTable;
private List<Column> targetColumns;
private ReferentialAction deleteRule = ReferentialAction.NO_ACTION;
public ReferentialAction updateRule = ReferentialAction.NO_ACTION;
protected ForeignKey(TableSpecification sourceTable, TableSpecification targetTable, String name) {
super( sourceTable, name );
@ -77,13 +80,25 @@ public class ForeignKey extends AbstractConstraint implements Constraint, Export
public void addColumnMapping(Column sourceColumn, Column targetColumn) {
if ( targetColumn == null ) {
if (targetColumns != null) LOG.attemptToMapColumnToNoTargetColumn(sourceColumn.toLoggableString(), getName());
if ( targetColumns != null ) {
if ( log.isWarnEnabled() ) {
log.warn(
"Attempt to map column [" + sourceColumn.toLoggableString()
+ "] to no target column after explicit target column(s) named for FK [name="
+ getName() + "]"
);
}
}
}
else {
if ( targetColumns == null ) {
if (!internalColumnAccess().isEmpty()) LOG.valueMappingMismatch(getTable().toLoggableString(),
getName(),
sourceColumn.toLoggableString());
if ( !internalColumnAccess().isEmpty() ) {
log.warn(
"Value mapping mismatch as part of FK [table=" + getTable().toLoggableString()
+ ", name=" + getName() + "] while adding source column ["
+ sourceColumn.toLoggableString() + "]"
);
}
targetColumns = new ArrayList<Column>();
}
targetColumns.add( targetColumn );
@ -96,9 +111,27 @@ public class ForeignKey extends AbstractConstraint implements Constraint, Export
return getSourceTable().getLoggableValueQualifier() + ".FK-" + getName();
}
public void validate() {
if ( getSourceTable() == null ) {
public ReferentialAction getDeleteRule() {
return deleteRule;
}
}
public void setDeleteRule(ReferentialAction deleteRule) {
this.deleteRule = deleteRule;
}
public ReferentialAction getUpdateRule() {
return updateRule;
}
public void setUpdateRule(ReferentialAction updateRule) {
this.updateRule = updateRule;
}
public static enum ReferentialAction {
NO_ACTION,
CASCADE,
SET_NULL,
SET_DEFAULT,
RESTRICT
}
}

View File

@ -23,6 +23,7 @@
*/
package org.hibernate.metamodel.relational;
import org.hibernate.internal.util.StringHelper;
/**

View File

@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import org.hibernate.HibernateException;
/**

View File

@ -22,8 +22,8 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import java.util.HashSet;
import java.util.Set;
import java.util.Collections;
/**
* A <tt>data container</tt> defined by a <tt>SELECT</tt> statement. This translates into an inline view in the
@ -33,13 +33,18 @@ import java.util.Set;
* @author Steve Ebersole
*/
public class InLineView extends AbstractTableSpecification implements ValueContainer {
private final Schema schema;
private final String logicalName;
private final String select;
private final String uniqueValueQualifier;
private Set<ObjectName> synchronizedTableSpaces = java.util.Collections.emptySet();
public InLineView(String select, String uniqueValueQualifier) {
public InLineView(Schema schema, String logicalName, String select) {
this.schema = schema;
this.logicalName = logicalName;
this.select = select;
this.uniqueValueQualifier = uniqueValueQualifier;
}
public Schema getSchema() {
return schema;
}
public String getSelect() {
@ -48,23 +53,47 @@ public class InLineView extends AbstractTableSpecification implements ValueConta
@Override
public String getLoggableValueQualifier() {
return uniqueValueQualifier;
}
public void addSynchronizedTable(String tableName) {
addSynchronizedTable( new ObjectName( null, null, tableName ) );
}
public void addSynchronizedTable(ObjectName tableName) {
if ( synchronizedTableSpaces.isEmpty() ) {
synchronizedTableSpaces = new HashSet<ObjectName>();
}
synchronizedTableSpaces.add( tableName );
return logicalName;
}
@Override
public Set<ObjectName> getSpaces() {
return synchronizedTableSpaces;
public Iterable<Index> getIndexes() {
return Collections.emptyList();
}
@Override
public Index getOrCreateIndex(String name) {
throw new UnsupportedOperationException( "Cannot create index on inline view" );
}
@Override
public Iterable<UniqueKey> getUniqueKeys() {
return Collections.emptyList();
}
@Override
public UniqueKey getOrCreateUniqueKey(String name) {
throw new UnsupportedOperationException( "Cannot create unique-key on inline view" );
}
@Override
public Iterable<String> getCheckConstraints() {
return Collections.emptyList();
}
@Override
public void addCheckConstraint(String checkCondition) {
throw new UnsupportedOperationException( "Cannot create check constraint on inline view" );
}
@Override
public Iterable<String> getComments() {
return Collections.emptyList();
}
@Override
public void addComment(String comment) {
throw new UnsupportedOperationException( "Cannot comment on inline view" );
}
@Override

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a SQL <tt>INDEX</tt>
*

View File

@ -21,23 +21,18 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.logical;
package org.hibernate.metamodel.relational;
/**
* Models the notion of an entity
* Marker for things which can be logged.
*
* @author Steve Ebersole
*/
public class Entity extends AbstractAttributeContainer {
public Entity(String name, Hierarchical superType) {
super( name, superType );
}
public interface Loggable {
/**
* {@inheritDoc}
* Obtain the string representation of this value usable in log statements.
*
* @return The loggable representation
*/
public TypeNature getNature() {
return TypeNature.ENTITY;
}
public String toLoggableString();
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models the qualified name of a database object.
* <p/>
@ -45,6 +44,14 @@ public class ObjectName {
this( null, null, name );
}
public ObjectName(Schema schema, String name) {
this( schema.getName().getSchema(), schema.getName().getCatalog(), Identifier.toIdentifier( name ) );
}
public ObjectName(Schema schema, Identifier name) {
this( schema.getName().getSchema(), schema.getName().getCatalog(), name );
}
public ObjectName(String schemaName, String catalogName, String name) {
this(
Identifier.toIdentifier( schemaName ),
@ -96,7 +103,7 @@ public class ObjectName {
return name;
}
public String getIdentifier() {
public String toText() {
return identifier;
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a table's primary key.
* <p/>

View File

@ -0,0 +1,94 @@
/*
* 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.relational;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a named schema/catalog pair and manages objects defined within.
*
* @author Steve Ebersole
*/
public class Schema {
public static class Name {
private final Identifier schema;
private final Identifier catalog;
public Name(Identifier schema, Identifier catalog) {
this.schema = schema;
this.catalog = catalog;
}
public Name(String schema, String catalog) {
this( Identifier.toIdentifier( schema ), Identifier.toIdentifier( catalog ) );
}
public Identifier getSchema() {
return schema;
}
public Identifier getCatalog() {
return catalog;
}
}
private final Name name;
public Schema(Name name) {
this.name = name;
}
public Schema(Identifier schema, Identifier catalog) {
this( new Name( schema, catalog ) );
}
public Name getName() {
return name;
}
private Map<Identifier,Table> tables = new HashMap<Identifier, Table>();
public Table getTable(Identifier name) {
return tables.get( name );
}
public Table createTable(Identifier name) {
Table table = new Table( this, name );
tables.put( name, table );
return table;
}
private Map<String,InLineView> inLineViews = new HashMap<String, InLineView>();
public InLineView getInLineView(String logicalName) {
return inLineViews.get( logicalName );
}
public InLineView createInLineView(String logicalName, String subSelect) {
InLineView inLineView = new InLineView( this, logicalName, subSelect );
inLineViews.put( logicalName, inLineView );
return inLineView;
}
}

View File

@ -23,31 +23,42 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a database {@code SEQUENCE}.
*
* @author Steve Ebersole
*/
public class Sequence implements Exportable {
private final ObjectName name;
private final int initialValue;
private final int incrementSize;
private final Schema schema;
private final String name;
private final String qualifiedName;
private int initialValue = 1;
private int incrementSize = 1;
public Sequence(ObjectName name, int initialValue, int incrementSize) {
public Sequence(Schema schema, String name) {
this.schema = schema;
this.name = name;
this.qualifiedName = new ObjectName( schema, name ).toText();
}
public Sequence(Schema schema, String name, int initialValue, int incrementSize) {
this( schema, name );
this.initialValue = initialValue;
this.incrementSize = incrementSize;
}
public String getExportIdentifier() {
return name.getIdentifier();
public Schema getSchema() {
return schema;
}
public ObjectName getName() {
public String getName() {
return name;
}
public String getExportIdentifier() {
return qualifiedName;
}
public int getInitialValue() {
return initialValue;
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a simple, non-compound value.
*

View File

@ -22,7 +22,9 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -33,42 +35,56 @@ import java.util.Set;
* @author Steve Ebersole
*/
public class Table extends AbstractTableSpecification implements ValueContainer, Exportable {
private final ObjectName name;
private final Set<ObjectName> spaces;
private final Schema database;
private final Identifier tableName;
private final String qualifiedName;
private List<Index> indexes;
private List<UniqueKey> uniqueKeys;
private List<String> checkConstraints;
private Set<String> comments;
public Table(ObjectName name) {
this.name = name;
this.spaces = java.util.Collections.singleton( name );
public Table(Schema database, String tableName) {
this( database, Identifier.toIdentifier( tableName ) );
}
public ObjectName getObjectName() {
return name;
public Table(Schema database, Identifier tableName) {
this.database = database;
this.tableName = tableName;
ObjectName objectName = new ObjectName( database.getName().getSchema(), database.getName().getCatalog(), tableName );
this.qualifiedName = objectName.toText();
}
@Override
public Schema getSchema() {
return database;
}
public Identifier getTableName() {
return tableName;
}
@Override
public String getLoggableValueQualifier() {
return getObjectName().getIdentifier();
return qualifiedName;
}
@Override
public String getExportIdentifier() {
return getObjectName().getIdentifier();
}
@Override
public Iterable<ObjectName> getSpaces() {
return spaces;
return qualifiedName;
}
@Override
public String toLoggableString() {
return getObjectName().getIdentifier();
return qualifiedName;
}
public Index createIndex(String name) {
@Override
public Iterable<Index> getIndexes() {
return indexes;
}
public Index getOrCreateIndex(String name) {
Index index = new Index( this, name );
if ( indexes == null ) {
indexes = new ArrayList<Index>();
@ -77,7 +93,12 @@ public class Table extends AbstractTableSpecification implements ValueContainer,
return index;
}
public UniqueKey createUniqueKey(String name) {
@Override
public Iterable<UniqueKey> getUniqueKeys() {
return uniqueKeys;
}
public UniqueKey getOrCreateUniqueKey(String name) {
UniqueKey uniqueKey = new UniqueKey( this, name );
if ( uniqueKeys == null ) {
uniqueKeys = new ArrayList<UniqueKey>();
@ -86,10 +107,34 @@ public class Table extends AbstractTableSpecification implements ValueContainer,
return uniqueKey;
}
@Override
public Iterable<String> getCheckConstraints() {
return checkConstraints;
}
@Override
public void addCheckConstraint(String checkCondition) {
if ( checkConstraints == null ) {
checkConstraints = new ArrayList<String>();
}
checkConstraints.add( checkCondition );
}
@Override
public Iterable<String> getComments() {
return comments;
}
@Override
public void addComment(String comment) {
if ( comments == null ) {
comments = new HashSet<String>();
}
comments.add( comment );
}
@Override
public String toString() {
return "Table{" +
"name=" + getObjectName().getIdentifier() +
'}';
return "Table{name=" + qualifiedName + '}';
}
}

View File

@ -23,13 +23,21 @@
*/
package org.hibernate.metamodel.relational;
import java.util.ArrayList;
/**
* Models what ANSI SQL terms a table specification which is a table or a view or an inline view.
*
* @author Steve Ebersole
*/
public interface TableSpecification extends ValueContainer {
public interface TableSpecification extends ValueContainer, Loggable {
/**
* Obtain a reference to the schema to which this table specification belongs.
*
* @return The schema to which this table specification belongs.
*/
public Schema getSchema();
/**
* Get the primary key definition for this table spec.
*
@ -37,14 +45,50 @@ public interface TableSpecification extends ValueContainer {
*/
public PrimaryKey getPrimaryKey();
public ForeignKey createForeignKey(TableSpecification targetTable, String name);
/**
* Factory method for creating a {@link Column} associated with this container.
*
* @param name The column name
*
* @return The generated column
*/
public Column createColumn(String name);
/**
* Factory method for creating a {@link Column} associated with this container.
*
* @param name The column name
*
* @return The generated column
*/
public Tuple createTuple(String name);
/**
* Factory method for creating a {@link DerivedValue} associated with this container.
*
* @param fragment The value expression
*
* @return The generated value.
*/
public DerivedValue createDerivedValue(String fragment);
public Iterable<ForeignKey> getForeignKeys();
/**
* Get the physical table names modelled here. This is especially important in the case of an inline view.
*
* @return The spaces.
*/
public Iterable<ObjectName> getSpaces();
public ForeignKey createForeignKey(TableSpecification targetTable, String name);
public Iterable<Index> getIndexes();
public Index getOrCreateIndex(String name);
public Iterable<UniqueKey> getUniqueKeys();
public UniqueKey getOrCreateUniqueKey(String name);
public Iterable<String> getCheckConstraints();
public void addCheckConstraint(String checkCondition);
public Iterable<String> getComments();
public void addComment(String comment);
}

View File

@ -23,6 +23,7 @@
*/
package org.hibernate.metamodel.relational;
import java.util.LinkedHashSet;
/**
* Models a compound value (a tuple or row-value-constructor is SQL terms). It is both a {@link Value} and
@ -40,27 +41,47 @@ package org.hibernate.metamodel.relational;
*
* @author Steve Ebersole
*/
public class Tuple extends AbstractValueContainer implements Value {
private final ValueContainer valueContainer;
public class Tuple implements Value, ValueContainer, Loggable {
private final TableSpecification table;
private final String name;
private final LinkedHashSet<SimpleValue> values = new LinkedHashSet<SimpleValue>();
public Tuple(ValueContainer valueContainer, String name) {
public Tuple(TableSpecification table, String name) {
this.table = table;
this.name = name;
this.valueContainer = valueContainer;
}
@Override
public ValueContainer getValueContainer() {
return valueContainer;
public TableSpecification getTable() {
return table;
}
@Override
public Iterable<SimpleValue> values() {
return values;
}
public void addValue(SimpleValue value) {
if ( ! value.getTable().equals( getTable() ) ) {
throw new IllegalArgumentException( "Tuple can only group values from same table" );
}
values.add( value );
}
@Override
public String getLoggableValueQualifier() {
return getValueContainer().getLoggableValueQualifier() + '.' + name;
return getTable().getLoggableValueQualifier() + '.' + name + "{tuple}";
}
@Override
public String toLoggableString() {
return getLoggableValueQualifier() + "{tuple}";
return getLoggableValueQualifier();
}
@Override
public void validateJdbcTypes(JdbcCodes typeCodes) {
for ( Value value : values() ) {
value.validateJdbcTypes( typeCodes );
}
}
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a SQL <tt>INDEX</tt> defined as UNIQUE
*

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Models a value within a {@link ValueContainer}. This will generally be either a {@link Column column} or a
* {@link DerivedValue derived value}, but we also allow the notion of {@link Tuple} at this level
@ -36,7 +35,7 @@ public interface Value {
*
* @return The owning table.
*/
public ValueContainer getValueContainer();
public TableSpecification getTable();
/**
* Obtain the string representation of this value usable in log statements.
@ -44,4 +43,36 @@ public interface Value {
* @return The loggable representation
*/
public String toLoggableString();
/**
* Used to track JDBC type usage throughout a series of potential recursive calls to component
* values since we do not know ahead of time which values correspond to which indexes of the
* jdbc type array.
*/
public static class JdbcCodes {
private final int[] typeCodes;
private int index = 0;
public JdbcCodes(int[] typeCodes) {
this.typeCodes = typeCodes;
}
public int nextJdbcCde() {
return typeCodes[index++];
}
public int getIndex() {
return index;
}
}
/**
* Validate the value against the incoming JDBC type code array, both in terms of number of types
* and compatibility of types.
*
* @param typeCodes The type codes.
*
* @throws org.hibernate.metamodel.ValidationException if validaton fails.
*/
public void validateJdbcTypes(JdbcCodes typeCodes);
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.relational;
/**
* Contract for data containers (what the ANSI SQL spec calls "table specifications") to which we can map
* entity state. The two flavors here are {@link Table physical table} and {@link InLineView inline view}, but a
@ -37,7 +36,7 @@ public interface ValueContainer {
*
* @return Iterator over value definitions.
*/
public Iterable<Value> values();
public Iterable<SimpleValue> values();
/**
* Get a qualifier which can be used to qualify {@link Value values} belonging to this container in
@ -46,38 +45,4 @@ public interface ValueContainer {
* @return The qualifier
*/
public String getLoggableValueQualifier();
/**
* Obtain the string representation of this value usable in log statements.
*
* @return The loggable representation
*/
public String toLoggableString();
/**
* Factory method for creating a {@link Column} associated with this container.
*
* @param name The column name
*
* @return The generated column
*/
public Column createColumn(String name);
/**
* Factory method for creating a {@link DerivedValue} associated with this container.
*
* @param fragment The value expression
*
* @return The generated value.
*/
public DerivedValue createDerivedValue(String fragment);
/**
* Factory method for creating a {@link Tuple} associated with this container.
*
* @param name The (logical) tuple name
*
* @return The generated tuple.
*/
public Tuple createTuple(String name);
}

View File

@ -0,0 +1,98 @@
/*
* 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;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.MappingException;
import org.hibernate.cfg.ExtendsQueueEntry;
import org.hibernate.metamodel.source.hbm.HbmHelper;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class ExtendsQueue implements Serializable {
private static final Logger log = LoggerFactory.getLogger( ExtendsQueue.class );
private final Metadata metadata;
private Set<ExtendsQueueEntry> extendsQueue = new HashSet<ExtendsQueueEntry>();
public ExtendsQueue(Metadata metadata) {
this.metadata = metadata;
}
public void add(ExtendsQueueEntry extendsQueueEntry) {
extendsQueue.add( extendsQueueEntry );
}
public int processExtendsQueue() {
log.debug( "processing extends queue" );
int added = 0;
ExtendsQueueEntry extendsQueueEntry = findPossibleExtends();
while ( extendsQueueEntry != null ) {
metadata.getMetadataSourceQueue().processHbmXml( extendsQueueEntry.getMetadataXml(), extendsQueueEntry.getEntityNames() );
extendsQueueEntry = findPossibleExtends();
}
if ( extendsQueue.size() > 0 ) {
Iterator iterator = extendsQueue.iterator();
StringBuffer buf = new StringBuffer( "Following super classes referenced in extends not found: " );
while ( iterator.hasNext() ) {
final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iterator.next();
buf.append( entry.getExplicitName() );
if ( entry.getMappingPackage() != null ) {
buf.append( "[" ).append( entry.getMappingPackage() ).append( "]" );
}
if ( iterator.hasNext() ) {
buf.append( "," );
}
}
throw new MappingException( buf.toString() );
}
return added;
}
protected ExtendsQueueEntry findPossibleExtends() {
Iterator<ExtendsQueueEntry> itr = extendsQueue.iterator();
while ( itr.hasNext() ) {
final ExtendsQueueEntry entry = itr.next();
boolean found = metadata.getEntityBinding( entry.getExplicitName() ) == null
&& metadata.getEntityBinding( HbmHelper.getClassName( entry.getExplicitName(), entry.getMappingPackage() ) ) != null;
if ( found ) {
itr.remove();
return entry;
}
}
return null;
}
}

View File

@ -0,0 +1,189 @@
/*
* 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;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.DuplicateMappingException;
import org.hibernate.annotations.common.reflection.MetadataProvider;
import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
import org.hibernate.cfg.EJB3NamingStrategy;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.MetadataSource;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.relational.Database;
import org.hibernate.metamodel.source.hbm.HibernateXmlBinder;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class Metadata implements Serializable {
private static final Logger log = LoggerFactory.getLogger( Metadata.class );
private final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this );
private final ExtendsQueue extendsQueue = new ExtendsQueue( this );
private final MetadataSourceQueue metadataSourceQueue = new MetadataSourceQueue( this );
private transient ReflectionManager reflectionManager = createReflectionManager();
public HibernateXmlBinder getHibernateXmlBinder() {
return hibernateXmlBinder;
}
public ExtendsQueue getExtendsQueue() {
return extendsQueue;
}
public MetadataSourceQueue getMetadataSourceQueue() {
return metadataSourceQueue;
}
public ReflectionManager getReflectionManager() {
return reflectionManager;
}
public void setReflectionManager(ReflectionManager reflectionManager) {
this.reflectionManager = reflectionManager;
}
private ReflectionManager createReflectionManager() {
return createReflectionManager( new JPAMetadataProvider() );
}
private ReflectionManager createReflectionManager(MetadataProvider metadataProvider) {
ReflectionManager reflectionManager = new JavaReflectionManager();
( (MetadataProviderInjector) reflectionManager ).setMetadataProvider( metadataProvider );
return reflectionManager;
}
private final Database database = new Database();
public Database getDatabase() {
return database;
}
private NamingStrategy namingStrategy = EJB3NamingStrategy.INSTANCE;
public NamingStrategy getNamingStrategy() {
return namingStrategy;
}
public void setNamingStrategy(NamingStrategy namingStrategy) {
this.namingStrategy = namingStrategy;
}
private Map<String,EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();
public EntityBinding getEntityBinding(String entityName) {
return entityBindingMap.get( entityName );
}
public Iterable<EntityBinding> getEntityBindings() {
return entityBindingMap.values();
}
public void addEntity(EntityBinding entityBinding) {
final String entityName = entityBinding.getEntity().getName();
if ( entityBindingMap.containsKey( entityName ) ) {
throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, entityName );
}
entityBindingMap.put( entityName, entityBinding );
}
private Map<String,PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
public PluralAttributeBinding getCollection(String collectionRole) {
return collectionBindingMap.get( collectionRole );
}
public Iterable<PluralAttributeBinding> getCollections() {
return collectionBindingMap.values();
}
public void addCollection(PluralAttributeBinding pluralAttributeBinding) {
final String owningEntityName = pluralAttributeBinding.getEntityBinding().getEntity().getName();
final String attributeName = pluralAttributeBinding.getAttribute().getName();
final String collectionRole = owningEntityName + '.' + attributeName;
if ( collectionBindingMap.containsKey( collectionRole ) ) {
throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, collectionRole );
}
collectionBindingMap.put( collectionRole, pluralAttributeBinding );
}
private Map<String,String> imports;
public void addImport(String importName, String entityName) {
if ( imports == null ) {
imports = new HashMap<String, String>();
}
log.trace( "Import: " + importName + " -> " + entityName );
String old = imports.put( importName, entityName );
if ( old != null ) {
log.debug( "import name [{}] overrode previous [{}]", importName, old );
}
}
private Map<String,FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>();
public Iterable<FetchProfile> getFetchProfiles() {
return fetchProfiles.values();
}
public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource source) {
FetchProfile profile = fetchProfiles.get( profileName );
if ( profile == null ) {
profile = new FetchProfile( profileName, source );
fetchProfiles.put( profileName, profile );
}
return profile;
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
//we need reflectionManager before reading the other components (MetadataSourceQueue in particular)
final MetadataProvider metadataProvider = (MetadataProvider) ois.readObject();
this.reflectionManager = createReflectionManager( metadataProvider );
ois.defaultReadObject();
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
//We write MetadataProvider first as we need reflectionManager before reading the other components
final MetadataProvider metadataProvider = ( ( MetadataProviderInjector ) reflectionManager ).getMetadataProvider();
out.writeObject( metadataProvider );
out.defaultWriteObject();
}
}

View File

@ -0,0 +1,276 @@
/*
* 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;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Entity;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.InvalidMappingException;
import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.cfg.MetadataSourceType;
import org.hibernate.internal.util.collections.JoinedIterator;
import org.hibernate.internal.util.xml.XmlDocument;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class MetadataSourceQueue implements Serializable {
private static final Logger log = LoggerFactory.getLogger( MetadataSourceQueue.class );
private final Metadata metadata;
private LinkedHashMap<XmlDocument, Set<String>> hbmMetadataToEntityNamesMap
= new LinkedHashMap<XmlDocument, Set<String>>();
private Map<String, XmlDocument> hbmMetadataByEntityNameXRef = new HashMap<String, XmlDocument>();
//XClass are not serializable by default
private transient List<XClass> annotatedClasses = new ArrayList<XClass>();
//only used during the secondPhaseCompile pass, hence does not need to be serialized
private transient Map<String, XClass> annotatedClassesByEntityNameMap = new HashMap<String, XClass>();
public MetadataSourceQueue(Metadata metadata) {
this.metadata = metadata;
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
annotatedClassesByEntityNameMap = new HashMap<String, XClass>();
//build back annotatedClasses
@SuppressWarnings("unchecked")
List<Class> serializableAnnotatedClasses = (List<Class>) ois.readObject();
annotatedClasses = new ArrayList<XClass>( serializableAnnotatedClasses.size() );
for ( Class clazz : serializableAnnotatedClasses ) {
annotatedClasses.add( metadata.getReflectionManager().toXClass( clazz ) );
}
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
List<Class> serializableAnnotatedClasses = new ArrayList<Class>( annotatedClasses.size() );
for ( XClass xClass : annotatedClasses ) {
serializableAnnotatedClasses.add( metadata.getReflectionManager().toClass( xClass ) );
}
out.writeObject( serializableAnnotatedClasses );
}
public void add(XmlDocument metadataXml) {
final Document document = metadataXml.getDocumentTree();
final Element hmNode = document.getRootElement();
Attribute packNode = hmNode.attribute( "package" );
String defaultPackage = packNode != null ? packNode.getValue() : "";
Set<String> entityNames = new HashSet<String>();
findClassNames( defaultPackage, hmNode, entityNames );
for ( String entity : entityNames ) {
hbmMetadataByEntityNameXRef.put( entity, metadataXml );
}
this.hbmMetadataToEntityNamesMap.put( metadataXml, entityNames );
}
private void findClassNames(String defaultPackage, Element startNode, Set<String> names) {
// if we have some extends we need to check if those classes possibly could be inside the
// same hbm.xml file...
Iterator[] classes = new Iterator[4];
classes[0] = startNode.elementIterator( "class" );
classes[1] = startNode.elementIterator( "subclass" );
classes[2] = startNode.elementIterator( "joined-subclass" );
classes[3] = startNode.elementIterator( "union-subclass" );
Iterator classIterator = new JoinedIterator( classes );
while ( classIterator.hasNext() ) {
Element element = (Element) classIterator.next();
String entityName = element.attributeValue( "entity-name" );
if ( entityName == null ) {
entityName = getClassName( element.attribute( "name" ), defaultPackage );
}
names.add( entityName );
findClassNames( defaultPackage, element, names );
}
}
private String getClassName(Attribute name, String defaultPackage) {
if ( name == null ) {
return null;
}
String unqualifiedName = name.getValue();
if ( unqualifiedName == null ) {
return null;
}
if ( unqualifiedName.indexOf( '.' ) < 0 && defaultPackage != null ) {
return defaultPackage + '.' + unqualifiedName;
}
return unqualifiedName;
}
public void add(XClass annotatedClass) {
annotatedClasses.add( annotatedClass );
}
protected void syncAnnotatedClasses() {
final Iterator<XClass> itr = annotatedClasses.iterator();
while ( itr.hasNext() ) {
final XClass annotatedClass = itr.next();
if ( annotatedClass.isAnnotationPresent( Entity.class ) ) {
annotatedClassesByEntityNameMap.put( annotatedClass.getName(), annotatedClass );
continue;
}
if ( !annotatedClass.isAnnotationPresent( javax.persistence.MappedSuperclass.class ) ) {
itr.remove();
}
}
}
protected void processMetadata(List<MetadataSourceType> order) {
syncAnnotatedClasses();
for ( MetadataSourceType type : order ) {
if ( MetadataSourceType.HBM.equals( type ) ) {
processHbmXmlQueue();
}
else if ( MetadataSourceType.CLASS.equals( type ) ) {
processAnnotatedClassesQueue();
}
}
}
private void processHbmXmlQueue() {
log.debug( "Processing hbm.xml files" );
for ( Map.Entry<XmlDocument, Set<String>> entry : hbmMetadataToEntityNamesMap.entrySet() ) {
// Unfortunately we have to create a Mappings instance for each iteration here
processHbmXml( entry.getKey(), entry.getValue() );
}
hbmMetadataToEntityNamesMap.clear();
hbmMetadataByEntityNameXRef.clear();
}
public void processHbmXml(XmlDocument metadataXml, Set<String> entityNames) {
try {
metadata.getHibernateXmlBinder().bindRoot( metadataXml, entityNames );
}
catch ( MappingException me ) {
throw new InvalidMappingException(
metadataXml.getOrigin().getType(),
metadataXml.getOrigin().getName(),
me
);
}
for ( String entityName : entityNames ) {
if ( annotatedClassesByEntityNameMap.containsKey( entityName ) ) {
annotatedClasses.remove( annotatedClassesByEntityNameMap.get( entityName ) );
annotatedClassesByEntityNameMap.remove( entityName );
}
}
}
private void processAnnotatedClassesQueue() {
log.debug( "Process annotated classes" );
//bind classes in the correct order calculating some inheritance state
List<XClass> orderedClasses = orderAndFillHierarchy( annotatedClasses );
// Map<XClass, InheritanceState> inheritanceStatePerClass = AnnotationBinder.buildInheritanceStates(
// orderedClasses, mappings
// );
for ( XClass clazz : orderedClasses ) {
// todo : replace this with similar non-static code.
// AnnotationBinder.bindClass( clazz, inheritanceStatePerClass, mappings );
final String entityName = clazz.getName();
if ( hbmMetadataByEntityNameXRef.containsKey( entityName ) ) {
hbmMetadataToEntityNamesMap.remove( hbmMetadataByEntityNameXRef.get( entityName ) );
hbmMetadataByEntityNameXRef.remove( entityName );
}
}
annotatedClasses.clear();
annotatedClassesByEntityNameMap.clear();
}
private List<XClass> orderAndFillHierarchy(List<XClass> original) {
List<XClass> copy = new ArrayList<XClass>( original );
insertMappedSuperclasses( original, copy );
// order the hierarchy
List<XClass> workingCopy = new ArrayList<XClass>( copy );
List<XClass> newList = new ArrayList<XClass>( copy.size() );
while ( workingCopy.size() > 0 ) {
XClass clazz = workingCopy.get( 0 );
orderHierarchy( workingCopy, newList, copy, clazz );
}
return newList;
}
private void insertMappedSuperclasses(List<XClass> original, List<XClass> copy) {
for ( XClass clazz : original ) {
XClass superClass = clazz.getSuperclass();
while ( superClass != null
&& !metadata.getReflectionManager().equals( superClass, Object.class )
&& !copy.contains( superClass ) ) {
if ( superClass.isAnnotationPresent( Entity.class )
|| superClass.isAnnotationPresent( javax.persistence.MappedSuperclass.class ) ) {
copy.add( superClass );
}
superClass = superClass.getSuperclass();
}
}
}
private void orderHierarchy(List<XClass> copy, List<XClass> newList, List<XClass> original, XClass clazz) {
if ( clazz == null || metadata.getReflectionManager().equals( clazz, Object.class ) ) {
return;
}
//process superclass first
orderHierarchy( copy, newList, original, clazz.getSuperclass() );
if ( original.contains( clazz ) ) {
if ( !newList.contains( clazz ) ) {
newList.add( clazz );
}
copy.remove( clazz );
}
}
public boolean isEmpty() {
return hbmMetadataToEntityNamesMap.isEmpty() && annotatedClasses.isEmpty();
}
}

View File

@ -0,0 +1,864 @@
/*
* 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.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.EntityMode;
import org.hibernate.MappingException;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.engine.Versioning;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.MetaAttribute;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.BagBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.Hierarchical;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.PluralAttributeNature;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Index;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Table;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.Tuple;
import org.hibernate.metamodel.relational.UniqueKey;
import org.hibernate.metamodel.relational.Value;
import org.hibernate.metamodel.source.Metadata;
import org.hibernate.metamodel.source.util.DomHelper;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
abstract class AbstractEntityBinder {
private static final Logger log = LoggerFactory.getLogger( AbstractEntityBinder.class );
protected final HibernateMappingBinder hibernateMappingBinder;
protected final Map<String, MetaAttribute> entityMetas;
protected final Schema.Name schemaName;
AbstractEntityBinder(HibernateMappingBinder hibernateMappingBinder, Element entityElement) {
this.hibernateMappingBinder = hibernateMappingBinder;
entityMetas = HbmHelper.extractMetas( entityElement, true, hibernateMappingBinder.getMappingMetas() );
final Attribute schemaAttribute = entityElement.attribute( "schema" );
String schemaName = ( schemaAttribute == null )
? hibernateMappingBinder.getDefaultSchemaName()
: schemaAttribute.getValue();
final Attribute catalogAttribute = entityElement.attribute( "catalog" );
String catalogName = ( catalogAttribute == null )
? hibernateMappingBinder.getDefaultCatalogName()
: catalogAttribute.getValue();
this.schemaName = new Schema.Name( schemaName, catalogName );
}
protected HibernateXmlBinder getHibernateXmlBinder() {
return hibernateMappingBinder.getHibernateXmlBinder();
}
protected Metadata getMetadata() {
return hibernateMappingBinder.getHibernateXmlBinder().getMetadata();
}
protected NamingStrategy getNamingStrategy() {
return getMetadata().getNamingStrategy();
}
protected void basicEntityBinding(Element node, EntityBinding entityBinding, Hierarchical superType) {
entityBinding.setMetaAttributes( entityMetas );
// transfer an explicitly defined lazy attribute
Attribute lazyNode = node.attribute( "lazy" );
boolean lazy = ( lazyNode == null )
? hibernateMappingBinder.isDefaultLazy()
: Boolean.valueOf( lazyNode.getValue() );
// go ahead and set the lazy here, since pojo.proxy can override it.
entityBinding.setLazy( lazy );
String entityName = hibernateMappingBinder.extractEntityName( node );
if ( entityName == null ) {
throw new MappingException( "Unable to determine entity name" );
}
entityBinding.setEntity( new Entity( entityName, superType ) );
bindPojoRepresentation( node, entityBinding );
bindDom4jRepresentation( node, entityBinding );
bindMapRepresentation( node, entityBinding );
Iterator itr = node.elementIterator( "fetch-profile" );
while ( itr.hasNext() ) {
final Element profileElement = ( Element ) itr.next();
hibernateMappingBinder.parseFetchProfile( profileElement, entityName );
}
entityBinding.setDiscriminatorValue( DomHelper.extractAttributeValue( node, "discriminator-value", entityName ) );
entityBinding.setDynamicUpdate( DomHelper.extractBooleanAttributeValue( node, "dynamic-update", false ) );
entityBinding.setDynamicInsert( DomHelper.extractBooleanAttributeValue( node, "dynamic-insert", false ) );
getMetadata().addImport( entityName, entityName );
if ( hibernateMappingBinder.isAutoImport() ) {
if ( entityName.indexOf( '.' ) > 0 ) {
getMetadata().addImport( StringHelper.unqualify( entityName ), entityName );
}
}
final Attribute batchNode = node.attribute( "batch-size" );
if ( batchNode != null ) {
entityBinding.setBatchSize( Integer.parseInt( batchNode.getValue() ) );
}
final Attribute sbuNode = node.attribute( "select-before-update" );
if ( sbuNode != null ) {
entityBinding.setSelectBeforeUpdate( Boolean.valueOf( sbuNode.getValue() ) );
}
// OPTIMISTIC LOCK MODE
Attribute olNode = node.attribute( "optimistic-lock" );
entityBinding.setOptimisticLockMode( getOptimisticLockMode( olNode ) );
// PERSISTER
Attribute persisterNode = node.attribute( "persister" );
if ( persisterNode != null ) {
try {
entityBinding.setEntityPersisterClass(
ReflectHelper.classForName( persisterNode.getValue() )
);
}
catch (ClassNotFoundException cnfe) {
throw new MappingException( "Could not find persister class: "
+ persisterNode.getValue() );
}
}
// CUSTOM SQL
handleCustomSQL( node, entityBinding );
Iterator tables = node.elementIterator( "synchronize" );
while ( tables.hasNext() ) {
entityBinding.addSynchronizedTable( ( (Element) tables.next() ).attributeValue( "table" ) );
}
Attribute abstractNode = node.attribute( "abstract" );
Boolean isAbstract = abstractNode == null
? null
: "true".equals( abstractNode.getValue() )
? Boolean.TRUE
: "false".equals( abstractNode.getValue() )
? Boolean.FALSE
: null;
entityBinding.setAbstract( isAbstract );
}
private void bindPojoRepresentation(Element node, EntityBinding entityBinding) {
String className = hibernateMappingBinder.getClassName( node.attribute( "name" ) );
String proxyName = hibernateMappingBinder.getClassName( node.attribute( "proxy" ) );
entityBinding.getEntity().getPojoEntitySpecifics().setClassName( className );
if ( proxyName != null ) {
entityBinding.getEntity().getPojoEntitySpecifics().setProxyInterfaceName( proxyName );
entityBinding.setLazy( true );
}
else if ( entityBinding.isLazy() ) {
entityBinding.getEntity().getPojoEntitySpecifics().setProxyInterfaceName( className );
}
Element tuplizer = locateTuplizerDefinition( node, EntityMode.POJO );
if ( tuplizer != null ) {
entityBinding.getEntity().getPojoEntitySpecifics().setTuplizerClassName( tuplizer.attributeValue( "class" ) );
}
}
private void bindDom4jRepresentation(Element node, EntityBinding entityBinding) {
String nodeName = node.attributeValue( "node" );
if ( nodeName == null ) {
nodeName = StringHelper.unqualify( entityBinding.getEntity().getName() );
}
entityBinding.getEntity().getDom4jEntitySpecifics().setNodeName(nodeName);
Element tuplizer = locateTuplizerDefinition( node, EntityMode.DOM4J );
if ( tuplizer != null ) {
entityBinding.getEntity().getDom4jEntitySpecifics().setTuplizerClassName( tuplizer.attributeValue( "class" ) );
}
}
private void bindMapRepresentation(Element node, EntityBinding entityBinding) {
Element tuplizer = locateTuplizerDefinition( node, EntityMode.MAP );
if ( tuplizer != null ) {
entityBinding.getEntity().getMapEntitySpecifics().setTuplizerClassName( tuplizer.attributeValue( "class" ) );
}
}
/**
* Locate any explicit tuplizer definition in the metadata, for the given entity-mode.
*
* @param container The containing element (representing the entity/component)
* @param entityMode The entity-mode for which to locate the tuplizer element
*
* @return The tuplizer element, or null.
*/
private static Element locateTuplizerDefinition(Element container, EntityMode entityMode) {
Iterator itr = container.elementIterator( "tuplizer" );
while( itr.hasNext() ) {
final Element tuplizerElem = ( Element ) itr.next();
if ( entityMode.toString().equals( tuplizerElem.attributeValue( "entity-mode") ) ) {
return tuplizerElem;
}
}
return null;
}
int getOptimisticLockMode(Attribute olAtt) throws MappingException {
if ( olAtt == null ) {
return Versioning.OPTIMISTIC_LOCK_VERSION;
}
String olMode = olAtt.getValue();
if ( olMode == null || "version".equals( olMode ) ) {
return Versioning.OPTIMISTIC_LOCK_VERSION;
}
else if ( "dirty".equals( olMode ) ) {
return Versioning.OPTIMISTIC_LOCK_DIRTY;
}
else if ( "all".equals( olMode ) ) {
return Versioning.OPTIMISTIC_LOCK_ALL;
}
else if ( "none".equals( olMode ) ) {
return Versioning.OPTIMISTIC_LOCK_NONE;
}
else {
throw new MappingException( "Unsupported optimistic-lock style: " + olMode );
}
}
private static void handleCustomSQL(Element entityElement, EntityBinding entityBinding)
throws MappingException {
Element element = entityElement.element( "sql-insert" );
if ( element != null ) {
boolean callable = HbmHelper.isCallable( element );
entityBinding.setCustomSqlInsert( element.getTextTrim(), callable, HbmHelper.getResultCheckStyle( element, callable ) );
}
element = entityElement.element( "sql-delete" );
if ( element != null ) {
boolean callable = HbmHelper.isCallable( element );
entityBinding.setCustomSqlDelete( element.getTextTrim(), callable, HbmHelper.getResultCheckStyle( element, callable ) );
}
element = entityElement.element( "sql-update" );
if ( element != null ) {
boolean callable = HbmHelper.isCallable( element );
entityBinding.setCustomSqlUpdate( element.getTextTrim(), callable, HbmHelper.getResultCheckStyle( element, callable ) );
}
element = entityElement.element( "loader" );
if ( element != null ) {
entityBinding.setLoaderName( element.attributeValue( "query-ref" ) );
}
}
protected String getClassTableName(
Element entityElement,
EntityBinding entityBinding,
Table denormalizedSuperTable) {
final String entityName = entityBinding.getEntity().getName();
final Attribute tableNameNode = entityElement.attribute( "table" );
String logicalTableName;
String physicalTableName;
if ( tableNameNode == null ) {
logicalTableName = StringHelper.unqualify( entityName );
physicalTableName = getHibernateXmlBinder().getMetadata().getNamingStrategy().classToTableName( entityName );
}
else {
logicalTableName = tableNameNode.getValue();
physicalTableName = getHibernateXmlBinder().getMetadata().getNamingStrategy().tableName( logicalTableName );
}
// todo : find out the purpose of these logical bindings
// mappings.addTableBinding( schema, catalog, logicalTableName, physicalTableName, denormalizedSuperTable );
return physicalTableName;
}
protected void buildAttributeBindings(Element entityElement, EntityBinding entityBinding) {
// null = UniqueKey (we are not binding a natural-id mapping)
// true = mutable, by default properties are mutable
// true = nullable, by default properties are nullable.
buildAttributeBindings( entityElement, entityBinding, null, true, true );
}
/**
* This form is essentially used to create natural-id mappings. But the processing is the same, aside from these
* extra parameterized values, so we encapsulate it here.
*
* @param entityElement
* @param entityBinding
* @param uniqueKey
* @param mutable
* @param nullable
*/
protected void buildAttributeBindings(
Element entityElement,
EntityBinding entityBinding,
UniqueKey uniqueKey,
boolean mutable,
boolean nullable) {
final boolean naturalId = uniqueKey != null;
final String entiytName = entityBinding.getEntity().getName();
final TableSpecification tabe = entityBinding.getBaseTable();
AttributeBinding attributeBinding = null;
Iterator iter = entityElement.elementIterator();
while ( iter.hasNext() ) {
final Element subElement = (Element) iter.next();
final String subElementName = subElement.getName();
final String propertyName = subElement.attributeValue( "name" );
if ( "bag".equals( subElementName ) ) {
BagBinding bagBinding = entityBinding.makeBagAttributeBinding( propertyName );
bindCollection( subElement, bagBinding, entityBinding, PluralAttributeNature.BAG, propertyName );
hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( bagBinding );
attributeBinding = bagBinding;
}
else if ( "idbag".equals( subElementName ) ) {
BagBinding bagBinding = entityBinding.makeBagAttributeBinding( propertyName );
bindCollection( subElement, bagBinding, entityBinding, PluralAttributeNature.BAG, propertyName );
hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( bagBinding );
attributeBinding = bagBinding;
// todo: handle identifier
}
else if ( "set".equals( subElementName ) ) {
BagBinding bagBinding = entityBinding.makeBagAttributeBinding( propertyName );
bindCollection( subElement, bagBinding, entityBinding, PluralAttributeNature.SET, propertyName );
hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( bagBinding );
attributeBinding = bagBinding;
}
else if ( "list".equals( subElementName ) ) {
BagBinding bagBinding = entityBinding.makeBagAttributeBinding( propertyName );
bindCollection( subElement, bagBinding, entityBinding, PluralAttributeNature.LIST, propertyName );
hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( bagBinding );
attributeBinding = bagBinding;
// todo : handle list index
}
else if ( "map".equals( subElementName ) ) {
BagBinding bagBinding = entityBinding.makeBagAttributeBinding( propertyName );
bindCollection( subElement, bagBinding, entityBinding, PluralAttributeNature.MAP, propertyName );
hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( bagBinding );
attributeBinding = bagBinding;
// todo : handle map key
}
else if ( "many-to-one".equals( subElementName ) ) {
// todo : implement
// value = new ManyToOne( mappings, table );
// bindManyToOne( subElement, (ManyToOne) value, propertyName, nullable, mappings );
}
else if ( "any".equals( subElementName ) ) {
// todo : implement
// value = new Any( mappings, table );
// bindAny( subElement, (Any) value, nullable, mappings );
}
else if ( "one-to-one".equals( subElementName ) ) {
// todo : implement
// value = new OneToOne( mappings, table, persistentClass );
// bindOneToOne( subElement, (OneToOne) value, propertyName, true, mappings );
}
else if ( "property".equals( subElementName ) ) {
SimpleAttributeBinding binding = entityBinding.makeSimpleAttributeBinding( propertyName );
bindSimpleAttribute( subElement, binding, entityBinding, propertyName );
attributeBinding = binding;
}
else if ( "component".equals( subElementName )
|| "dynamic-component".equals( subElementName )
|| "properties".equals( subElementName ) ) {
// todo : implement
// String subpath = StringHelper.qualify( entityName, propertyName );
// value = new Component( mappings, persistentClass );
//
// bindComponent(
// subElement,
// (Component) value,
// persistentClass.getClassName(),
// propertyName,
// subpath,
// true,
// "properties".equals( subElementName ),
// mappings,
// inheritedMetas,
// false
// );
}
else if ( "join".equals( subElementName ) ) {
// todo : implement
// Join join = new Join();
// join.setPersistentClass( persistentClass );
// bindJoin( subElement, join, mappings, inheritedMetas );
// persistentClass.addJoin( join );
}
else if ( "subclass".equals( subElementName ) ) {
// todo : implement
// handleSubclass( persistentClass, mappings, subElement, inheritedMetas );
}
else if ( "joined-subclass".equals( subElementName ) ) {
// todo : implement
// handleJoinedSubclass( persistentClass, mappings, subElement, inheritedMetas );
}
else if ( "union-subclass".equals( subElementName ) ) {
// todo : implement
// handleUnionSubclass( persistentClass, mappings, subElement, inheritedMetas );
}
else if ( "filter".equals( subElementName ) ) {
// todo : implement
// parseFilter( subElement, entityBinding );
}
else if ( "natural-id".equals( subElementName ) ) {
// todo : implement
// UniqueKey uk = new UniqueKey();
// uk.setName("_UniqueKey");
// uk.setTable(table);
// //by default, natural-ids are "immutable" (constant)
// boolean mutableId = "true".equals( subElement.attributeValue("mutable") );
// createClassProperties(
// subElement,
// persistentClass,
// mappings,
// inheritedMetas,
// uk,
// mutableId,
// false,
// true
// );
// table.addUniqueKey(uk);
}
else if ( "query".equals(subElementName) ) {
// todo : implement
// bindNamedQuery(subElement, persistentClass.getEntityName(), mappings);
}
else if ( "sql-query".equals(subElementName) ) {
// todo : implement
// bindNamedSQLQuery(subElement, persistentClass.getEntityName(), mappings);
}
else if ( "resultset".equals(subElementName) ) {
// todo : implement
// bindResultSetMappingDefinition( subElement, persistentClass.getEntityName(), mappings );
}
// if ( value != null ) {
// Property property = createProperty( value, propertyName, persistentClass
// .getClassName(), subElement, mappings, inheritedMetas );
// if ( !mutable ) property.setUpdateable(false);
// if ( naturalId ) property.setNaturalIdentifier(true);
// persistentClass.addProperty( property );
// if ( uniqueKey!=null ) uniqueKey.addColumns( property.getColumnIterator() );
// }
}
}
protected void bindSimpleAttribute(Element propertyElement, SimpleAttributeBinding attributeBinding, EntityBinding entityBinding, String attributeName) {
if ( attributeBinding.getAttribute() == null ) {
// attribute has not been bound yet
SingularAttribute attribute = entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
attributeBinding.setAttribute( attribute );
basicAttributeBinding( propertyElement, attributeBinding );
}
if ( attributeBinding.getValue() == null ) {
// relational model has not been bound yet
Value idValue = processValues( propertyElement, entityBinding.getBaseTable(), attributeName );
attributeBinding.setValue( idValue );
}
}
protected void bindCollection(
Element collectionElement,
PluralAttributeBinding collectionBinding,
EntityBinding entityBinding,
PluralAttributeNature attributeNature,
String attributeName) {
if ( collectionBinding.getAttribute() == null ) {
// domain model has not been bound yet
PluralAttribute attribute = entityBinding.getEntity().getOrCreatePluralAttribute( attributeName, attributeNature );
collectionBinding.setAttribute( attribute );
basicCollectionBinding( collectionElement, collectionBinding );
}
// todo : relational model binding
}
protected void basicCollectionBinding(Element collectionElement, PluralAttributeBinding collectionBinding) {
// todo : implement
}
// private static Property createProperty(
// final Value value,
// final String propertyName,
// final String className,
// final Element subnode,
// final Mappings mappings,
// java.util.Map inheritedMetas) throws MappingException {
//
// if ( StringHelper.isEmpty( propertyName ) ) {
// throw new MappingException( subnode.getName() + " mapping must defined a name attribute [" + className + "]" );
// }
//
// value.setTypeUsingReflection( className, propertyName );
//
// // this is done here 'cos we might only know the type here (ugly!)
// // TODO: improve this a lot:
// if ( value instanceof ToOne ) {
// ToOne toOne = (ToOne) value;
// String propertyRef = toOne.getReferencedPropertyName();
// if ( propertyRef != null ) {
// mappings.addUniquePropertyReference( toOne.getReferencedEntityName(), propertyRef );
// }
// }
// else if ( value instanceof Collection ) {
// Collection coll = (Collection) value;
// String propertyRef = coll.getReferencedPropertyName();
// // not necessarily a *unique* property reference
// if ( propertyRef != null ) {
// mappings.addPropertyReference( coll.getOwnerEntityName(), propertyRef );
// }
// }
//
// value.createForeignKey();
// Property prop = new Property();
// prop.setValue( value );
// bindProperty( subnode, prop, mappings, inheritedMetas );
// return prop;
// }
protected Value processValues(Element identifierElement, TableSpecification baseTable, String propertyPath) {
// first boolean (false here) indicates that by default columns are nullable
// second boolean (true here) indicates that by default column names should be guessed
return processValues( identifierElement, baseTable, false, true, propertyPath );
}
protected Value processValues(
Element propertyElement,
TableSpecification table,
boolean isNullableByDefault,
boolean autoColumnCreation,
String propertyPath) {
final UniqueKeyBinder propertyUniqueKeyBinder = new UniqueKeyBinder( propertyElement.attribute( "unique-key" ), table );
final IndexBinder propertyIndexBinder = new IndexBinder( propertyElement.attribute( "index" ), table );
final Attribute columnAttribute = propertyElement.attribute( "column" );
if ( columnAttribute == null ) {
SimpleValue value = null;
Tuple tuple = null;
final Iterator valueElements = propertyElement.elementIterator();
while ( valueElements.hasNext() ) {
if ( value != null ) {
if ( tuple == null ) {
tuple = table.createTuple( "[" + propertyPath + "]" );
}
tuple.addValue( value );
}
final Element valueElement = (Element) valueElements.next();
if ( "column".equals( valueElement.getName() ) ) {
final Element columnElement = valueElement;
final String explicitName = columnElement.attributeValue( "name" );
final String logicalColumnName = getNamingStrategy().logicalColumnName( explicitName, propertyPath );
final String columnName = getNamingStrategy().columnName( explicitName );
// todo : find out the purpose of these logical bindings
// mappings.addColumnBinding( logicalColumnName, column, table );
Column column = table.createColumn( columnName );
value = column;
basicColumnBinding( columnElement, column, isNullableByDefault );
propertyUniqueKeyBinder.bindColumn( column );
propertyIndexBinder.bindColumn( column );
new UniqueKeyBinder( columnElement.attribute( "unique-key" ), table ).bindColumn( column );
new IndexBinder( columnElement.attribute( "index" ), table ).bindColumn( column );
}
else if ( "formula".equals( valueElement.getName() ) ) {
value = table.createDerivedValue( valueElement.getTextTrim() );
}
}
// todo : logical 1-1 handling
// final Attribute uniqueAttribute = node.attribute( "unique" );
// if ( uniqueAttribute != null
// && "true".equals( uniqueAttribute.getValue() )
// && ManyToOne.class.isInstance( simpleValue ) ) {
// ( (ManyToOne) simpleValue ).markAsLogicalOneToOne();
// }
if ( tuple != null ) {
return tuple;
}
else if ( value != null ) {
return value;
}
else if ( autoColumnCreation ) {
final String columnName = getNamingStrategy().propertyToColumnName( propertyPath );
final String logicalColumnName = getNamingStrategy().logicalColumnName( null, propertyPath );
// todo : find out the purpose of these logical bindings
// mappings.addColumnBinding( logicalColumnName, column, table );
Column column = table.createColumn( columnName );
basicColumnBinding( propertyElement, column, isNullableByDefault );
propertyUniqueKeyBinder.bindColumn( column );
propertyIndexBinder.bindColumn( column );
return column;
}
}
if ( propertyElement.elementIterator( "column" ).hasNext() ) {
throw new MappingException( "column attribute may not be used together with <column> subelement" );
}
if ( propertyElement.elementIterator( "formula" ).hasNext() ) {
throw new MappingException( "column attribute may not be used together with <formula> subelement" );
}
final String explicitName = columnAttribute.getValue();
final String logicalColumnName = getNamingStrategy().logicalColumnName( explicitName, propertyPath );
final String columnName = getNamingStrategy().columnName( explicitName );
// todo : find out the purpose of these logical bindings
// mappings.addColumnBinding( logicalColumnName, column, table );
Column column = table.createColumn( columnName );
basicColumnBinding( propertyElement, column, isNullableByDefault );
propertyUniqueKeyBinder.bindColumn( column );
propertyIndexBinder.bindColumn( column );
return column;
}
protected static class UniqueKeyBinder {
private final List<UniqueKey> uniqueKeys;
UniqueKeyBinder(Attribute uniqueKeyAttribute, TableSpecification table) {
if ( uniqueKeyAttribute == null ) {
uniqueKeys = Collections.emptyList();
}
else {
uniqueKeys = new ArrayList<UniqueKey>();
StringTokenizer uniqueKeyNames = new StringTokenizer( uniqueKeyAttribute.getValue(), ", " );
while ( uniqueKeyNames.hasMoreTokens() ) {
uniqueKeys.add( table.getOrCreateUniqueKey( uniqueKeyNames.nextToken() ) );
}
}
}
void bindColumn(Column column) {
for ( UniqueKey uniqueKey : uniqueKeys ) {
uniqueKey.addColumn( column );
}
}
}
protected static class IndexBinder {
private final List<Index> indexes;
IndexBinder(Attribute indexAttribute, TableSpecification table) {
if ( indexAttribute == null ) {
indexes = Collections.emptyList();
}
else {
indexes = new ArrayList<Index>();
StringTokenizer indexNames = new StringTokenizer( indexAttribute.getValue(), ", " );
while ( indexNames.hasMoreTokens() ) {
indexes.add( table.getOrCreateIndex( indexNames.nextToken() ) );
}
}
}
void bindColumn(Column column) {
for ( Index index : indexes ) {
index.addColumn( column );
}
}
}
public static void basicColumnBinding(Element node, Column column, boolean isNullable) throws MappingException {
Attribute lengthNode = node.attribute( "length" );
if ( lengthNode != null ) {
column.getSize().setLength( Integer.parseInt( lengthNode.getValue() ) );
}
Attribute scalNode = node.attribute( "scale" );
if ( scalNode != null ) {
column.getSize().setScale( Integer.parseInt( scalNode.getValue() ) );
}
Attribute precNode = node.attribute( "precision" );
if ( precNode != null ) {
column.getSize().setPrecision( Integer.parseInt( precNode.getValue() ) );
}
Attribute nullNode = node.attribute( "not-null" );
column.setNullable( nullNode == null ? isNullable : nullNode.getValue().equals( "false" ) );
Attribute unqNode = node.attribute( "unique" );
if ( unqNode != null ) {
column.setUnique( unqNode.getValue().equals( "true" ) );
}
column.setCheckCondition( node.attributeValue( "check" ) );
column.setDefaultValue( node.attributeValue( "default" ) );
Attribute typeNode = node.attribute( "sql-type" );
if ( typeNode != null ) column.setSqlType( typeNode.getValue() );
String customWrite = node.attributeValue( "write" );
if(customWrite != null && !customWrite.matches("[^?]*\\?[^?]*")) {
throw new MappingException("write expression must contain exactly one value placeholder ('?') character");
}
column.setWriteFragment( customWrite );
column.setReadFragment( node.attributeValue( "read" ) );
Element comment = node.element("comment");
if ( comment != null ) {
column.setComment( comment.getTextTrim() );
}
}
protected void basicAttributeBinding(Element propertyElement, SimpleAttributeBinding valueBinding) {
Attribute typeAttribute = propertyElement.attribute( "type" );
if ( typeAttribute != null ) {
valueBinding.getHibernateTypeDescriptor().setTypeName( typeAttribute.getValue() );
}
valueBinding.setMetaAttributes( HbmHelper.extractMetas( propertyElement, entityMetas ) );
final String propertyName = valueBinding.getAttribute().getName();
final String explicitNodename = propertyElement.attributeValue( "node" );
final String nodeName = explicitNodename != null ? explicitNodename : propertyName;
valueBinding.setNodeName( nodeName );
final Attribute accessNode = propertyElement.attribute( "access" );
if ( accessNode != null ) {
valueBinding.setPropertyAccessorName( accessNode.getValue() );
}
else if ( propertyElement.getName().equals( "properties" ) ) {
valueBinding.setPropertyAccessorName( "embedded" );
}
else {
valueBinding.setPropertyAccessorName( hibernateMappingBinder.getDefaultAccess() );
}
final String explicitCascade = propertyElement.attributeValue( "cascade" );
final String cascade = StringHelper.isNotEmpty( explicitCascade ) ? explicitCascade : hibernateMappingBinder.getDefaultCascade();
valueBinding.setCascade( cascade );
final Attribute updateAttribute = propertyElement.attribute( "update" );
valueBinding.setUpdateable( updateAttribute == null || "true".equals( updateAttribute.getValue() ) );
final Attribute insertAttribute = propertyElement.attribute( "insert" );
valueBinding.setInsertable( insertAttribute == null || "true".equals( insertAttribute.getValue() ) );
final Attribute optimisticLockAttribute = propertyElement.attribute( "optimistic-lock" );
valueBinding.setOptimisticLockable( optimisticLockAttribute == null || "true".equals( optimisticLockAttribute.getValue() ) );
final Attribute generatedAttribute= propertyElement.attribute( "generated" );
final String generationName = generatedAttribute == null ? null : generatedAttribute.getValue();
final PropertyGeneration generation = PropertyGeneration.parse( generationName );
valueBinding.setGeneration( generation );
if ( generation == PropertyGeneration.ALWAYS || generation == PropertyGeneration.INSERT ) {
// generated properties can *never* be insertable...
if ( valueBinding.isInsertable() ) {
if ( insertAttribute == null ) {
// insertable simply because the user did not specify anything; just override it
valueBinding.setInsertable( false );
}
else {
// the user specifically supplied insert="true", which constitutes an illegal combo
throw new MappingException(
"cannot specify both insert=\"true\" and generated=\"" + generation.getName() +
"\" for property: " +
propertyName
);
}
}
// properties generated on update can never be updateable...
if ( valueBinding.isUpdateable() && generation == PropertyGeneration.ALWAYS ) {
if ( updateAttribute == null ) {
// updateable only because the user did not specify
// anything; just override it
valueBinding.setUpdateable( false );
}
else {
// the user specifically supplied update="true",
// which constitutes an illegal combo
throw new MappingException(
"cannot specify both update=\"true\" and generated=\"" + generation.getName() +
"\" for property: " +
propertyName
);
}
}
}
boolean isLazyable = "property".equals( propertyElement.getName() )
|| "component".equals( propertyElement.getName() )
|| "many-to-one".equals( propertyElement.getName() )
|| "one-to-one".equals( propertyElement.getName() )
|| "any".equals( propertyElement.getName() );
if ( isLazyable ) {
Attribute lazyNode = propertyElement.attribute( "lazy" );
valueBinding.setLazy( lazyNode != null && "true".equals( lazyNode.getValue() ) );
}
}
}

View File

@ -0,0 +1,127 @@
/*
* 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.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.hibernate.MappingException;
import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
import org.hibernate.mapping.MetaAttribute;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class HbmHelper {
public static boolean isCallable(Element e) {
return isCallable( e, true );
}
public static boolean isCallable(Element element, boolean supportsCallable) {
Attribute attrib = element.attribute( "callable" );
if ( attrib != null && "true".equals( attrib.getValue() ) ) {
if ( !supportsCallable ) {
throw new MappingException( "callable attribute not supported yet!" );
}
return true;
}
return false;
}
public static ExecuteUpdateResultCheckStyle getResultCheckStyle(Element element, boolean callable) {
Attribute attr = element.attribute( "check" );
if ( attr == null ) {
// use COUNT as the default. This mimics the old behavior, although
// NONE might be a better option moving forward in the case of callable
return ExecuteUpdateResultCheckStyle.COUNT;
}
return ExecuteUpdateResultCheckStyle.parse( attr.getValue() );
}
public static final Map<String, MetaAttribute> extractMetas(Element node, Map<String, MetaAttribute> baseline) {
return extractMetas( node, false, baseline );
}
public static final Map<String, MetaAttribute> extractMetas(Element node, boolean onlyInheritable, Map<String, MetaAttribute> baseline) {
Map<String, MetaAttribute> extractedMetas = new HashMap<String, MetaAttribute>();
extractedMetas.putAll( baseline );
Iterator iter = node.elementIterator( "meta" );
while ( iter.hasNext() ) {
Element metaNode = (Element) iter.next();
boolean inheritable = Boolean.valueOf( metaNode.attributeValue( "inherit" ) ).booleanValue();
if ( onlyInheritable & !inheritable ) {
continue;
}
final String name = metaNode.attributeValue( "attribute" );
final MetaAttribute inheritedMetaAttribute = (MetaAttribute) baseline.get( name );
MetaAttribute metaAttribute = (MetaAttribute) extractedMetas.get( name );
if ( metaAttribute == null || metaAttribute == inheritedMetaAttribute ) {
metaAttribute = new MetaAttribute( name );
extractedMetas.put( name, metaAttribute );
}
metaAttribute.addValue( metaNode.getText() );
}
return extractedMetas;
}
public static String getSubselect(Element element) {
String subselect = element.attributeValue( "subselect" );
if ( subselect != null ) {
return subselect;
}
else {
Element subselectElement = element.element( "subselect" );
return subselectElement == null ? null : subselectElement.getText();
}
}
public static String extractEntityName(Element elem, String unqualifiedPackageName) {
String entityName = elem.attributeValue( "entity-name" );
return entityName == null ? getClassName( elem.attribute( "name" ), unqualifiedPackageName ) : entityName;
}
public static String getClassName(Attribute att, String unqualifiedPackageName) {
if ( att == null ) return null;
return getClassName( att.getValue(), unqualifiedPackageName );
}
public static String getClassName(String unqualifiedName, String unqualifiedPackageName) {
if ( unqualifiedName == null ) {
return null;
}
if ( unqualifiedName.indexOf( '.' ) < 0 && unqualifiedPackageName != null ) {
return unqualifiedPackageName + '.' + unqualifiedName;
}
return unqualifiedName;
}
}

View File

@ -0,0 +1,203 @@
/*
* 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.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.hibernate.MappingException;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.xml.XmlDocument;
import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.MetaAttribute;
import org.hibernate.mapping.MetadataSource;
import org.hibernate.metamodel.source.util.DomHelper;
/**
* Responsible for performing binding of the {@code <hibernate-mapping/>} DOM element
*/
class HibernateMappingBinder {
private final HibernateXmlBinder hibernateXmlBinder;
private final XmlDocument xmlDocument;
private final Element hibernateMappingElement;
private final String defaultSchemaName;
private final String defaultCatalogName;
private final String defaultCascade;
private final String defaultAccess;
private final boolean defaultLazy;
private final String packageName;
private final boolean autoImport;
private Map<String, MetaAttribute> mappingMetas;
HibernateMappingBinder(HibernateXmlBinder hibernateXmlBinder, XmlDocument xmlDocument) {
this.hibernateXmlBinder = hibernateXmlBinder;
this.xmlDocument = xmlDocument;
this.hibernateMappingElement = xmlDocument.getDocumentTree().getRootElement();
defaultSchemaName = DomHelper.extractAttributeValue( hibernateMappingElement, "schema" );
defaultCatalogName = DomHelper.extractAttributeValue( hibernateMappingElement, "catalog" );
defaultCascade = DomHelper.extractAttributeValue( hibernateMappingElement, "default-cascade", "none" );
defaultAccess = DomHelper.extractAttributeValue( hibernateMappingElement, "default-access", "property" );
defaultLazy = "true".equals( DomHelper.extractAttributeValue( hibernateMappingElement, "default-lazy", "false" ) );
packageName = DomHelper.extractAttributeValue( hibernateMappingElement, "package" );
autoImport = "true".equals( DomHelper.extractAttributeValue( hibernateMappingElement, "auto-import", "false" ) );
mappingMetas = HbmHelper.extractMetas( hibernateMappingElement, true, hibernateXmlBinder.getGlobalMetas() );
}
HibernateXmlBinder getHibernateXmlBinder() {
return hibernateXmlBinder;
}
XmlDocument getXmlDocument() {
return xmlDocument;
}
String getDefaultSchemaName() {
return defaultSchemaName;
}
String getDefaultCatalogName() {
return defaultCatalogName;
}
String getDefaultCascade() {
return defaultCascade;
}
String getDefaultAccess() {
return defaultAccess;
}
boolean isDefaultLazy() {
return defaultLazy;
}
String getPackageName() {
return packageName;
}
boolean isAutoImport() {
return autoImport;
}
Map<String, MetaAttribute> getMappingMetas() {
return mappingMetas;
}
void processElement() {
Iterator rootChildren = hibernateMappingElement.elementIterator();
while ( rootChildren.hasNext() ) {
final Element element = (Element) rootChildren.next();
final String elementName = element.getName();
if ( "filter-def".equals( elementName ) ) {
// parseFilterDef( element, mappings );
}
else if ( "fetch-profile".equals( elementName ) ) {
parseFetchProfile( element, null );
}
else if ( "identifier-generator".equals( elementName ) ) {
// parseIdentifierGeneratorRegistration( element, mappings );
}
else if ( "typedef".equals( elementName ) ) {
// bindTypeDef( element, mappings );
}
else if ( "class".equals( elementName ) ) {
new RootEntityBinder( this, element ).process( element );
}
else if ( "subclass".equals( elementName ) ) {
// PersistentClass superModel = getSuperclass( mappings, element );
// handleSubclass( superModel, mappings, element, inheritedMetas );
}
else if ( "joined-subclass".equals( elementName ) ) {
// PersistentClass superModel = getSuperclass( mappings, element );
// handleJoinedSubclass( superModel, mappings, element, inheritedMetas );
}
else if ( "union-subclass".equals( elementName ) ) {
// PersistentClass superModel = getSuperclass( mappings, element );
// handleUnionSubclass( superModel, mappings, element, inheritedMetas );
}
else if ( "query".equals( elementName ) ) {
// bindNamedQuery( element, null, mappings );
}
else if ( "sql-query".equals( elementName ) ) {
// bindNamedSQLQuery( element, null, mappings );
}
else if ( "resultset".equals( elementName ) ) {
// bindResultSetMappingDefinition( element, null, mappings );
}
else if ( "import".equals( elementName ) ) {
processImport( element );
}
else if ( "database-object".equals( elementName ) ) {
// bindAuxiliaryDatabaseObject( element, mappings );
}
}
}
private void processImport(Element importNode) {
String className = getClassName( importNode.attribute( "class" ) );
Attribute renameNode = importNode.attribute( "rename" );
String rename = ( renameNode == null ) ? StringHelper.unqualify( className ) : renameNode.getValue();
hibernateXmlBinder.getMetadata().addImport( className, rename );
}
protected void parseFetchProfile(Element element, String containingEntityName) {
String profileName = element.attributeValue( "name" );
FetchProfile profile = hibernateXmlBinder.getMetadata().findOrCreateFetchProfile( profileName, MetadataSource.HBM );
Iterator itr = element.elementIterator( "fetch" );
while ( itr.hasNext() ) {
final Element fetchElement = ( Element ) itr.next();
final String association = fetchElement.attributeValue( "association" );
final String style = fetchElement.attributeValue( "style" );
String entityName = fetchElement.attributeValue( "entity" );
if ( entityName == null ) {
entityName = containingEntityName;
}
if ( entityName == null ) {
throw new MappingException( "could not determine entity for fetch-profile fetch [" + profileName + "]:[" + association + "]" );
}
profile.addFetch( entityName, association, style );
}
}
String extractEntityName(Element element) {
return HbmHelper.extractEntityName( element, packageName );
}
String getClassName(Attribute attribute) {
return HbmHelper.getClassName( attribute, packageName );
}
String getClassName(String unqualifiedName) {
return HbmHelper.getClassName( unqualifiedName, packageName );
}
}

View File

@ -0,0 +1,172 @@
/*
* 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.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dom4j.Element;
import org.hibernate.cfg.ExtendsQueueEntry;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.JoinedIterator;
import org.hibernate.internal.util.xml.XmlDocument;
import org.hibernate.mapping.MetaAttribute;
import org.hibernate.metamodel.source.Metadata;
/**
* Binder for {@code hbm.xml} files
*
* @author Steve Ebersole
*/
public class HibernateXmlBinder {
private final Metadata metadata;
private final Map<String, MetaAttribute> globalMetas;
public HibernateXmlBinder(Metadata metadata) {
this( metadata, Collections.<String, MetaAttribute>emptyMap() );
}
public HibernateXmlBinder(Metadata metadata, Map<String, MetaAttribute> globalMetas) {
this.metadata = metadata;
this.globalMetas = globalMetas;
}
public void bindRoot(XmlDocument metadataXml) {
bindRoot( metadataXml, Collections.<String>emptySet() );
}
public void bindRoot(XmlDocument metadataXml, Set<String> entityNames) {
final HibernateMappingBinder mappingBinder = new HibernateMappingBinder( this, metadataXml );
List<String> names = locateEntityNamesAwaitingExtends( metadataXml, mappingBinder );
if ( !names.isEmpty() ) {
// classes mentioned in extends not available - so put it in queue
for ( String name : names ) {
metadata.getExtendsQueue().add( new ExtendsQueueEntry( name, mappingBinder.getPackageName(), metadataXml, entityNames ) );
}
return;
}
mappingBinder.processElement();
}
Metadata getMetadata() {
return metadata;
}
Map<String, MetaAttribute> getGlobalMetas() {
return globalMetas;
}
private List<String> locateEntityNamesAwaitingExtends(XmlDocument metadataXml, HibernateMappingBinder mappingBinder) {
final String unqualifiedPackageName = mappingBinder.getPackageName();
final Element rootElement = metadataXml.getDocumentTree().getRootElement();
List<String> awaitingExtends = new ArrayList<String>();
// first, iterate over all elements capable of defining an extends attribute
// collecting all found extends references if they cannot be resolved
// against the already processed mappings.
Iterator[] subclasses = new Iterator[3];
subclasses[0] = rootElement.elementIterator( "subclass" );
subclasses[1] = rootElement.elementIterator( "joined-subclass" );
subclasses[2] = rootElement.elementIterator( "union-subclass" );
Iterator iterator = new JoinedIterator( subclasses );
while ( iterator.hasNext() ) {
final Element element = (Element) iterator.next();
final String extendsName = element.attributeValue( "extends" );
// mappings might contain either the "raw" extends name (in the case of
// an entity-name mapping) or a FQN (in the case of a POJO mapping).
if ( getMetadata().getEntityBinding( extendsName ) == null
&& getMetadata().getEntityBinding( HbmHelper.getClassName( extendsName, unqualifiedPackageName ) ) == null ) {
awaitingExtends.add( extendsName );
}
}
if ( !awaitingExtends.isEmpty() ) {
// So far, the 'awaitingExtends' list containg all entity names found as extends in this
// current document which were not previously processed in earlier documents.
//
// Now we will go through and remove the ones that are contained in this document
final java.util.Set<String> set = new HashSet<String>( awaitingExtends );
EntityElementHandler handler = new EntityElementHandler() {
public void handleEntity(String entityName, String className) {
if ( entityName != null ) {
set.remove( entityName );
}
else {
String fqn = HbmHelper.getClassName( className, unqualifiedPackageName );
set.remove( fqn );
if ( unqualifiedPackageName != null ) {
set.remove( StringHelper.unqualify( fqn ) );
}
}
}
};
recognizeEntities( rootElement, handler );
awaitingExtends.clear();
awaitingExtends.addAll( set );
}
return awaitingExtends;
}
/**
* Given an entity-containing-element (startNode) recursively locate all
* entity names defined within that element.
*
* @param startNode The containing element
* @param handler The thing that knows what to do whenever we recognize an
* entity-name
*/
private static void recognizeEntities(final Element startNode, EntityElementHandler handler) {
Iterator[] classes = new Iterator[4];
classes[0] = startNode.elementIterator( "class" );
classes[1] = startNode.elementIterator( "subclass" );
classes[2] = startNode.elementIterator( "joined-subclass" );
classes[3] = startNode.elementIterator( "union-subclass" );
Iterator classIterator = new JoinedIterator( classes );
while ( classIterator.hasNext() ) {
Element element = (Element) classIterator.next();
handler.handleEntity(
element.attributeValue( "entity-name" ),
element.attributeValue( "name" )
);
recognizeEntities( element, handler );
}
}
private static interface EntityElementHandler {
public void handleEntity(String entityName, String className);
}
}

View File

@ -0,0 +1,337 @@
/*
* 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 org.dom4j.Attribute;
import org.dom4j.Element;
import org.hibernate.InvalidMappingException;
import org.hibernate.MappingException;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.mapping.RootClass;
import org.hibernate.metamodel.binding.Caching;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Identifier;
import org.hibernate.metamodel.relational.InLineView;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.Tuple;
import org.hibernate.metamodel.relational.Value;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
class RootEntityBinder extends AbstractEntityBinder {
RootEntityBinder(HibernateMappingBinder hibernateMappingBinder, Element entityElement) {
super( hibernateMappingBinder, entityElement );
}
public void process(Element entityElement) {
EntityBinding entityBinding = new EntityBinding();
basicEntityBinding( entityElement, entityBinding, null );
basicTableBinding( entityElement, entityBinding );
Attribute mutableAttribute = entityElement.attribute( "mutable" );
if ( mutableAttribute != null ) {
entityBinding.setMutable( Boolean.valueOf( mutableAttribute.getValue() ) );
}
Attribute whereAttribute = entityElement.attribute( "where" );
if ( whereAttribute != null ) {
entityBinding.setWhereFilter( whereAttribute.getValue() );
}
Attribute polymorphismAttribute = entityElement.attribute( "polymorphism" );
if ( polymorphismAttribute != null ) {
entityBinding.setExplicitPolymorphism( "explicit".equals( polymorphismAttribute.getValue() ) );
}
Attribute rowidAttribute = entityElement.attribute( "rowid" );
if ( rowidAttribute != null ) {
entityBinding.setRowId( rowidAttribute.getValue() );
}
bindIdentifier( entityElement, entityBinding );
bindDiscriminator( entityElement, entityBinding );
bindVersion( entityElement, entityBinding );
bindCaching( entityElement, entityBinding );
// called createClassProperties in HBMBinder...
buildAttributeBindings( entityElement, entityBinding );
getHibernateXmlBinder().getMetadata().addEntity( entityBinding );
}
private void basicTableBinding(Element entityElement, EntityBinding entityBinding) {
final Schema schema = getHibernateXmlBinder().getMetadata().getDatabase().getSchema( schemaName );
final String subSelect = HbmHelper.getSubselect( entityElement );
if ( subSelect != null ) {
final String logicalName = entityBinding.getEntity().getName();
InLineView inLineView = schema.getInLineView( logicalName );
if ( inLineView == null ) {
inLineView = schema.createInLineView( logicalName, subSelect );
}
entityBinding.setBaseTable( inLineView );
}
else {
final Identifier tableName = Identifier.toIdentifier( getClassTableName( entityElement, entityBinding, null ) );
org.hibernate.metamodel.relational.Table table = schema.getTable( tableName );
if ( table == null ) {
table = schema.createTable( tableName );
}
entityBinding.setBaseTable( table );
Element comment = entityElement.element( "comment" );
if ( comment != null ) {
table.addComment( comment.getTextTrim() );
}
Attribute checkAttribute = entityElement.attribute( "check" );
if ( checkAttribute != null ) {
table.addCheckConstraint( checkAttribute.getValue() );
}
}
}
private void bindIdentifier(Element entityElement, EntityBinding entityBinding) {
final Element idElement = entityElement.element( "id" );
if ( idElement != null ) {
bindSimpleId( idElement, entityBinding );
return;
}
final Element compositeIdElement = entityElement.element( "composite-id" );
if ( compositeIdElement != null ) {
bindCompositeId( compositeIdElement, entityBinding );
}
throw new InvalidMappingException(
"Entity [" + entityBinding.getEntity().getName() + "] did not contain identifier mapping",
hibernateMappingBinder.getXmlDocument()
);
}
private void bindSimpleId(Element identifierElement, EntityBinding entityBinding) {
// Handle the domain portion of the binding...
final String explicitName = identifierElement.attributeValue( "name" );
final String attributeName = explicitName == null ? RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME : explicitName;
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
SimpleAttributeBinding idBinding = entityBinding.makeSimpleAttributeBinding( attributeName );
basicAttributeBinding( identifierElement, idBinding );
// Handle the relational portion of the binding...
Value idValue = processValues( identifierElement, entityBinding.getBaseTable(), attributeName );
idBinding.setValue( idValue );
// ear-mark this value binding as the identifier...
entityBinding.getEntityIdentifier().setValueBinding( idBinding );
if ( idValue instanceof Tuple ) {
// this should never ever happen..
throw new MappingException( "Unanticipated situation" );
}
entityBinding.getBaseTable().getPrimaryKey().addColumn( (Column) idValue );
// SimpleValue id = new SimpleValue( mappings, entity.getTable() );
// entity.setIdentifier( id );
// if ( propertyName == null || entity.getPojoRepresentation() == null ) {
// bindSimpleValue( idNode, id, false, RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME, mappings );
// if ( !id.isTypeSpecified() ) {
// throw new MappingException( "must specify an identifier type: " + entity.getEntityName()
// );
// }
// }
// else {
// bindSimpleValue( idNode, id, false, propertyName, mappings );
// PojoRepresentation pojo = entity.getPojoRepresentation();
// id.setTypeUsingReflection( pojo.getClassName(), propertyName );
//
// Property prop = new Property();
// prop.setValue( id );
// bindProperty( idNode, prop, mappings, inheritedMetas );
// entity.setIdentifierProperty( prop );
// }
// if ( propertyName == null ) {
// bindSimpleValue( idNode, id, false, RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME, mappings );
// }
// else {
// bindSimpleValue( idNode, id, false, propertyName, mappings );
// }
//
// if ( propertyName == null || !entity.hasPojoRepresentation() ) {
// if ( !id.isTypeSpecified() ) {
// throw new MappingException( "must specify an identifier type: "
// + entity.getEntityName() );
// }
// }
// else {
// id.setTypeUsingReflection( entity.getClassName(), propertyName );
// }
//
// if ( propertyName != null ) {
// Property prop = new Property();
// prop.setValue( id );
// bindProperty( idNode, prop, mappings, inheritedMetas );
// entity.setIdentifierProperty( prop );
// }
// TODO:
/*
* if ( id.getHibernateType().getReturnedClass().isArray() ) throw new MappingException(
* "illegal use of an array as an identifier (arrays don't reimplement equals)" );
*/
// makeIdentifier( idNode, id, mappings );
}
private static void bindCompositeId(Element identifierElement, EntityBinding entityBinding) {
final String explicitName = identifierElement.attributeValue( "name" );
// String propertyName = idNode.attributeValue( "name" );
// Component id = new Component( mappings, entity );
// entity.setIdentifier( id );
// bindCompositeId( idNode, id, entity, propertyName, mappings, inheritedMetas );
// if ( propertyName == null ) {
// entity.setEmbeddedIdentifier( id.isEmbedded() );
// if ( id.isEmbedded() ) {
// // todo : what is the implication of this?
// id.setDynamic( !entity.hasPojoRepresentation() );
// /*
// * Property prop = new Property(); prop.setName("id");
// * prop.setPropertyAccessorName("embedded"); prop.setValue(id);
// * entity.setIdentifierProperty(prop);
// */
// }
// }
// else {
// Property prop = new Property();
// prop.setValue( id );
// bindProperty( idNode, prop, mappings, inheritedMetas );
// entity.setIdentifierProperty( prop );
// }
//
// makeIdentifier( idNode, id, mappings );
}
private void bindDiscriminator(Element entityElement, EntityBinding entityBinding) {
Element discriminatorElement = entityElement.element( "discriminator" );
if ( discriminatorElement == null ) {
return;
}
final String explicitName = discriminatorElement.attributeValue( "name" );
final String attributeName = explicitName == null ? RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME : explicitName;
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
SimpleAttributeBinding discriminatorBinding = entityBinding.makeSimpleAttributeBinding( attributeName );
basicAttributeBinding( discriminatorElement, discriminatorBinding );
if ( discriminatorBinding.getHibernateTypeDescriptor().getTypeName() == null ) {
discriminatorBinding.getHibernateTypeDescriptor().setTypeName( "string" );
}
// Handle the relational portion of the binding...
Value discriminatorValue = processValues( discriminatorElement, entityBinding.getBaseTable(), attributeName );
discriminatorBinding.setValue( discriminatorValue );
// ear-mark this value binding as the discriminator...
entityBinding.makeEntityDiscriminator();
entityBinding.getEntityDiscriminator().setValueBinding( discriminatorBinding );
if ( "true".equals( discriminatorElement.attributeValue( "force" ) ) ) {
entityBinding.getEntityDiscriminator().setForced( true );
}
if ( "false".equals( discriminatorElement.attributeValue( "insert" ) ) ) {
entityBinding.getEntityDiscriminator().setInserted( false );
}
}
private void bindVersion(Element entityElement, EntityBinding entityBinding) {
Element versioningElement = entityElement.element( "version" );
if ( versioningElement == null ) {
versioningElement = entityElement.element( "timestamp" );
}
if ( versioningElement == null ) {
return;
}
boolean isVersion = "version".equals( versioningElement.getName() );
final String explicitName = versioningElement.attributeValue( "name" );
if ( explicitName == null ) {
throw new MappingException( "Mising property name for version/timestamp mapping [" + entityBinding.getEntity().getName() + "]" );
}
entityBinding.getEntity().getOrCreateSingularAttribute( explicitName );
SimpleAttributeBinding versionBinding = entityBinding.makeSimpleAttributeBinding( explicitName );
basicAttributeBinding( versioningElement, versionBinding );
if ( versionBinding.getHibernateTypeDescriptor().getTypeName() == null ) {
if ( isVersion ) {
versionBinding.getHibernateTypeDescriptor().setTypeName( "integer" );
}
else {
final String tsSource = versioningElement.attributeValue( "source" );
if ( "db".equals( tsSource ) ) {
versionBinding.getHibernateTypeDescriptor().setTypeName( "dbtimestamp" );
}
else {
versionBinding.getHibernateTypeDescriptor().setTypeName( "timestamp" );
}
}
}
// Handle the relational portion of the binding...
Value discriminatorValue = processValues( versioningElement, entityBinding.getBaseTable(), explicitName );
versionBinding.setValue( discriminatorValue );
// for version properties marked as being generated, make sure they are "always"
// generated; aka, "insert" is invalid; this is dis-allowed by the DTD,
// but just to make sure...
if ( versionBinding.getGeneration() == PropertyGeneration.INSERT ) {
throw new MappingException( "'generated' attribute cannot be 'insert' for versioning property" );
}
entityBinding.setVersioningValueBinding( versionBinding );
}
private void bindCaching(Element entityElement, EntityBinding entityBinding) {
final Element cacheElement = entityElement.element( "cache" );
if ( cacheElement == null ) {
return;
}
final String explicitRegion = cacheElement.attributeValue( "region" );
final String region = explicitRegion != null ? explicitRegion : entityBinding.getEntity().getName();
final String strategy = cacheElement.attributeValue( "usage" );
final boolean cacheLazyProps = !"non-lazy".equals( cacheElement.attributeValue( "include" ) );
entityBinding.setCaching( new Caching( region, strategy, cacheLazyProps ) );
}
}

View File

@ -0,0 +1,61 @@
/*
* 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.util;
import org.dom4j.Attribute;
import org.dom4j.Element;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class DomHelper {
public static String extractAttributeValue(Element element, String attributeName) {
return extractAttributeValue( element, attributeName, null );
}
public static String extractAttributeValue(Element element, String attributeName, String defaultValue) {
Attribute attribute = element.attribute( attributeName );
return attribute == null ? defaultValue : attribute.getValue();
}
public static int extractIntAttributeValue(Element element, String attributeName) {
return extractIntAttributeValue( element, attributeName, -1 );
}
public static int extractIntAttributeValue(Element element, String attributeName, int defaultValue) {
Attribute attribute = element.attribute( attributeName );
return attribute == null ? defaultValue : Integer.valueOf( attribute.getValue() );
}
public static boolean extractBooleanAttributeValue(Element element, String attributeName) {
return extractBooleanAttributeValue( element, attributeName, false );
}
public static boolean extractBooleanAttributeValue(Element element, String attributeName, boolean defaultValue) {
Attribute attribute = element.attribute( attributeName );
return attribute == null ? defaultValue : Boolean.valueOf( attribute.getValue() );
}
}

View File

@ -0,0 +1,116 @@
/*
* 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.binding;
import org.xml.sax.InputSource;
import org.hibernate.internal.util.ConfigHelper;
import org.hibernate.internal.util.xml.MappingReader;
import org.hibernate.internal.util.xml.Origin;
import org.hibernate.internal.util.xml.XMLHelper;
import org.hibernate.internal.util.xml.XmlDocument;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.source.Metadata;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* Basic tests of {@code hbm.xml} beinding code
*
* @author Steve Ebersole
*/
public class BasicHbmBindingTests extends BaseUnitTestCase {
@Test
public void testSuperSimpleMapping() {
Metadata metadata = new Metadata();
{
XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" );
metadata.getHibernateXmlBinder().bindRoot( xmlDocument );
EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() );
assertNotNull( entityBinding );
assertNotNull( entityBinding.getEntityIdentifier() );
assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() );
assertNull( entityBinding.getVersioningValueBinding() );
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" );
assertNotNull( idAttributeBinding );
assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() );
assertNotNull( idAttributeBinding.getAttribute() );
assertNotNull( idAttributeBinding.getValue() );
assertTrue( idAttributeBinding.getValue() instanceof Column );
AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" );
assertNotNull( nameBinding );
assertNotNull( nameBinding.getAttribute() );
assertNotNull( nameBinding.getValue() );
}
{
XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml" );
metadata.getHibernateXmlBinder().bindRoot( xmlDocument );
EntityBinding entityBinding = metadata.getEntityBinding( SimpleVersionedEntity.class.getName() );
assertNotNull( entityBinding );
assertNotNull( entityBinding.getEntityIdentifier() );
assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() );
assertNotNull( entityBinding.getVersioningValueBinding() );
assertNotNull( entityBinding.getVersioningValueBinding().getAttribute() );
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" );
assertNotNull( idAttributeBinding );
assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() );
assertNotNull( idAttributeBinding.getAttribute() );
assertNotNull( idAttributeBinding.getValue() );
assertTrue( idAttributeBinding.getValue() instanceof Column );
AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" );
assertNotNull( nameBinding );
assertNotNull( nameBinding.getAttribute() );
assertNotNull( nameBinding.getValue() );
}
}
private XmlDocument readResource(final String name) {
final String path = "/org/hibernate/test/id/Car.hbm.xml";
Origin origin = new Origin() {
@Override
public String getType() {
return "resource";
}
@Override
public String getName() {
return name;
}
};
InputSource inputSource = new InputSource( ConfigHelper.getResourceAsStream( name ) );
return MappingReader.INSTANCE.readMappingDocument( XMLHelper.DEFAULT_DTD_RESOLVER, inputSource, origin );
}
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.metamodel.binding">
<class name="SimpleEntity">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,55 @@
/*
* 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.binding;
/**
* @author Steve Ebersole
*/
public class SimpleEntity {
private Long id;
private String name;
public SimpleEntity() {
}
public SimpleEntity(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.binding;
import java.sql.Types;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.Table;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertSame;
/**
* Basic binding "smoke" tests
*
* @author Steve Ebersole
*/
public class SimpleValueBindingTests extends BaseUnitTestCase {
public static final Datatype BIGINT = new Datatype( Types.BIGINT, "BIGINT", Long.class );
public static final Datatype VARCHAR = new Datatype( Types.VARCHAR, "VARCHAR", String.class );
@Test
public void testBasicMiddleOutBuilding() {
Table table = new Table( new Schema( null, null ), "the_table" );
Entity entity = new Entity( "TheEntity", null );
EntityBinding entityBinding = new EntityBinding();
entityBinding.setEntity( entity );
entityBinding.setBaseTable( table );
SingularAttribute idAttribute = entity.getOrCreateSingularAttribute( "id" );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( "id" );
attributeBinding.getHibernateTypeDescriptor().setTypeName( "long" );
assertSame( idAttribute, attributeBinding.getAttribute() );
entityBinding.getEntityIdentifier().setValueBinding( attributeBinding );
Column idColumn = table.createColumn( "id" );
idColumn.setDatatype( BIGINT );
idColumn.setSize( Column.Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );
table.getPrimaryKey().setName( "my_table_pk" );
attributeBinding.setValue( idColumn );
}
}

View File

@ -0,0 +1,40 @@
<?xml version="1.0"?>
<!--
~ 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
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.metamodel.binding">
<class name="SimpleVersionedEntity">
<id name="id">
<generator class="increment"/>
</id>
<version name="version"/>
<property name="name"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,64 @@
/*
* 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.binding;
/**
* @author Steve Ebersole
*/
public class SimpleVersionedEntity {
private Long id;
private String name;
private long version;
public SimpleVersionedEntity() {
}
public SimpleVersionedEntity(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
}

View File

@ -24,11 +24,12 @@
package org.hibernate.metamodel.relational;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
* @author Steve Ebersole
*/
@ -53,9 +54,9 @@ public class ObjectNameTests extends BaseUnitTestCase {
@Test
public void testIdentifierBuilding() {
ObjectName on = new ObjectName( "schema", "catalog", "name" );
assertEquals( "schema.catalog.name", on.getIdentifier() );
assertEquals( "schema.catalog.name", on.toText() );
on = new ObjectName( "schema", null, "name" );
assertEquals( "schema.name", on.getIdentifier() );
assertEquals( "schema.name", on.toText() );
}
}

View File

@ -35,8 +35,6 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class TableManipulationTests extends BaseUnitTestCase {
@ -45,10 +43,11 @@ public class TableManipulationTests extends BaseUnitTestCase {
@Test
public void testTableCreation() {
Table table = new Table( new ObjectName( null, null, "my_table" ) );
assertNull( table.getObjectName().getSchema() );
assertNull( table.getObjectName().getCatalog() );
assertEquals( "my_table", table.getObjectName().getName().toString() );
Schema schema = new Schema( null, null );
Table table = schema.createTable( Identifier.toIdentifier( "my_table" ) );
assertNull( table.getSchema().getName().getSchema() );
assertNull( table.getSchema().getName().getCatalog() );
assertEquals( "my_table", table.getTableName().toString() );
assertEquals( "my_table", table.getExportIdentifier() );
assertNull( table.getPrimaryKey().getName() );
assertFalse( table.values().iterator().hasNext() );
@ -88,7 +87,8 @@ public class TableManipulationTests extends BaseUnitTestCase {
@Test
public void testBasicForeignKeyDefinition() {
Table book = new Table( new ObjectName( null, null, "BOOK" ) );
Schema schema = new Schema( null, null );
Table book = schema.createTable( Identifier.toIdentifier( "BOOK" ) );
Column bookId = book.createColumn( "id" );
bookId.setDatatype( INTEGER );
@ -96,7 +96,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
book.getPrimaryKey().addColumn( bookId );
book.getPrimaryKey().setName( "BOOK_PK" );
Table page = new Table( new ObjectName( null, null, "PAGE" ) );
Table page = schema.createTable( Identifier.toIdentifier( "PAGE" ) );
Column pageId = page.createColumn( "id" );
pageId.setDatatype( INTEGER );