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.datadictionary;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
020
021/**
022                    The primitiveAttribute element identifies one pair of
023                    corresponding fields in the primary business object and
024                    the related business object.
025
026                    JSTL: primitiveAttribute is a Map which is accessed by the
027                    sequential key of "0", "1", etc.  Each entry contains the following
028                    keys:
029                        * sourceName (String)
030                        * targetName (String)
031                    The value corresponding to the sourceName key is the attribute name defined
032                    for the primary business object.
033                    The value corresponding to the targetName key is the attribute name for
034                    the object being referenced by objectAttributeName.
035 */
036public class PrimitiveAttributeDefinition extends DataDictionaryDefinitionBase {
037    private static final long serialVersionUID = -715128943756700821L;
038    
039        protected String sourceName;
040    protected String targetName;
041
042    public PrimitiveAttributeDefinition() {}
043
044
045    /**
046     * @return sourceName
047     */
048    public String getSourceName() {
049        return sourceName;
050    }
051
052    /**
053     * sourceName is the name of the POJO property of the business object
054     * 
055     * @throws IllegalArgumentException if the given sourceName is blank
056     */
057    public void setSourceName(String sourceName) {
058        if (StringUtils.isBlank(sourceName)) {
059            throw new IllegalArgumentException("invalid (blank) sourceName");
060        }
061
062        this.sourceName = sourceName;
063    }
064
065
066    /**
067     * @return targetName
068     */
069    public String getTargetName() {
070        return targetName;
071    }
072
073    /**
074     * targetName is the name of attribute that corresponds to the sourceName in the looked up BO
075     * 
076     * @throws IllegalArgumentException if the given targetName is blank
077     */
078    public void setTargetName(String targetName) {
079        if (StringUtils.isBlank(targetName)) {
080            throw new IllegalArgumentException("invalid (blank) targetName");
081        }
082
083        this.targetName = targetName;
084    }
085
086
087    /**
088     * Directly validate simple fields.
089     * 
090     * @see org.kuali.rice.krad.datadictionary.DataDictionaryDefinition#completeValidation(java.lang.Class, java.lang.Object)
091     */
092    public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass) {
093        if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, sourceName)) {
094            throw new AttributeValidationException("unable to find attribute '" + sourceName + "' in relationship class '" + rootBusinessObjectClass + "' (" + "" + ")");
095        }
096        if (!DataDictionary.isPropertyOf(otherBusinessObjectClass, targetName)) {
097            throw new AttributeValidationException("unable to find attribute '" + targetName + "' in related class '" + otherBusinessObjectClass.getName() + "' (" + "" + ")");
098        }
099
100        Class sourceClass = DataDictionary.getAttributeClass(rootBusinessObjectClass, sourceName);
101        Class targetClass = DataDictionary.getAttributeClass(otherBusinessObjectClass, targetName);
102        if ((null == sourceClass && null != targetClass) || (null != sourceClass && null == targetClass) || !StringUtils.equals(sourceClass.getName(), targetClass.getName())) {            
103                String sourceClassName = rootBusinessObjectClass.getName();
104            String targetClassName = otherBusinessObjectClass.getName();
105            String sourcePath = sourceClassName + "." + sourceName;
106            String targetPath = targetClassName + "." + targetName;
107            
108            // Just a temp hack to ignore null Person objects
109            if ((sourcePath != null && !StringUtils.contains(sourcePath, ".principalId")) && (targetPath != null && !StringUtils.contains(targetPath, ".principalId"))) {
110                throw new AttributeValidationException("source attribute '" + sourcePath + "' (" + sourceClass + ") and target attribute '" + targetPath + "' (" + targetClass + ") are of differing types (" + "" + ")");
111            }
112        }
113    }
114
115
116    /**
117     * @see java.lang.Object#toString()
118     */
119    @Override
120    public String toString() {
121        return "PrimitiveAttributeDefinition (" + getSourceName()+","+getTargetName()+")";
122    }
123}