blob: c3bfa5158e5644496e681f9d698600027a11ec4d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2012 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation
*
******************************************************************************/
package org.eclipse.persistence.tools.gen.internal;
import java.util.Iterator;
import java.util.List;
import org.eclipse.persistence.tools.utility.StringTools;
/**
* Represents an association role (the referrer or referenced role).
* <p>
* Provisional API: This interface is part of an interim API that is still under development and
* expected to change significantly before reaching stability. It is available at this early stage
* to solicit feedback from pioneering adopters on the understanding that any code that uses this
* API will almost certainly be broken (repeatedly) as the API evolves.
*
* @version 2.6
*/
@SuppressWarnings("nls")
public class AssociationRole implements java.io.Serializable {
private transient Association mAssociation; //transient: see restore
private boolean mIsReferrerRole;
private String mPropertyName;
private String mCascade;
private final static long serialVersionUID = 1;
AssociationRole(Association association, boolean isReferrerRole) {
super();
mAssociation = association;
mIsReferrerRole = isReferrerRole;
}
/**
* Empty constructor needed by the deserialization (should not be used otherwise).
*/
public AssociationRole() {
super();
}
/**
* Called after the asscociations are deserialized to attach
* the customizer object.
*/
protected void restore(Association association) {
mAssociation = association;
}
public Association getAssociation() {
return mAssociation;
}
public boolean isReferrerRole() {
return mIsReferrerRole;
}
/**
* Returns the opposite role or null if the association
* is not bi directional.
*/
public AssociationRole getOppositeRole() {
Association association = getAssociation();
if (!association.getDirectionality().equals(Association.BI_DI)) {
return null;
}
if (isReferrerRole()) {
return association.getReferencedRole();
} else {
return association.getReferrerRole();
}
}
/**
* Returns the association cardinality, one of {@link #MANY_TO_ONE}|{@link #MANY_TO_MANY}
* |{@link #ONE_TO_ONE}|{@link #ONE_TO_MANY}
*/
public String getCardinality() {
String type = mAssociation.getCardinality();
if (!mIsReferrerRole) {
if (type.equals(Association.ONE_TO_MANY)) {
type = Association.MANY_TO_ONE;
} else if (type.equals(Association.MANY_TO_ONE)) {
type = Association.ONE_TO_MANY;
}
}
return type;
}
public ORMGenTable getReferrerTable() {
if (mIsReferrerRole) {
return mAssociation.getReferrerTable();
} else {
return mAssociation.getReferencedTable();
}
}
public List<ORMGenColumn> getReferrerColumns(){
if (mIsReferrerRole) {
return mAssociation.getReferrerColumns();
} else {
return mAssociation.getReferencedColumns();
}
}
/**
* Returns the referenced column corresponding to a referrer column.
*/
public ORMGenColumn getReferencedColumn(String referrerColumn) {
boolean hasJoinTable = mAssociation.getJoinTable() != null;
List<ORMGenColumn> referrerColumns = getReferrerColumns();
for (int i = 0, n = referrerColumns.size(); i < n; ++i) {
ORMGenColumn column = referrerColumns.get(i);
if (column.getName().equals(referrerColumn)) {
if (hasJoinTable) {
return getReferrerJoinColumns().get(i);
} else {
return getReferencedColumns().get(i);
}
}
}
assert(false);
return null;
}
/**
* Returns the referrer column corresponding to a referenced column.
*/
public ORMGenColumn getReferrerColumn(String referencedColumn) {
boolean hasJoinTable = mAssociation.getJoinTable() != null;
List<ORMGenColumn> referencedColumns = getReferencedColumns();
for (int i = 0, n = referencedColumns.size(); i < n; ++i) {
ORMGenColumn column = referencedColumns.get(i);
if (column.getName().equals(referencedColumn)) {
if (hasJoinTable) {
return getReferencedJoinColumns().get(i);
} else {
return getReferrerColumns().get(i);
}
}
}
assert(false);
return null;
}
public ORMGenTable getReferencedTable() {
if (mIsReferrerRole) {
return mAssociation.getReferencedTable();
} else {
return mAssociation.getReferrerTable();
}
}
public List<ORMGenColumn> getReferencedColumns() {
if (mIsReferrerRole) {
return mAssociation.getReferencedColumns();
} else {
return mAssociation.getReferrerColumns();
}
}
public List<ORMGenColumn> getReferrerJoinColumns() {
if (mIsReferrerRole) {
return mAssociation.getReferrerJoinColumns();
} else {
return mAssociation.getReferencedJoinColumns();
}
}
public List<ORMGenColumn> getReferencedJoinColumns() {
if (mIsReferrerRole) {
return mAssociation.getReferencedJoinColumns();
} else {
return mAssociation.getReferrerJoinColumns();
}
}
/**
* Returns the name that should be used by the generator for
* the property corresponding to this role.
*/
public String getPropertyName() {
if (mPropertyName != null) { //if the user explicitly set it then don't be too smart
return mPropertyName;
}
return getDefaultPropertyName();
}
private String getDefaultPropertyName() {
String propName = StringTools.EMPTY_STRING;
ORMGenTable referrerTable = getReferrerTable();
ORMGenTable referencedTable = getReferencedTable();
boolean isSingular = isSingular();
propName = referencedTable.getVarName(isSingular);
List<AssociationRole> clashingRoles = new java.util.ArrayList<AssociationRole>(); //roles with our same referrer and referenced tables (i.e would yield the same property name in the same bean)
/*make sure there is no role with the same name.*/
for (Iterator<AssociationRole> iter = referrerTable.getAssociationRoles().iterator(); iter.hasNext(); ) {
AssociationRole role = iter.next();
if (role.getReferrerTable().getName().equals(referrerTable.getName())
&& role.getReferencedTable().getName().equals(referencedTable.getName())
&& role.isSingular() == isSingular) {
clashingRoles.add(role);
}
}
if (clashingRoles.size() > 1) {
int index = clashingRoles.indexOf(this);
assert(index >= 0);
propName += index+1;
}
/*make sure there is no column with the same name.*/
for (Iterator<ORMGenColumn> iter = referrerTable.getColumns().iterator(); iter.hasNext(); ) {
ORMGenColumn column = iter.next();
if (column.getPropertyName().equals(propName)) {
String prefix = isSingular ? "Bean" : "Set";
propName += prefix;
break;
}
}
return propName;
}
private boolean isSingular() {
String cardinality = getCardinality();
return cardinality.equals(Association.ONE_TO_ONE) || cardinality.equals(Association.MANY_TO_ONE);
}
/**
* Changes the name that should be used by the generator for
* the property corresponding to this role.
* If the argument name is null or empty string then the
* default computed name is used.
*/
public void setPropertyName(String name) {
if (name != null && name.length() == 0) {
name = null;
}
if (name != null && name.equals(getDefaultPropertyName())) {
name = null;
}
mPropertyName = name;
}
/**
* Returns the cascade value for this role.
* Returns if none.
*/
public String getCascade() {
return mCascade;
}
public void setCascade(String cascade) {
// if no checkbox is selected, set cascade to an empty string
if (cascade != null && cascade.length() == 0) {
cascade = StringTools.EMPTY_STRING;
}
mCascade = cascade;
}
/**
* Returns a descriptive string used in a comment in the generated
* file (from the Velocity template).
*/
public String getDescription() {
//<!-- $directionality $cardinality association to $referencedClassName -->
String directionality;
if (getAssociation().getDirectionality().equals(Association.BI_DI)) {
directionality = "bi-directional";
} else {
directionality = "uni-directional";
}
return directionality + " " + getAssociation().getCardinality() + " association to " + getReferencedTable().getClassName();
}
}