001    /**
002     * Copyright 2005-2014 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.uif.util;
017    
018    import static org.junit.Assert.assertEquals;
019    import static org.junit.Assert.assertNull;
020    import static org.junit.Assert.assertTrue;
021    
022    import java.lang.reflect.Field;
023    import java.lang.reflect.ParameterizedType;
024    import java.util.ArrayList;
025    import java.util.Arrays;
026    import java.util.HashMap;
027    import java.util.HashSet;
028    import java.util.List;
029    import java.util.Map;
030    import java.util.Set;
031    
032    import org.junit.Before;
033    import org.junit.Ignore;
034    import org.junit.Test;
035    import org.kuali.rice.krad.uif.component.Component;
036    import org.kuali.rice.krad.uif.component.ComponentBase;
037    import org.kuali.rice.krad.uif.component.ReferenceCopy;
038    import org.kuali.rice.krad.uif.container.CollectionGroup;
039    import org.kuali.rice.krad.uif.container.CollectionGroupBase;
040    import org.kuali.rice.krad.uif.control.CheckboxControl;
041    import org.kuali.rice.krad.uif.element.Action;
042    import org.kuali.rice.krad.uif.element.Label;
043    import org.kuali.rice.krad.uif.field.DataField;
044    import org.kuali.rice.krad.uif.field.DataFieldBase;
045    import org.kuali.rice.krad.uif.field.FieldBase;
046    import org.kuali.rice.krad.uif.field.InputField;
047    import org.kuali.rice.krad.uif.field.InputFieldBase;
048    import org.kuali.rice.krad.uif.widget.Tooltip;
049    
050    /**
051     * ComponentUtilsTest tests various ComponentUtils methods
052     * 
053     * @author Kuali Rice Team (rice.collab@kuali.org)
054     */
055    public class ComponentUtilsTest {
056    
057        private String componentId;
058        private Component component;
059    
060        @Before
061        public void setup() {
062            component = new InputFieldBase();
063            componentId = "field1";
064            component.setId(componentId);
065        }
066    
067        // Initialization methods
068        private CollectionGroup initializeCollectionGroup() {
069            CollectionGroupBase collectionGroup = new CollectionGroupBase();
070            collectionGroup = (CollectionGroupBase) initializeComponentBase(collectionGroup);
071    
072            DataField field1 = initializeDataField();
073            DataField field2 = initializeDataField();
074            List<DataField> fields = new ArrayList<DataField>();
075            fields.add(field1);
076            fields.add(field2);
077            collectionGroup.setAddLineItems(fields);
078    
079            Action action1 = new Action();
080            action1 = (Action) initializeComponentBase(action1);
081            action1.setActionLabel("Action Label");
082            action1.setActionScript("<script>Action script</script>");
083    
084            Action action2 = new Action();
085            action2 = (Action) initializeComponentBase(action2);
086            action2.setActionLabel("Action Label 2");
087            action2.setActionScript("<script>Action script 2</script>");
088            List<Action> addLineActions = new ArrayList<Action>();
089            addLineActions.add(action1);
090            addLineActions.add(action2);
091            collectionGroup.setAddLineActions(addLineActions);
092    
093            return collectionGroup;
094        }
095    
096        private FieldBase initializeFieldBase() {
097            FieldBase fieldBase = new FieldBase();
098            fieldBase = (FieldBase) initializeComponentBase(fieldBase);
099            fieldBase.setShortLabel("Label");
100    
101            return fieldBase;
102        }
103    
104        private DataField initializeDataField() {
105            DataFieldBase dataField = new DataFieldBase();
106            dataField = (DataFieldBase) initializeComponentBase(dataField);
107            dataField.setAddHiddenWhenReadOnly(true);
108    
109            List<String> additionalHiddenPropertyNames = new ArrayList<String>();
110            additionalHiddenPropertyNames.add("HiddenA");
111            additionalHiddenPropertyNames.add("HiddenB");
112            additionalHiddenPropertyNames.add("HiddenC");
113            dataField.setAdditionalHiddenPropertyNames(additionalHiddenPropertyNames);
114    
115            dataField.setApplyMask(true);
116            dataField.setDefaultValue("default");
117            dataField.setDictionaryAttributeName("DictionaryName");
118            dataField.setDictionaryObjectEntry("DictionaryObjectEntry");
119            dataField.setEscapeHtmlInPropertyValue(true);
120            dataField.setForcedValue("Forced");
121            dataField.setMultiLineReadOnlyDisplay(true);
122    
123            return dataField;
124        }
125    
126        private ComponentBase initializeComponentBase(ComponentBase componentBase) {
127            List<String> additionalComponentsToRefresh = new ArrayList<String>();
128            additionalComponentsToRefresh.add("A");
129            additionalComponentsToRefresh.add("B");
130            additionalComponentsToRefresh.add("C");
131            componentBase.setAdditionalComponentsToRefresh(additionalComponentsToRefresh);
132    
133            List<String> additionalCssClasses = new ArrayList<String>();
134            additionalCssClasses.add("Class1");
135            additionalCssClasses.add("Class2");
136            additionalCssClasses.add("Class3");
137            componentBase.setAdditionalCssClasses(additionalCssClasses);
138    
139            componentBase.setAlign("right");
140    
141            List<String> cellCssClasses = new ArrayList<String>();
142            cellCssClasses.add("CellClass1");
143            cellCssClasses.add("CellClass2");
144            cellCssClasses.add("CellClass3");
145            componentBase.setWrapperCssClasses(cellCssClasses);
146    
147            componentBase.setWrapperStyle("Style1");
148            componentBase.setCellWidth("20px");
149            componentBase.setColSpan(2);
150            componentBase.setConditionalRefresh("Refresh");
151    
152            List<String> cssClasses = new ArrayList<String>();
153            cssClasses.add("CssClass1");
154            cssClasses.add("CssClass2");
155            cssClasses.add("CssClass3");
156            componentBase.setCssClasses(cssClasses);
157    
158            Map<String, String> dataAttributes = new HashMap<String, String>();
159            dataAttributes.put("One", "A");
160            dataAttributes.put("Two", "B");
161            dataAttributes.put("Three", "C");
162            componentBase.setDataAttributes(dataAttributes);
163    
164            componentBase.setFinalizeMethodToCall("methodA");
165            componentBase.setMethodToCallOnRefresh("methodB");
166            componentBase.setOnBlurScript("onblurscript");
167            componentBase.setOnChangeScript("onchangescript");
168            componentBase.setOnClickScript("onclickscript");
169            componentBase.setOnCloseScript("onclosescript");
170            componentBase.setOnDblClickScript("ondblclickscript");
171            componentBase.setOnDocumentReadyScript("ondocreadyscript");
172            componentBase.setOnFocusScript("onfocusscript");
173            componentBase.setOnKeyDownScript("onkeydownscript");
174            componentBase.setOnKeyPressScript("onkeypressscript");
175            componentBase.setOnKeyUpScript("onkeyupscript");
176            componentBase.setOnLoadScript("onloadscript");
177            componentBase.setOnMouseDownScript("onmousedownscript");
178            componentBase.setOnMouseMoveScript("onmousemovescript");
179            componentBase.setOnMouseOutScript("onmouseoutscript");
180            componentBase.setOnMouseOverScript("onmouseoverscript");
181            componentBase.setOnMouseUpScript("onmouseupscript");
182            componentBase.setOnSubmitScript("onsubmitscript");
183            componentBase.setOnUnloadScript("onunloadscript");
184            componentBase.setOrder(5);
185            componentBase.setPostRenderContent("PostRenderContent");
186            componentBase.setPreRenderContent("PreRenderContent");
187            componentBase.setProgressiveRender("ProgressiveRender");
188            componentBase.setReadOnly(false);
189            componentBase.setRefreshedByAction(false);
190            componentBase.setRefreshTimer(12);
191    
192            List<String> refreshWhenChangedPropertyNames = new ArrayList<String>();
193            refreshWhenChangedPropertyNames.add("property1");
194            refreshWhenChangedPropertyNames.add("property2");
195            refreshWhenChangedPropertyNames.add("property3");
196            componentBase.setRefreshWhenChangedPropertyNames(refreshWhenChangedPropertyNames);
197    
198            componentBase.setRenderedHtmlOutput("<output>");
199            componentBase.setRowSpan(3);
200            componentBase.setStyle("slick");
201            componentBase.setTemplate("TemplateA");
202            componentBase.setTemplateName("TemplateName");
203    
204            Map<String, String> templateOptions = new HashMap<String, String>();
205            templateOptions.put("Option1", "Value1");
206            templateOptions.put("Option1", "Value2");
207            templateOptions.put("Option1", "Value3");
208            componentBase.setTemplateOptions(templateOptions);
209    
210            componentBase.setTemplateOptionsJSString("OptionsJS");
211            componentBase.setTitle("Title");
212            componentBase.setValign("middle");
213            componentBase.setWidth("30px");
214    
215            return componentBase;
216        }
217    
218        // End of Initialization methods
219    
220        /**
221         * test that {@link ComponentUtils#updateIdWithSuffix} works ok
222         */
223        @Test
224        public void testUpdateIdWithSuffix() {
225            ComponentUtils.updateIdWithSuffix(component, null);
226            assertTrue(component.getId().equalsIgnoreCase(componentId));
227    
228            String suffix = "_field";
229            ComponentUtils.updateIdWithSuffix(component, suffix);
230            assertTrue(component.getId().equalsIgnoreCase(componentId + suffix));
231        }
232    
233        @Test
234        /**
235         * test {@link ComponentUtils#copyUsingCloning} using a FieldBase object
236         */
237        public void testCopyUsingCloningWithFieldBaseSucceeds() {
238            FieldBase fieldBaseOriginal = initializeFieldBase();
239            FieldBase fieldBaseCopy = copy(fieldBaseOriginal);
240    
241            assertTrue(ComponentCopyPropertiesMatch(fieldBaseOriginal, fieldBaseCopy));
242            assertTrue(fieldBaseOriginal.getShortLabel().equals(fieldBaseCopy.getShortLabel()));
243        }
244    
245        public static <T extends Component> T copy(T component) {
246            return component.copy();
247        }
248    
249        @Test
250        /**
251         * test {@link ComponentUtils#copyUsingCloning} using a DataField object
252         */
253        public void testCopyUsingCloningWithDataFieldSucceeds() {
254            DataField dataFieldOriginal = initializeDataField();
255    
256            DataField dataFieldCopy = copy(dataFieldOriginal);
257            assertTrue(ComponentCopyPropertiesMatch(dataFieldOriginal, dataFieldCopy));
258        }
259    
260        /**
261         * test {@link ComponentUtils#copyUsingCloning} using a CollectionGroup object
262         */
263        @Test
264        public void testCopyUsingCloningWithSimpleCollectionGroupSucceeds() {
265            CollectionGroup collectionGroupOriginal = initializeCollectionGroup();
266            CollectionGroup collectionGroupCopy = copy(collectionGroupOriginal);
267    
268            assertTrue(ComponentCopyPropertiesMatch(collectionGroupOriginal, collectionGroupCopy));
269    
270            for (int i = 0; i < collectionGroupOriginal.getAddLineItems().size(); i++) {
271                assertTrue(ComponentCopyPropertiesMatch((ComponentBase) collectionGroupOriginal.getAddLineItems().get(i).unwrap(),
272                        (ComponentBase) collectionGroupCopy.getAddLineItems().get(i).unwrap()));
273            }
274    
275            for (int i = 0; i < collectionGroupOriginal.getAddLineActions().size(); i++) {
276                assertTrue(ComponentCopyPropertiesMatch(collectionGroupOriginal.getAddLineActions().get(i),
277                        collectionGroupCopy.getAddLineActions().get(i)));
278            }
279        }
280    
281        private boolean ComponentCopyPropertiesMatch(Component originalComponent, Component copiedComponent) {
282            boolean result = true;
283    
284            List<String> missingComponentsToRefresh = originalComponent.getAdditionalComponentsToRefresh();
285            if (missingComponentsToRefresh != null) {
286                missingComponentsToRefresh = new ArrayList<String>(missingComponentsToRefresh);
287                missingComponentsToRefresh.removeAll(copiedComponent.getAdditionalComponentsToRefresh());
288                if (!missingComponentsToRefresh.isEmpty()) {
289                    result = false;
290                }
291            }
292    
293            List<String> missingAdditionalCssClasses = new ArrayList<String>(originalComponent.getAdditionalCssClasses());
294            missingAdditionalCssClasses.removeAll(copiedComponent.getAdditionalCssClasses());
295            if (!missingAdditionalCssClasses.isEmpty()) {
296                result = false;
297            }
298    
299            if (!originalComponent.getAlign().equals(copiedComponent.getAlign())) {
300                result = false;
301            }
302    
303            List<String> missingCellCssClasses = originalComponent.getWrapperCssClasses();
304            if (missingCellCssClasses != null) {
305                missingCellCssClasses.removeAll(copiedComponent.getWrapperCssClasses());
306                if (!missingCellCssClasses.isEmpty()) {
307                    result = false;
308                }
309            }
310    
311            if (!originalComponent.getWrapperStyle().equals(copiedComponent.getWrapperStyle())) {
312                result = false;
313            }
314            if (!originalComponent.getCellWidth().equals(copiedComponent.getCellWidth())) {
315                result = false;
316            }
317            if (originalComponent.getColSpan() != copiedComponent.getColSpan()) {
318                result = false;
319            }
320            if (!originalComponent.getConditionalRefresh().equals(copiedComponent.getConditionalRefresh())) {
321                result = false;
322            }
323    
324            List<String> missingCssClasses = new ArrayList<String>(originalComponent.getCssClasses());
325            missingCssClasses.removeAll(copiedComponent.getCssClasses());
326            if (!missingCssClasses.isEmpty()) {
327                result = false;
328            }
329    
330            Map<String, String> origDataAttributes = originalComponent.getDataAttributes();
331            if (origDataAttributes != null) {
332                Set<String> dataAttributes = new HashSet<String>(origDataAttributes.values());
333                dataAttributes.removeAll(copiedComponent.getDataAttributes().values());
334                if (!dataAttributes.isEmpty()) {
335                    result = false;
336                }
337            }
338    
339            if (!originalComponent.getFinalizeMethodToCall().equals(copiedComponent.getFinalizeMethodToCall())) {
340                result = false;
341            }
342            if (originalComponent instanceof ComponentBase &&  copiedComponent instanceof ComponentBase){
343                if (! (((ComponentBase)originalComponent).getMethodToCallOnRefresh().equals(((ComponentBase)copiedComponent).getMethodToCallOnRefresh()))) {
344                    result = false;
345                }
346            } else {
347                result = false;
348            }
349            if (!originalComponent.getOnBlurScript().equals(copiedComponent.getOnBlurScript())) {
350                result = false;
351            }
352            if (!originalComponent.getOnChangeScript().equals(copiedComponent.getOnChangeScript())) {
353                result = false;
354            }
355            if (!originalComponent.getOnClickScript().equals(copiedComponent.getOnClickScript())) {
356                result = false;
357            }
358            if (!originalComponent.getOnCloseScript().equals(copiedComponent.getOnCloseScript())) {
359                result = false;
360            }
361            if (!originalComponent.getOnDblClickScript().equals(copiedComponent.getOnDblClickScript())) {
362                result = false;
363            }
364            if (!originalComponent.getOnDocumentReadyScript().equals(copiedComponent.getOnDocumentReadyScript())) {
365                result = false;
366            }
367            if (!originalComponent.getOnFocusScript().equals(copiedComponent.getOnFocusScript())) {
368                result = false;
369            }
370            if (!originalComponent.getOnKeyDownScript().equals(copiedComponent.getOnKeyDownScript())) {
371                result = false;
372            }
373            if (!originalComponent.getOnKeyPressScript().equals(copiedComponent.getOnKeyPressScript())) {
374                result = false;
375            }
376            if (!originalComponent.getOnKeyUpScript().equals(copiedComponent.getOnKeyUpScript())) {
377                result = false;
378            }
379            if (!originalComponent.getOnLoadScript().equals(copiedComponent.getOnLoadScript())) {
380                result = false;
381            }
382            if (!originalComponent.getOnMouseDownScript().equals(copiedComponent.getOnMouseDownScript())) {
383                result = false;
384            }
385            if (!originalComponent.getOnMouseMoveScript().equals(copiedComponent.getOnMouseMoveScript())) {
386                result = false;
387            }
388            if (!originalComponent.getOnMouseOutScript().equals(copiedComponent.getOnMouseOutScript())) {
389                result = false;
390            }
391            if (!originalComponent.getOnMouseOverScript().equals(copiedComponent.getOnMouseOverScript())) {
392                result = false;
393            }
394            if (!originalComponent.getOnMouseUpScript().equals(copiedComponent.getOnMouseUpScript())) {
395                result = false;
396            }
397            if (!originalComponent.getOnSubmitScript().equals(copiedComponent.getOnSubmitScript())) {
398                result = false;
399            }
400            if (!originalComponent.getOnUnloadScript().equals(copiedComponent.getOnUnloadScript())) {
401                result = false;
402            }
403            if (originalComponent.getOrder() != copiedComponent.getOrder()) {
404                result = false;
405            }
406            if (!originalComponent.getPostRenderContent().equals(copiedComponent.getPostRenderContent())) {
407                result = false;
408            }
409            if (!originalComponent.getPreRenderContent().equals(copiedComponent.getPreRenderContent())) {
410                result = false;
411            }
412            if (!originalComponent.getProgressiveRender().equals(copiedComponent.getProgressiveRender())) {
413                result = false;
414            }
415            if (originalComponent.getRequired() != copiedComponent.getRequired()) {
416                result = false;
417            }
418            if (originalComponent.getRefreshTimer() != copiedComponent.getRefreshTimer()) {
419                result = false;
420            }
421    
422            List<String> missingRefreshWhenChangedPropertyNames = originalComponent.getRefreshWhenChangedPropertyNames();
423            if (missingRefreshWhenChangedPropertyNames != null) {
424                missingRefreshWhenChangedPropertyNames = new ArrayList<String>(missingRefreshWhenChangedPropertyNames);
425                missingRefreshWhenChangedPropertyNames.removeAll(copiedComponent.getRefreshWhenChangedPropertyNames());
426                if (!missingRefreshWhenChangedPropertyNames.isEmpty()) {
427                    result = false;
428                }
429            }
430    
431            if (!originalComponent.getRenderedHtmlOutput().equals(copiedComponent.getRenderedHtmlOutput())) {
432                result = false;
433            }
434            if (originalComponent.getRowSpan() != copiedComponent.getRowSpan()) {
435                result = false;
436            }
437            if (!originalComponent.getStyle().equals(copiedComponent.getStyle())) {
438                result = false;
439            }
440            if (!originalComponent.getTemplate().equals(copiedComponent.getTemplate())) {
441                result = false;
442            }
443            if (!originalComponent.getTemplateName().equals(copiedComponent.getTemplateName())) {
444                result = false;
445            }
446    
447            Map<String, String> origTemplateOptions = originalComponent.getTemplateOptions();
448            if (origTemplateOptions != null) {
449                Set<String> templateOptions = new HashSet<String>(origTemplateOptions.values());
450                Map<String, String> copiedTemplateOptions = copiedComponent.getTemplateOptions();
451    
452                if (copiedTemplateOptions != null) {
453                    templateOptions.removeAll(copiedTemplateOptions.values());
454                }
455    
456                if (!templateOptions.isEmpty()) {
457                    result = false;
458                }
459            }
460    
461            if (!originalComponent.getTemplateOptionsJSString().equals(copiedComponent.getTemplateOptionsJSString())) {
462                result = false;
463            }
464            if (!originalComponent.getTitle().equals(copiedComponent.getTitle())) {
465                result = false;
466            }
467            if (!originalComponent.getValign().equals(copiedComponent.getValign())) {
468                result = false;
469            }
470            if (!originalComponent.getWidth().equals(copiedComponent.getWidth())) {
471                result = false;
472            }
473    
474            return result;
475        }
476    
477        /**
478         * Test {@link ComponentUtils#cleanContextDeap} using a BreadcrumbItem object
479         */
480        @Test
481        public void testCleanContextDeap() {
482            Map<String, Object> context = new HashMap<String, Object>();
483            context.put("contextkey", "value");
484            context.put("contextkey2", "value2");
485    
486            BreadcrumbItem breadcrumbItem = new BreadcrumbItem();
487            breadcrumbItem.setContext(context);
488    
489            InputField inputField = new InputFieldBase();
490            inputField.setContext(context);
491    
492            Label fieldLabel = new Label();
493            fieldLabel.setContext(context);
494    
495            Tooltip labelTootlip = new Tooltip();
496            labelTootlip.setContext(context);
497            fieldLabel.setToolTip(labelTootlip);
498    
499            inputField.setFieldLabel(fieldLabel);
500    
501            breadcrumbItem.setSiblingBreadcrumbComponent(inputField);
502    
503            Tooltip tooltip = new Tooltip();
504            tooltip.setContext(context);
505    
506            breadcrumbItem.setToolTip(tooltip);
507    
508            ComponentUtils.cleanContextDeap(breadcrumbItem);
509    
510            assertEquals(0, breadcrumbItem.getContext().size());
511            assertEquals(0, inputField.getContext().size());
512            assertEquals(0, fieldLabel.getContext().size());
513            assertEquals(0, labelTootlip.getContext().size());
514            assertEquals(0, tooltip.getContext().size());
515        }
516    
517        @Ignore // Ignored for now, this is a proof of concept for using reflection to test copying
518        @Test
519        /**
520         * test {@link ComponentUtils#copyUsingCloning} using a DataField object
521         */
522        public void testCopyUsingCloningWithDataTableSucceeds() {
523            CheckboxControl dataTableOriginal = new CheckboxControl();
524    
525            initializeClass(dataTableOriginal);
526    
527            CheckboxControl dataTableCopy = copy(dataTableOriginal);
528    
529            assertTrue(propertiesMatch(dataTableOriginal, dataTableCopy));
530        }
531    
532        private void initializeClass(Object originalObject) {
533            Class originalClass = originalObject.getClass();
534            long index = 0L;
535    
536            for (Field field : originalClass.getDeclaredFields()) {
537                if (field.isAnnotationPresent(ReferenceCopy.class)) {
538                    continue;
539                }
540    
541                try {
542                    if (field.getType().equals(String.class)) {
543                        field.setAccessible(true);
544                        field.set(originalObject, "Test" + index);
545                    }
546    
547                    if (field.getType().equals(long.class)) {
548                        field.setAccessible(true);
549                        field.setLong(originalObject, index);
550                    }
551    
552                    if (field.getType().equals(int.class)) {
553                        field.setAccessible(true);
554                        field.setInt(originalObject, (int) index);
555                    }
556    
557                    if (field.getType().equals(List.class)) {
558                        field.setAccessible(true);
559                        ParameterizedType myListType = ((ParameterizedType) field.getGenericType());
560                        //myListType.getActualTypeArguments()[0].name;    // string value that looks like this: interface org.kuali.rice.krad.uif.component.Component
561                        int something = 2;
562                        //Class listClass = Class.forName(myListType.getActualTypeArguments()[0]);
563                        Object[] objects = new Object[1];
564                        objects[0] = new FieldBase();
565                        List<?> fieldList = Arrays.asList((Object[]) objects);
566                        field.set(originalObject, fieldList);
567                        List<?> retrievedList = (List<?>) field.get(originalObject);
568                        int somethingElse = 3;
569    
570                        //ArrayList<?> arrayList = new ArrayList<?>();
571    
572                    }
573                } catch (IllegalAccessException e) {
574                    // do nothing
575                }
576    
577                ++index;
578            }
579        }
580    
581        private boolean propertiesMatch(Object originalObject, Object copiedObject) {
582            Class originalClass = originalObject.getClass();
583            Class copiedClass = copiedObject.getClass();
584    
585            for (Field field : originalClass.getDeclaredFields()) {
586                if (field.isAnnotationPresent(ReferenceCopy.class)) {
587                    continue;
588                }
589    
590                if (field.getType().equals(String.class)) {
591                    boolean propertiesMatch = stringPropertiesMatch(originalObject, copiedObject, copiedClass, field);
592                    if (!propertiesMatch) {
593                        return false;
594                    }
595                }
596    
597                if (field.getType().equals(long.class)) {
598                    boolean propertiesMatch = longPropertiesMatch(originalObject, copiedObject, copiedClass, field);
599                    if (!propertiesMatch) {
600                        return false;
601                    }
602                }
603    
604                if (field.getType().equals(int.class)) {
605                    boolean propertiesMatch = intPropertiesMatch(originalObject, copiedObject, copiedClass, field);
606                    if (!propertiesMatch) {
607                        return false;
608                    }
609                }
610            }
611    
612            return true;
613        }
614    
615        private boolean intPropertiesMatch(Object originalObject, Object copiedObject, Class copiedClass, Field field) {
616            try {
617                field.setAccessible(true);
618                int oritinalInt = field.getInt(originalObject);
619                Field copiedClassField = copiedClass.getDeclaredField(field.getName());
620                copiedClassField.setAccessible(true);
621                int copiedInt = copiedClassField.getInt(copiedObject);
622    
623                return oritinalInt == copiedInt;
624            } catch (IllegalAccessException e) {
625                return false;
626            } catch (NoSuchFieldException e) {
627                return false;
628            }
629        }
630    
631        private boolean longPropertiesMatch(Object originalObject, Object copiedObject, Class copiedClass, Field field) {
632            try {
633                field.setAccessible(true);
634                Long originalLong = field.getLong(originalObject);
635                Field copiedClassField = copiedClass.getDeclaredField(field.getName());
636                copiedClassField.setAccessible(true);
637                Long copiedLong = copiedClassField.getLong(copiedObject);
638    
639                return originalLong.equals(copiedLong);
640            } catch (IllegalAccessException e) {
641                return false;
642            } catch (NoSuchFieldException e) {
643                return false;
644            }
645        }
646    
647        private boolean stringPropertiesMatch(Object originalObject, Object copiedObject, Class copiedClass, Field field) {
648            try {
649                field.setAccessible(true);
650                String originalString = (String) field.get(originalObject);
651                String copiedString = new String();
652                Field copiedClassField = copiedClass.getDeclaredField(field.getName());
653                copiedClassField.setAccessible(true);
654                copiedString = (String) copiedClassField.get(copiedObject);
655    
656                return originalString.equals(copiedString);
657            } catch (IllegalAccessException e) {
658                return false;
659            } catch (NoSuchFieldException e) {
660                return false;
661            }
662        }
663    }