1   /*
2    * Copyright 2003 - 2013 The eFaps Team
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Revision:        $Rev$
17   * Last Changed:    $Date$
18   * Last Changed By: $Author$
19   */
20  
21  package org.efaps.admin.datamodel.ui;
22  
23  import java.util.List;
24  
25  import org.efaps.admin.datamodel.Attribute;
26  import org.efaps.admin.event.EventDefinition;
27  import org.efaps.admin.event.EventType;
28  import org.efaps.admin.event.Parameter;
29  import org.efaps.admin.event.Parameter.ParameterValues;
30  import org.efaps.admin.event.Return;
31  import org.efaps.admin.event.Return.ReturnValues;
32  import org.efaps.admin.ui.AbstractCommand;
33  import org.efaps.admin.ui.AbstractUserInterfaceObject.TargetMode;
34  import org.efaps.admin.ui.field.Field;
35  import org.efaps.admin.ui.field.Field.Display;
36  import org.efaps.db.Context;
37  import org.efaps.db.Instance;
38  import org.efaps.util.EFapsException;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  /**
43   * This class is used as the value for a field. It can be used to get the for
44   * the user interface necessary strings etc.
45   *
46   * @author The eFaps Team
47   * @version $Id$
48   */
49  public class FieldValue
50      implements Comparable<Object>, IUIValue
51  {
52      /**
53       * Logger for this class.
54       */
55      private static final Logger LOG = LoggerFactory.getLogger(FieldValue.class);
56  
57      /**
58       * The instance variable stores the class to represent this form value.
59       *
60       * @see #getClassUI
61       */
62      private final Attribute attribute;
63  
64      /**
65       * The variable stores the field instance for this value.
66       *
67       * @see #getInstance
68       */
69      private final Instance instance;
70  
71      /**
72        *  Instance for which this field is called (not the same
73        *  as the instance of the field...).
74        */
75      private final Instance callInstance;
76  
77      /**
78       * List of instances that where received from a query while
79       * receiving the {@link #instance}. e.g. used for a table to pass
80       * the instances of all rows so that for column the amount of
81       * queries necessary can be reduced;
82       */
83      private final List<Instance> requestInstances;
84  
85  
86      /**
87       * The instance variable stores the field for this value.
88       *
89       * @see #getFieldDef
90       */
91      private final Field field;
92  
93      /**
94       * Stores the UIInterface belonging to this fieldvalue.
95       */
96      private final UIInterface ui;
97  
98      /**
99       * The instance variable stores the value for this form value.
100      *
101      * @see #getValue
102      */
103     private Object value;
104 
105     /**
106      * Targetmode for this fieldvalue.
107      */
108     private TargetMode targetMode;
109 
110     /**
111      * Stores he display mode for this field.
112      */
113     private Display display;
114 
115     /**
116      * Object that will be passed to the event as CLASS.
117      */
118     private Object classObject;
119 
120     /**
121      * Command that opened the form this field belongs to.
122      */
123     private AbstractCommand cmd;
124 
125     /**
126      * Constructor used to evaluate the value from the database by using one of
127      * the getter methods for html. Used normally on create when no instances
128      * are given.
129      *
130      * @param _field            field this value belongs to
131      * @param _attr             attribute the value belongs to
132      */
133     public FieldValue(final Field _field,
134                       final Attribute _attr)
135     {
136         this(_field, _attr, null, null, null);
137     }
138 
139     /**
140      * Constructor used to evaluate the value from the database by using one of
141      * the getter methods for html.
142      *
143      * @param _field            field this value belongs to
144      * @param _attr             attribute the value belongs to
145      * @param _value            value of the FieldValue
146      * @param _valueInstance    Instance the Value belongs to
147      * @param _callInstance     Instance that called Value for edit, view etc.
148      */
149     public FieldValue(final Field _field,
150                       final Attribute _attr,
151                       final Object _value,
152                       final Instance _valueInstance,
153                       final Instance _callInstance)
154     {
155         this(_field, _attr, _value, _valueInstance, _callInstance, null);
156     }
157 
158     /**
159      * Constructor used to evaluate the value from the database by using one of
160      * the getter methods for html.
161      *
162      * @param _field            field this value belongs to
163      * @param _attr             attribute the value belongs to
164      * @param _value            value of the FieldValue
165      * @param _valueInstance    Instance the Value belongs to
166      * @param _callInstance     Instance that called Value for edit, view etc.
167      * @param _requestInstances Instance called inthe same request
168      */
169     public FieldValue(final Field _field,
170                       final Attribute _attr,
171                       final Object _value,
172                       final Instance _valueInstance,
173                       final Instance _callInstance,
174                       final List<Instance> _requestInstances)
175     {
176         this(_field, _attr, _value, _valueInstance, _callInstance, _requestInstances, null);
177     }
178 
179     /**
180      * Constructor used to evaluate the value from the database by using one of
181      * the getter methods for html.
182      *
183      * @param _field            field this value belongs to
184      * @param _attr             attribute the value belongs to
185      * @param _value            value of the FieldValue
186      * @param _valueInstance    Instance the Value belongs to
187      * @param _callInstance     Instance that called Value for edit, view etc.
188      * @param _requestInstances Instance called in the same request
189      * @param _classObject      Object that will be passed to the esjp
190      */
191     public FieldValue(final Field _field,
192                       final Attribute _attr,
193                       final Object _value,
194                       final Instance _valueInstance,
195                       final Instance _callInstance,
196                       final List<Instance> _requestInstances,
197                       final Object _classObject)
198     {
199         this(_field, _attr, _value, _valueInstance, _callInstance, _requestInstances, _classObject, null);
200     }
201 
202     /**
203      * Constructor used to evaluate the value from the database by using one of
204      * the getter methods for html.
205      *
206      * @param _field            field this value belongs to
207      * @param _attr             attribute the value belongs to
208      * @param _value            value of the FieldValue
209      * @param _valueInstance    Instance the Value belongs to
210      * @param _callInstance     Instance that called Value for edit, view etc.
211      * @param _requestInstances Instance called in the same request
212      * @param _classObject      Object that will be passed to the esjp
213      * @param _cmd              Cmd that called the UIObject this field belongs to
214      */
215     //CHECKSTYLE:OFF
216     public FieldValue(final Field _field,
217                       final Attribute _attr,
218                       final Object _value,
219                       final Instance _valueInstance,
220                       final Instance _callInstance,
221                       final List<Instance> _requestInstances,
222                       final Object _classObject,
223                       final AbstractCommand _cmd)
224     {
225     //CHECKSTYLE:ON
226         this.field = _field;
227         this.attribute = _attr;
228         this.value = _value;
229         this.instance = _valueInstance;
230         this.callInstance = _callInstance;
231         this.requestInstances = _requestInstances;
232         this.classObject = _classObject;
233         this.ui = _attr == null
234             ? this.field.getClassUI() == null ? new StringUI()
235             : this.field.getClassUI() : _attr.getAttributeType().getUI();
236         this.cmd = _cmd;
237     }
238 
239 
240     /**
241      * Constructor used in case of comparison.
242      *
243      * @param _field field this value belongs to
244      * @param _ui UIInterface this value belongs to
245      * @param _compareValue value to be compared
246      */
247     public FieldValue(final Field _field,
248                       final UIInterface _ui,
249                       final Object _compareValue)
250     {
251         this.ui = _ui;
252         this.field = _field;
253         this.value = _compareValue;
254         this.instance = null;
255         this.callInstance = null;
256         this.attribute = null;
257         this.requestInstances = null;
258     }
259 
260 
261     /**
262      * Method to get html code for this FieldValue in case of edit.
263      *
264      * @see #executeEvents
265      * @param _mode         target mode
266      * @throws EFapsException on error
267      * @return html code as a String
268      */
269     public String getEditHtml(final TargetMode _mode)
270         throws EFapsException
271     {
272         this.targetMode = _mode;
273         this.display = Display.EDITABLE;
274         String ret = null;
275         ret = executeEvents(EventType.UI_FIELD_VALUE);
276         if (ret == null) {
277             ret = executeEvents(EventType.UI_FIELD_FORMAT);
278             if (ret == null && this.ui != null) {
279                 ret = this.ui.getEditHtml(this);
280             }
281         }
282         return ret;
283     }
284 
285     /**
286      * Method to get html code for this FieldValue in case of view.
287      *
288      * @see #executeEvents
289      * @param _mode         target mode
290      * @throws EFapsException on error
291      * @return html code as a String
292      */
293     public String getReadOnlyHtml(final TargetMode _mode)
294         throws EFapsException
295     {
296         this.targetMode = _mode;
297         this.display = Display.READONLY;
298         String ret = null;
299         ret = executeEvents(EventType.UI_FIELD_VALUE);
300         if (ret == null) {
301             ret = executeEvents(EventType.UI_FIELD_FORMAT);
302             if (ret == null && this.ui != null) {
303                 ret = this.ui.getReadOnlyHtml(this);
304             }
305         }
306         return ret;
307     }
308 
309     /**
310      * Method to get html code for this FieldValue in case of hidden.
311      *
312      * @see #executeEvents
313      * @param _mode         target mode
314      * @throws EFapsException on error
315      * @return html code as a String
316      */
317     public String getHiddenHtml(final TargetMode _mode)
318         throws EFapsException
319     {
320         this.targetMode = _mode;
321         this.display = Display.HIDDEN;
322         String ret = null;
323         ret = executeEvents(EventType.UI_FIELD_VALUE);
324         if (ret == null) {
325             ret = executeEvents(EventType.UI_FIELD_FORMAT);
326             if (ret == null && this.ui != null) {
327                 ret = this.ui.getHiddenHtml(this);
328             }
329         }
330         return ret;
331     }
332 
333     /**
334      * Method to get a plain string for this FieldValue .
335      *
336      * @see #executeEvents
337      * @param _mode         target mode
338      * @throws EFapsException on error
339      * @return plain string
340      * @throws EFapsException
341      */
342     public String getStringValue(final TargetMode _mode)
343         throws EFapsException
344     {
345         this.targetMode = _mode;
346         this.display = Display.NONE;
347         String ret = null;
348         ret = executeEvents(EventType.UI_FIELD_VALUE);
349         if (ret == null) {
350             ret = executeEvents(EventType.UI_FIELD_FORMAT);
351             if (ret == null && this.ui != null) {
352                 ret = this.ui.getStringValue(this);
353             }
354         }
355         return ret;
356     }
357 
358     /**
359      * Executes the field value events for a field.
360      * @param _eventType type of event to be executed
361      * @throws EFapsException on error
362      * @return string from called field value events or <code>null</code> if no
363      *         field value event is defined
364      *
365      */
366     protected String executeEvents(final EventType _eventType)
367         throws EFapsException
368     {
369         String ret = null;
370         if (this.field != null && this.field.hasEvents(_eventType)) {
371 
372             final List<EventDefinition> events = this.field.getEvents(_eventType);
373 
374             final StringBuilder html = new StringBuilder();
375             if (events != null) {
376                 final Parameter parameter = new Parameter();
377                 parameter.put(ParameterValues.ACCESSMODE, this.targetMode);
378                 parameter.put(ParameterValues.UIOBJECT, this);
379                 parameter.put(ParameterValues.CALL_INSTANCE, this.callInstance);
380                 parameter.put(ParameterValues.INSTANCE, this.instance);
381                 parameter.put(ParameterValues.REQUEST_INSTANCES, this.requestInstances);
382                 parameter.put(ParameterValues.CLASS, this.classObject);
383                 parameter.put(ParameterValues.CALL_CMD, this.cmd);
384                 if (parameter.get(ParameterValues.PARAMETERS) == null) {
385                     parameter.put(ParameterValues.PARAMETERS, Context.getThreadContext().getParameters());
386                 }
387                 for (final EventDefinition evenDef : events) {
388                     final Return retu = evenDef.execute(parameter);
389                     if (retu.get(ReturnValues.SNIPLETT) != null) {
390                         html.append(retu.get(ReturnValues.SNIPLETT));
391                     } else if (retu.get(ReturnValues.VALUES) != null) {
392                         this.value = retu.get(ReturnValues.VALUES);
393                     }
394                 }
395             }
396             if (html.length() > 0) {
397                 ret = html.toString();
398             }
399         }
400         return ret;
401     }
402 
403     /**
404      * Method is used to retrieve the value that must be used for comparison.
405      *
406      * @return Object
407      * @throws EFapsException on error
408      */
409     public Object getObject4Compare() throws EFapsException
410     {
411         Object ret = null;
412         if (this.ui != null) {
413             ret = this.ui.getObject4Compare(this);
414         }
415         return ret;
416     }
417 
418     /**
419      * The user interface implementing this attribute is returned. If no
420      * attribute for this field is defined, a <code>null</code> is returned.
421      *
422      * @return class implementing the user interface for given attribute
423      *         instance or <code>null</code> if not attribute is defined
424      * @see #attribute
425      */
426     public UIInterface getClassUI()
427     {
428         return this.ui;
429     }
430 
431     /**
432      * Method to compare this FieldValue to a target FieldValue.
433      *
434      * @param _target field value to compare to
435      * @return 0 if smaller, else -1
436      */
437     @Override
438     public int compareTo(final Object _target)
439     {
440         final FieldValue target = (FieldValue) _target;
441 
442         int ret = 0;
443         if (this.value == null || target.getValue() == null) {
444             if (this.value == null && target.getValue() != null) {
445                 ret = -1;
446             }
447             if (this.value != null && target.getValue() == null) {
448                 ret = 1;
449             }
450         } else {
451             if (getClassUI().getClass().isInstance(target.getClassUI())) {
452                 try {
453                     ret = getClassUI().compare(this, target);
454                 } catch (final EFapsException e) {
455                     FieldValue.LOG.error("Comparing FieldValue to another FieldValue threw an error", e);
456                 }
457             } else {
458                 FieldValue.LOG.error("can't compare this Objects because they don't have the same ClassUI");
459             }
460         }
461         return ret;
462     }
463 
464     /**
465      * This is the getter method for the instance variable {@link #instance}.
466      *
467      * @return value of instance variable {@link #instance}
468      * @see #instance
469      */
470     public Instance getInstance()
471     {
472         return this.instance;
473     }
474 
475     /**
476      * Getter method for the instance variable {@link #callInstance}.
477      *
478      * @return value of instance variable {@link #callInstance}
479      */
480     public Instance getCallInstance()
481     {
482         return this.callInstance;
483     }
484 
485     /**
486      * This is the getter method for the instance variable {@link #value}.
487      *
488      * @return value of instance variable {@link #value}
489      * @see #value
490      */
491     public Object getValue()
492     {
493         return this.value;
494     }
495 
496     /**
497      * Setter method for instance variable {@link #value}.
498      *
499      * @param _value value for instance variable {@link #value}
500      */
501     public void setValue(final Object _value)
502     {
503         this.value = _value;
504     }
505 
506     /**
507      * Getter method for the instance variable {@link #classObject}.
508      *
509      * @return value of instance variable {@link #classObject}
510      */
511     public Object getClassObject()
512     {
513         return this.classObject;
514     }
515 
516     /**
517      * This is the getter method for instance variable {@link #attribute}.
518      *
519      * @return value of instance variable {@link #attribute}
520      * @see #attribute
521      */
522     public Attribute getAttribute()
523     {
524         return this.attribute;
525     }
526 
527     /**
528      * This is the getter method for instance variable {@link #field}.
529      *
530      * @return value of instance variable {@link #field}
531      */
532     public Field getField()
533     {
534         return this.field;
535     }
536 
537     /**
538      * Getter method for instance variable {@link #targetMode}.
539      *
540      * @return value of instance variable {@link #targetMode}
541      */
542     public TargetMode getTargetMode()
543     {
544         return this.targetMode;
545     }
546 
547     /**
548      * Setter method for instance variable {@link #targetMode}.
549      *
550      * @param _targetMode value for instance variable {@link #targetMode}
551      */
552 
553     public void setTargetMode(final TargetMode _targetMode)
554     {
555         this.targetMode = _targetMode;
556     }
557 
558     /**
559      * Getter method for instance variable {@link #display}.
560      *
561      * @return value of instance variable {@link #display}
562      */
563     @Override
564     public Display getDisplay()
565     {
566         return this.display;
567     }
568 
569     /**
570      * Getter method for the instance variable {@link #requestInstances}.
571      *
572      * @return value of instance variable {@link #requestInstances}
573      */
574     public List<Instance> getRequestInstances()
575     {
576         return this.requestInstances;
577     }
578 }