001    /**
002     * Copyright 2005-2013 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     */
016    package org.kuali.rice.krad.util;
017    
018    import org.apache.commons.beanutils.NestedNullException;
019    import org.junit.Test;
020    import org.kuali.rice.coreservice.impl.parameter.ParameterBo;
021    import org.kuali.rice.kns.util.FieldUtils;
022    import org.kuali.rice.kns.web.struts.form.pojo.PojoPlugin;
023    import org.kuali.rice.kns.web.struts.form.pojo.PojoPropertyUtilsBean;
024    import org.kuali.rice.krad.bo.BusinessObject;
025    import org.kuali.rice.krad.bo.DocumentAttachment;
026    import org.kuali.rice.krad.bo.MultiDocumentAttachment;
027    import org.kuali.rice.krad.datadictionary.AttributeDefinition;
028    import org.kuali.rice.krad.datadictionary.DataDictionaryEntryBase;
029    import org.kuali.rice.krad.maintenance.MaintenanceDocumentBase;
030    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
031    import org.kuali.rice.krad.test.document.BOContainingPerson;
032    import org.kuali.rice.krad.test.KRADTestCase;
033    
034    import java.util.ArrayList;
035    import java.util.HashMap;
036    import java.util.Map;
037    
038    import static org.junit.Assert.*;
039    
040    /**
041     * ObjectUtilsTest tests {@link ObjectUtils}
042     * 
043     * @author Kuali Rice Team (rice.collab@kuali.org)
044     */
045    public class ObjectUtilsTest extends KRADTestCase {
046        @Test
047        /**
048         * tests {@link ObjectUtils#equalByKeys(org.kuali.rice.krad.bo.PersistableBusinessObject, org.kuali.rice.krad.bo.PersistableBusinessObject)}
049         */
050        public void testObjectUtils_equalsByKey() throws Exception {
051            ParameterBo parameterInDB = new ParameterBo();
052            parameterInDB.setNamespaceCode("KR-NS");
053            parameterInDB.setName("OBJ_UTIL_TEST");
054            
055            ParameterBo parameterNew = new ParameterBo();
056            parameterNew.setNamespaceCode("KR-NS");
057            parameterInDB.setName(null);
058            
059            boolean equalsResult = false;
060            equalsResult = ObjectUtils.equalByKeys(parameterInDB, parameterNew);
061            assertFalse(equalsResult);
062        }
063        
064    /*      @Test
065            public void testGetFormatterWithDataDictionary() throws Exception {
066                    // test formatter getting correctly pulled from data dictionary
067                    TravelAccountUseRate useRate = new TravelAccountUseRate();
068                    Formatter formatter = ObjectUtils.getFormatterWithDataDictionary(useRate, "active");
069                    assertTrue("Incorrect formatter returned for active property", formatter instanceof BooleanFormatter);
070    
071                    changeAttributeDefinitionFormatter(useRate.getClass(), "active", IntegerFormatter.class);
072                    formatter = ObjectUtils.getFormatterWithDataDictionary(useRate, "active");
073                    assertTrue("Incorrect formatter returned for active property", formatter instanceof IntegerFormatter);
074                    
075                    // test formatter getting correctly pulled by data type
076                    formatter = ObjectUtils.getFormatterWithDataDictionary(useRate, "activeFromDate");
077                    assertTrue("Incorrect formatter returned for date type", formatter instanceof DateFormatter);
078                    
079                    formatter = ObjectUtils.getFormatterWithDataDictionary(useRate, "rate");
080                    assertTrue("Incorrect formatter returned for percent type", formatter instanceof PercentageFormatter);
081                    
082                    formatter = ObjectUtils.getFormatterWithDataDictionary(useRate, "number");
083                    assertTrue("Incorrect formatter returned for string type", formatter.getClass().getName().equals("org.kuali.rice.core.web.format.Formatter"));
084            }
085    */
086            private void changeAttributeDefinitionFormatter(Class boClass, String attributeName, Class formatterClass) {
087                    DataDictionaryEntryBase entry = (DataDictionaryEntryBase) KRADServiceLocatorWeb.getDataDictionaryService()
088                                    .getDataDictionary().getDictionaryObjectEntry(boClass.getName());
089                    if (entry != null) {
090                            AttributeDefinition attributeDefinition = entry.getAttributeDefinition(attributeName);
091                            attributeDefinition.setFormatterClass(formatterClass.getName());
092                    }
093            }
094    
095        @Test
096        public void testMissingNestedObjectCreation() throws Exception {
097            PojoPlugin.initBeanUtils();
098            MaintenanceDocumentBase m = new MaintenanceDocumentBase();
099            m.setAttachments(new ArrayList<MultiDocumentAttachment>());
100            assertNotNull(m.getAttachments());
101            Object o = ObjectUtils.getPropertyValue(m, "attachments[0]");
102            assertNotNull(o);
103            assertTrue(o instanceof MultiDocumentAttachment);
104        }
105    
106        @Test
107        public void testInvalidOJBCollection() {
108            // abcd is not a collection (or any other) property
109            assertNull(new PojoPropertyUtilsBean.PersistenceStructureServiceProvider().getCollectionItemClass(new MaintenanceDocumentBase(), "abcd"));
110            // attachment is a valid property, but not a collection
111            assertNull(new PojoPropertyUtilsBean.PersistenceStructureServiceProvider().getCollectionItemClass(new MaintenanceDocumentBase(), "attachment"));
112            // attachmentContent is an array
113            assertNull(new PojoPropertyUtilsBean.PersistenceStructureServiceProvider().getCollectionItemClass(new DocumentAttachment(), "attachmentContent"));
114        }
115    
116    
117        @Test
118        public void testPopulateBusinessObjectFromMap() {
119            PojoPlugin.initBeanUtils();
120    
121            NestedBo nestedBo = new NestedBo();
122    
123            Map<String, Object> values = new HashMap<String, Object>();
124            values.put("nestedImpl.value", "value");
125    
126            FieldUtils.populateBusinessObjectFromMap(nestedBo, values);
127    
128            assertNotNull(nestedBo.nested);
129    
130            nestedBo.nested = null;
131            values.clear();
132            values.put("nestedIntf.value", "value");
133    
134            try {
135                FieldUtils.populateBusinessObjectFromMap(nestedBo, values);
136                fail("Expected to throw NestedNullException due to attempt to instantiate interface");
137            } catch (NestedNullException nne) {
138                // expected
139            }
140    
141            BOContainingPerson bo = new BOContainingPerson();
142            values.clear();
143            values.put("person.name", "value");
144            FieldUtils.populateBusinessObjectFromMap(bo, values);
145    
146            assertNotNull(bo.getPerson());
147            assertEquals("value", bo.getPerson().getName());
148        }
149    
150        public static interface ValueHolder {
151            public void setValue(String value);
152            public String getValue();
153        }
154    
155        public static class NestedBo implements BusinessObject, ValueHolder {
156            public String value = "foo";
157            public NestedBo nested = null;
158    
159            public void refresh() {}
160    
161            public void setNestedImpl(NestedBo nested) {
162                this.nested = nested;
163            }
164    
165            public NestedBo getNestedImpl() {
166                return nested;
167            }
168    
169            public void setNestedIntf(ValueHolder refreshable) {
170                nested = (NestedBo) refreshable;
171            }
172    
173            public ValueHolder getNestedIntf() {
174                return nested;
175            }
176    
177            public void setValue(String value) {
178                this.value = value;
179            }
180    
181            public String getValue() {
182                return value;
183            }
184        }
185    
186    }