/******************************************************************************* * Copyright (c) 2010-2011 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributor: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.hibernate.jpt.core.internal.context; import org.eclipse.jpt.jpa.core.context.Entity; import org.eclipse.jpt.jpa.core.context.JoinColumn; import org.eclipse.jpt.jpa.core.context.Relationship; import org.eclipse.jpt.jpa.core.context.RelationshipMapping; import org.eclipse.jpt.jpa.db.Table; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.jboss.tools.hibernate.jpt.core.internal.HibernateJpaProject; import org.jboss.tools.hibernate.jpt.core.internal.HibernateJptPlugin; import org.jboss.tools.hibernate.jpt.core.internal.validation.HibernateJpaValidationMessage; import org.jboss.tools.hibernate.runtime.spi.INamingStrategy; /** * @author Dmitry Geraskov * */ public class NamingStrategyMappingTools { public static String buildJoinTableDefaultName(Relationship relationshipReference) { if (relationshipReference.getJpaProject().getDataSource().connectionProfileIsActive()) { return buildDbJoinTableDefaultName(relationshipReference); } RelationshipMapping relationshipMapping = relationshipReference.getMapping(); if (relationshipMapping == null) { return null; } if (!(relationshipReference.getTypeMapping() instanceof Entity)) return null;//could be JavaNullTypeMapping Entity ownerEntity = (Entity) relationshipReference.getTypeMapping(); org.eclipse.jpt.jpa.core.context.Table ownerTable = ownerEntity.getTable(); if (ownerTable == null) { return null; } Entity targetEntity = relationshipMapping.getResolvedTargetEntity(); if (targetEntity == null) { return null; } org.eclipse.jpt.jpa.core.context.Table targetTable = targetEntity.getTable(); if (targetTable == null) { return null; } INamingStrategy ns = getJpaProject(relationshipReference).getNamingStrategy(); if (getJpaProject(relationshipReference).isNamingStrategyEnabled() && ns != null){ /* * By testing generated DDL I have found for JPA console configuration: * 1) first parameter of the method is always fully qualified owner entity class name * 2) second and forth parameters of the method are always fully qualified target entity class name * 3) third parameter of the method is name attribute of @Table annotation, * if it is not specified, then it is *unqualified* name attribute of @Entity annotation * if @Entity annotation not specified it is *unqualified* name of the target entity class. * 4) fifth parameter is owner entity field name (even if @Column annotation set different name) * */ try { String targetEntityName = targetEntity.getPersistentType().getName(); String ownerEntityName = ownerEntity.getPersistentType().getName(); String propName = relationshipMapping.getPersistentAttribute().getName(); return ns.collectionTableName(ownerEntityName, targetTable.getName(), targetEntityName, targetTable.getName(), propName); } catch (Exception e) { IMessage m = HibernateJpaValidationMessage.buildMessage(IMessage.HIGH_SEVERITY, Messages.NAMING_STRATEGY_EXCEPTION, relationshipReference); HibernateJptPlugin.logException(m.getText(), e); } } return ownerTable.getName() + '_' + targetTable.getName(); } public static HibernateJpaProject getJpaProject(Relationship relationshipReference){ return (HibernateJpaProject)relationshipReference.getJpaProject(); } protected static String buildDbJoinTableDefaultName(Relationship relationshipReference) { Table owningTable = relationshipReference.getTypeMapping().getPrimaryDbTable(); if (owningTable == null) { return null; } RelationshipMapping relationshipMapping = relationshipReference.getMapping(); if (relationshipMapping == null) { return null; } Entity targetEntity = relationshipMapping.getResolvedTargetEntity(); if (targetEntity == null) { return null; } Table targetTable = targetEntity.getPrimaryDbTable(); if (targetTable == null) { return null; } String name = owningTable.getName() + '_' + targetTable.getName(); return owningTable.getDatabase().convertNameToIdentifier(name); } public static String buildJoinColumnDefaultName(JoinColumn joinColumn, JoinColumn.ParentAdapter parent) { if (parent.getJoinColumnsSize() != 1) { return null; } String prefix = parent.getAttributeName(); if (prefix == null) { Entity targetEntity = parent.getRelationshipTarget(); if (targetEntity == null) { return null; } prefix = targetEntity.getName(); } // not sure which of these is correct... // (the spec implies that the referenced column is always the // primary key column of the target entity) // Column targetColumn = joinColumn.getTargetPrimaryKeyDbColumn(); String targetColumnName = joinColumn.getReferencedColumnName(); if (targetColumnName == null) { return null; } String name = prefix + '_' + targetColumnName; // not sure which of these is correct... // converting the name to an identifier will result in the identifier // being delimited nearly every time (at least on non-Sybase/MS // databases); but that probably is not the intent of the spec... // return targetColumn.getDatabase().convertNameToIdentifier(name); return name; } }