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