001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.bo;
017
018import java.io.Serializable;
019import java.util.HashMap;
020import java.util.Map;
021
022/**
023 * Represents a relationship to another class that exists within a given parent class
024 *
025 * <p>
026 * In terms of relational db, this can be thought of as a foreign key relationship. That is one of the
027 * properties (fields) of the parent class (parent table) has a relationship to another class (table)
028 * </p>
029 *
030 * @author Kuali Rice Team (rice.collab@kuali.org)
031 */
032public class DataObjectRelationship implements Serializable {
033    private Class<?> relatedClass;
034    private Class<?> parentClass;
035    private String parentAttributeName;
036    private String userVisibleIdentifierKey = null;
037
038    private Map<String, String> parentToChildReferences = new HashMap<String, String>(4);
039
040    public DataObjectRelationship() {
041    }
042
043    public DataObjectRelationship(Class<?> parentClass, String parentAttributeName, Class<?> relatedClass) {
044        super();
045
046        this.relatedClass = relatedClass;
047        this.parentClass = parentClass;
048        this.parentAttributeName = parentAttributeName;
049    }
050
051    /**
052     * Returns the Class that contains the relationship (the parent)
053     *
054     * @return Class<?> parent class
055     */
056    public Class<?> getParentClass() {
057        return parentClass;
058    }
059
060    /**
061     * Returns the class the attribute within the parent class has a relationship to
062     *
063     * @return Class<?> related class
064     */
065    public Class<?> getRelatedClass() {
066        return this.relatedClass;
067    }
068
069    /**
070     * Returns the name of the attribute within the parent class that holds the related class object
071     *
072     * <p>
073     * Note this attribute should be of type given by #getRelatedClass
074     * </p>
075     *
076     * @return String attribute name within parent class
077     */
078    public String getParentAttributeName() {
079        return parentAttributeName;
080    }
081
082    /**
083     * Provides a Map of attribute pairs that make up the relationship, where the map key
084     * is the attribute name on the parent class and the map value is the attribute name on
085     * the related class
086     *
087     * @return Map<String, String> related attribute pairs
088     */
089    public Map<String, String> getParentToChildReferences() {
090        return parentToChildReferences;
091    }
092
093    /**
094     * Setter for the Map of attributes that participate in the relationship
095     *
096     * @param referenceAttributes
097     */
098    public void setParentToChildReferences(Map<String, String> referenceAttributes) {
099        this.parentToChildReferences = referenceAttributes;
100    }
101
102    /**
103     * Retrieves the attribute within the parent class that is related to the given attribute of
104     * the related class by the relationship represented by this object
105     *
106     * @param childAttributeName - name of attribute within the related class to find parent attribute for
107     * @return String attribute name within parent class
108     */
109    public String getParentAttributeForChildAttribute(String childAttributeName) {
110        for (Map.Entry<String, String> entry : parentToChildReferences.entrySet()) {
111            if (entry.getValue().equals(childAttributeName)) {
112                return entry.getKey();
113            }
114        }
115        return null;
116    }
117
118    /**
119     * Retrieves the attribute within the related class that is related to the given attribute of the
120     * parent class by the relationship represented by this object
121     *
122     * @param parentAttributeName - name of attribute within the parent class to find related (child) attribute for
123     * @return String attribute name within the related class
124     */
125    public String getChildAttributeForParentAttribute(String parentAttributeName) {
126        return parentToChildReferences.get(parentAttributeName);
127    }
128
129    public String getUserVisibleIdentifierKey() {
130        return userVisibleIdentifierKey;
131    }
132
133    public void setUserVisibleIdentifierKey(String userVisibleIdentifierKey) {
134        this.userVisibleIdentifierKey = userVisibleIdentifierKey;
135    }
136
137    public String toString() {
138        StringBuffer sb = new StringBuffer();
139        sb.append("Relationship: ").append(parentClass.getName()).append(" -> ").append(relatedClass.getName());
140        for (Map.Entry<String, String> refs : parentToChildReferences.entrySet()) {
141            sb.append("\n   ").append(refs.getKey()).append(" -> ").append(refs.getValue());
142        }
143        return sb.toString();
144    }
145}