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
018/**
019 * A single attribute definition in the DataDictionary, which contains information relating to the display, validation, and general
020 * maintenance of a specific attribute of an entry.
021 * 
022 * 
023 */
024import org.apache.commons.lang.StringUtils;
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.kuali.rice.krad.datadictionary.control.ControlDefinition;
028import org.kuali.rice.krad.datadictionary.exception.CompletionException;
029import org.kuali.rice.krad.datadictionary.validation.ValidationPattern;
030import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
031
032/**
033 * A single attribute definition in the DataDictionary, which contains
034 * information relating to the display, validation, and general maintenance of a
035 * specific attribute of an entry.
036 * 
037 * 
038 */
039public class ExternalizableAttributeDefinitionProxy extends AttributeDefinition {
040        private static final long serialVersionUID = -3204870440281417429L;
041
042        // logger
043        private static Log LOG = LogFactory
044                        .getLog(ExternalizableAttributeDefinitionProxy.class);
045
046        private String sourceExternalizableBusinessObjectInterface;
047        private String sourceAttributeName;
048        private AttributeDefinition delegate;
049
050        /**
051         * Constructs an AttributeReferenceDefinition
052         */
053        public ExternalizableAttributeDefinitionProxy() {
054                LOG.debug("creating new ExternalizableAttributeDefinitionProxy");
055        }
056
057        public void setSourceExternalizableBusinessObjectInterface(
058                        String sourceClassName) {
059                if (StringUtils.isBlank(sourceClassName)) {
060                        throw new IllegalArgumentException(
061                                        "invalid (blank) sourceClassName");
062                }
063
064                this.sourceExternalizableBusinessObjectInterface = sourceClassName;
065        }
066
067        public String getSourceExternalizableBusinessObjectInterface() {
068                return this.sourceExternalizableBusinessObjectInterface;
069        }
070
071        public void setSourceAttributeName(String sourceAttributeName) {
072                if (StringUtils.isBlank(sourceAttributeName)) {
073                        throw new IllegalArgumentException(
074                                        "invalid (blank) sourceAttributeName");
075                }
076
077                this.sourceAttributeName = sourceAttributeName;
078        }
079
080        public String getSourceAttributeName() {
081                return this.sourceAttributeName;
082        }
083
084        /**
085         * @return AttributeDefinition acting as delegate for this
086         *         AttributeReferenceDefinition
087         */
088        AttributeDefinition getDelegate() {
089                BusinessObjectEntry delegateEntry = null;
090                if ( delegate == null ) {
091                        try {
092                                delegateEntry = KRADServiceLocatorWeb
093                                                .getKualiModuleService()
094                                                .getResponsibleModuleService(
095                                                                Class
096                                                                                .forName(getSourceExternalizableBusinessObjectInterface()))
097                                                .getExternalizableBusinessObjectDictionaryEntry(
098                                                                Class
099                                                                                .forName(getSourceExternalizableBusinessObjectInterface()));
100                        } catch (ClassNotFoundException e) {
101                                LOG.error("Unable to get delegate entry for sourceExternalizableBusinessObjectInterface",e);
102                        }
103        
104                        if (delegateEntry == null) {
105                                throw new CompletionException(
106                                                "no BusinessObjectEntry exists for sourceClassName '"
107                                                                + getSourceExternalizableBusinessObjectInterface()
108                                                                + "'");
109                        }
110                        delegate = delegateEntry
111                                        .getAttributeDefinition(getSourceAttributeName());
112                        if (delegate == null) {
113                                throw new CompletionException(
114                                                "no AttributeDefnintion exists for sourceAttributeName '"
115                                                                + getSourceExternalizableBusinessObjectInterface()
116                                                                + "." + getSourceAttributeName() + "'");
117                        }
118                }
119
120                return delegate;
121        }
122
123        /**
124         * Sets the given AttributeDefinition as the delegate for this instance
125         * 
126         * @param delegate
127         */
128        void setDelegate(AttributeDefinition delegate) {
129                if (delegate == null) {
130                        throw new IllegalArgumentException("invalid (null) delegate");
131                }
132
133                this.delegate = delegate;
134        }
135
136        /**
137         * If forceUppercase wasn't set on this instance, use the value from its
138         * delegate.
139         * 
140         * @see org.kuali.core.datadictionary.AttributeDefinition#getForceUppercase()
141         */
142        public Boolean getForceUppercase() {
143                Boolean value = super.getForceUppercase();
144                if (value == null) {
145                        value = getDelegate().getForceUppercase();
146                }
147
148                return value;
149        }
150
151        /**
152         * If name wasn't set on this instance, use the value from its delegate.
153         * 
154         * @see org.kuali.core.datadictionary.AttributeDefinition#getName()
155         */
156        public String getName() {
157                String name = super.getName();
158                if (name == null) {
159                        name = getDelegate().getName();
160                }
161
162                return name;
163        }
164
165        /**
166         * If label wasn't set on this instance, use the value from its delegate.
167         * 
168         * @see org.kuali.core.datadictionary.AttributeDefinition#getLabel()
169         */
170        public String getLabel() {
171                String label = super.getLabel();
172
173                if (label == null) {
174                        label = getDelegate().getLabel();
175                }
176
177                return label;
178        }
179
180        /**
181         * If shortlabel wasn't set on this instance, use the value from its
182         * delegate.
183         * 
184         * @see org.kuali.core.datadictionary.AttributeDefinition#getShortLabel()
185         */
186        public String getShortLabel() {
187                String shortLabel = super.getDirectShortLabel();
188                if (shortLabel == null) {
189                        shortLabel = getDelegate().getShortLabel();
190                }
191
192                return shortLabel;
193        }
194
195        /**
196         * If maxLength wasn't set on this instance, use the value from its
197         * delegate.
198         * 
199         * @see org.kuali.core.datadictionary.AttributeDefinition#getMaxLength()
200         */
201        public Integer getMaxLength() {
202                Integer maxLength = super.getMaxLength();
203                if (maxLength == null) {
204                        maxLength = getDelegate().getMaxLength();
205                }
206
207                return maxLength;
208        }
209
210        /**
211         * @return true if a validationPattern is available, directly or indirectly
212         * 
213         * @see org.kuali.core.datadictionary.AttributeDefinition#hasValidationPattern()
214         */
215        public boolean hasValidationPattern() {
216                return (getValidationPattern() != null);
217        }
218
219        /**
220         * If validationPattern wasn't set on this instance, use the value from its
221         * delegate.
222         * 
223         * @see org.kuali.core.datadictionary.AttributeDefinition#getValidationPattern()
224         */
225        public ValidationPattern getValidationPattern() {
226                ValidationPattern validationPattern = super.getValidationPattern();
227                if (validationPattern == null) {
228                        validationPattern = getDelegate().getValidationPattern();
229                }
230
231                return validationPattern;
232        }
233
234        /**
235         * If required wasn't set on this instance, use the value from its delegate.
236         * 
237         * @see org.kuali.core.datadictionary.AttributeDefinition#isRequired()
238         */
239        public Boolean isRequired() {
240                Boolean required = super.isRequired();
241                if (required == null) {
242                        required = getDelegate().isRequired();
243                }
244
245                return required;
246        }
247
248        /**
249         * If control wasn't set on this instance, use the value from its delegate.
250         * 
251         * @see org.kuali.core.datadictionary.AttributeDefinition#getControl()
252         */
253        public ControlDefinition getControl() {
254                ControlDefinition control = super.getControl();
255                if (control == null) {
256                        control = getDelegate().getControl();
257                }
258
259                return control;
260        }
261
262        /**
263         * If summary wasn't set on this instance, use the value from its delegate.
264         * 
265         * @see org.kuali.core.datadictionary.AttributeDefinition#getSummary()
266         */
267        public String getSummary() {
268                String summary = super.getSummary();
269                if (summary == null) {
270                        summary = getDelegate().getSummary();
271                }
272
273                return summary;
274        }
275
276        /**
277         * If description wasn't set on this instance, use the value from its
278         * delegate.
279         * 
280         * @see org.kuali.core.datadictionary.AttributeDefinition#getDescription()
281         */
282        public String getDescription() {
283                String description = super.getDescription();
284                if (description == null) {
285                        description = getDelegate().getDescription();
286                }
287
288                return description;
289        }
290
291        /**
292         * @return true if a formatterClass is available, directly or indirectly
293         * 
294         * @see org.kuali.core.datadictionary.AttributeDefinition#hasFormatterClass()
295         */
296        public boolean hasFormatterClass() {
297                return (getFormatterClass() != null);
298        }
299
300        /**
301         * If a formatterClass wasn't set for this instance, use the value from its
302         * delegate.
303         * 
304         * @see org.kuali.core.datadictionary.AttributeDefinition#getFormatterClass()
305         */
306        public String getFormatterClass() {
307                String formatterClass = super.getFormatterClass();
308                if (formatterClass == null) {
309                        formatterClass = getDelegate().getFormatterClass();
310                }
311
312                return formatterClass;
313        }
314
315        /**
316         * @see org.kuali.core.datadictionary.AttributeDefinition#getDisplayLabelAttribute()
317         */
318        @Override
319        public String getDisplayLabelAttribute() {
320                String displayLabelAttribute = super.getDisplayLabelAttribute();
321                if (StringUtils.isBlank(displayLabelAttribute)) {
322                        displayLabelAttribute = getDelegate().getDisplayLabelAttribute();
323                }
324                return displayLabelAttribute;
325        }
326
327        /**
328         * Validate the fields associated with locating the delegate. Other
329         * validation must be deferred until the delegate class has been assigned.
330         * 
331         * @see org.kuali.core.datadictionary.DataDictionaryEntry#completeValidation()
332         */
333        @Override
334        public void completeValidation(Class rootObjectClass, Class otherObjectClass) {
335                if (StringUtils.isBlank(sourceExternalizableBusinessObjectInterface)) {
336                        throw new IllegalArgumentException(
337                                        "invalid (blank) sourceClassName for attribute '"
338                                                        + rootObjectClass.getName() + "." + getName() + "'");
339                }
340                if (StringUtils.isBlank(sourceAttributeName)) {
341                        throw new IllegalArgumentException(
342                                        "invalid (blank) sourceAttributeName for attribute '"
343                                                        + rootObjectClass.getName() + "." + getName() + "'");
344                }
345                if ( DataDictionary.validateEBOs ) {
346                        getDelegate(); // forces validation
347                        super.completeValidation(rootObjectClass, otherObjectClass);
348                }
349        }
350
351        /**
352         * @see java.lang.Object#toString()
353         */
354        public String toString() {
355                String name = super.getName();
356
357                // workaround for the mysterious,
358                // still-unreproducible-on-my-machine, null delegate exception on
359                // Tomcat startup
360                if ((name == null) && (getDelegate() != null)) {
361                        name = getDelegate().getName();
362                }
363                return "AttributeReferenceDefinition for attribute " + name;
364        }
365}