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;
22  
23  import java.util.Collections;
24  import java.util.HashSet;
25  import java.util.Set;
26  import java.util.UUID;
27  
28  import org.efaps.admin.ui.Form;
29  import org.efaps.admin.user.Company;
30  import org.efaps.ci.CIAdminDataModel;
31  import org.efaps.util.EFapsException;
32  import org.efaps.util.cache.CacheReloadException;
33  
34  /**
35   * Class extending type for classification purpose.
36   *
37   * @author The eFaps Team
38   * @version $Id$
39   */
40  public class Classification
41      extends Type
42  {
43      /**
44       * Needed for serialization.
45       */
46      private static final long serialVersionUID = 1L;
47  
48      /**
49       * Enum contains the keys for the attributes.
50       */
51      public enum Keys {
52          /** key to the type {@link Classification#multipleSelect}. */
53          MULTI("multipleSelect"),
54          /** key to the type {@link Classification#classifiesType}. */
55          TYPE("type"),
56          /** key to the relation type {@link Classification#classifyRelation}. */
57          RELTYPE ("relType"),
58          /** key to attribute of the relation type {@link Classification#relLinkAttributeName}. */
59          RELLINKATTR ("relLinkAttribute"),
60          /**  key to attribute of the relation type {@link Classification#relTypeAttributeName}. */
61          RELTYPEATTR ("relTypeAttribute"),
62          /** key to attribute of the type {@link Classification#linkAttributeName}. */
63          LINKATTR ("classLinkAttribute");
64  
65          /** value. */
66          private final String value;
67  
68          /**
69           * Private constructor setting the instance variable.
70           * @param _value  value
71           */
72          private Keys(final String _value)
73          {
74              this.value = _value;
75          }
76  
77          /**
78           * Getter method for instance variable {@link #value}.
79           *
80           * @return value of instance variable {@link #value}
81           */
82          public String getValue()
83          {
84              return this.value;
85          }
86      }
87  
88      /**
89       * Instance variable for the parent classification this classification is
90       * child of.
91       */
92      private Long parent = null;
93  
94      /**
95       * Can multiple Classifications be selected.
96       */
97      private boolean multipleSelect = true;
98  
99      /**
100      * Instance variable for all child classification of this classification.
101      */
102     private final Set<Long> children = new HashSet<Long>();
103 
104     /**
105      * Type this Classification is classifying.
106      */
107     private Long classifiesType;
108 
109     /**
110      * Relation belonging to the type this Classification is classifying.
111      */
112     private Long classifyRelation;
113 
114     /**
115      * Name of the Attribute of the Relation {@link #classifyRelation} that
116      * links the Relation to the type {@link #classifiesType} that is classified.
117      */
118     private String relLinkAttributeName;
119 
120     /**
121      * Name of the Attribute of the Relation {@link #classifyRelation} that
122      * contains the ids of the classifications that are classifying the type
123      *  {@link #classifiesType}.
124      */
125     private String relTypeAttributeName;
126 
127     /**
128      * Name of the Attribute that links this Classification to the type it
129      * classifies.
130      */
131     private String linkAttributeName;
132 
133     /**
134      * Companies this Classification is assigned to.
135      */
136     private final Set<Company> companies = new HashSet<Company>();
137 
138     /**
139      * @param _id       id of this Classification
140      * @param _uuid     uuid of this Classification
141      * @param _name     name of this Classification
142      * @throws CacheReloadException on error
143      */
144     protected Classification(final long _id,
145                              final String _uuid,
146                              final String _name)
147         throws CacheReloadException
148     {
149         super(_id, _uuid, _name);
150     }
151 
152     /**
153      * Getter method for instance variable {@link #parent}.
154      *
155      * @return value of instance variable {@link #parent}
156      * @throws CacheReloadException on error
157      */
158     public Classification getParentClassification()
159         throws CacheReloadException
160     {
161         return isRoot() ? null : Classification.get(this.parent);
162     }
163 
164     /**
165      * Setter method for instance variable {@link #parent}.
166      *
167      * @param _parentClassification value for instance variable {@link #parent}
168      */
169     protected void setParentClassification(final Long _parentClassification)
170     {
171         this.parent = _parentClassification;
172         setDirty();
173     }
174 
175     /**
176      * Getter method for instance variable {@link #childs}.
177      * @return value of instance variable {@link #childs}
178      * @throws CacheReloadException on error
179      */
180     public Set<Classification> getChildClassifications()
181         throws CacheReloadException
182     {
183         final Set<Classification> ret = new HashSet<Classification>();
184         for (final Long id : this.children) {
185             final Classification child = Classification.get(id);
186             ret.add(child);
187         }
188         return Collections.unmodifiableSet(ret);
189     }
190 
191     /**
192      * Getter method for the instance variable {@link #children}.
193      *
194      * @return value of instance variable {@link #children}
195      */
196     protected Set<Long> getChildren()
197     {
198         return this.children;
199     }
200 
201     /**
202      * Getter method for instance variable {@link #linkAttributeName}.
203      *
204      * @return value of instance variable {@link #linkAttributeName}
205      */
206     public String getLinkAttributeName()
207     {
208         return this.linkAttributeName;
209     }
210 
211     /**
212      * Getter method for instance variable {@link #classifiesType}. If the
213      * variable is null the value for this instance variable of the parent
214      * classification will be returned.
215      *
216      * @return value of instance variable {@link #classifiesType}
217      * @throws CacheReloadException on error
218      */
219     public Type getClassifiesType()
220         throws CacheReloadException
221     {
222         final Type ret;
223         if (this.classifiesType == null && this.parent != null) {
224             ret = getParentClassification().getClassifiesType();
225         } else {
226             ret = Type.get(this.classifiesType);
227         }
228         return ret;
229     }
230 
231     /**
232      * Getter method for instance variable {@link #classifyRelation}. If the
233      * variable is null the value for this instance variable of the parent
234      * classification will be returned.
235      *
236      * @return value of instance variable {@link #classifyRelation}
237      * @throws CacheReloadException on error
238      */
239     public Type getClassifyRelationType()
240         throws CacheReloadException
241     {
242         final Type ret;
243         if (this.classifyRelation == null && this.parent != null) {
244             ret = getParentClassification().getClassifyRelationType();
245         } else {
246             ret = Type.get(this.classifyRelation);
247         }
248         return ret;
249     }
250 
251     /**
252      * Getter method for instance variable {@link #relLinkAttributeName}. If the
253      * variable is null the value for this instance variable of the parent
254      * classification will be returned.
255      *
256      * @return value of instance variable {@link #relLinkAttributeName}
257      * @throws CacheReloadException on error
258      */
259     public String getRelLinkAttributeName()
260         throws CacheReloadException
261     {
262         final String ret;
263         if (this.relLinkAttributeName == null && this.parent != null) {
264             ret = getParentClassification().getRelLinkAttributeName();
265         } else {
266             ret = this.relLinkAttributeName;
267         }
268         return ret;
269     }
270 
271     /**
272      * Getter method for instance variable {@link #relTypeAttributeName}. If the
273      * variable is null the value for this instance variable of the parent
274      * classification will be returned.
275      * @return value of instance variable {@link #relTypeAttributeName}
276      * @throws CacheReloadException on error
277      */
278     public String getRelTypeAttributeName()
279         throws CacheReloadException
280     {
281         final String ret;
282         if (this.relTypeAttributeName == null && this.parent != null) {
283             ret = getParentClassification().getRelTypeAttributeName();
284         } else {
285             ret = this.relTypeAttributeName;
286         }
287         return ret;
288     }
289 
290     /**
291      * Is this Classification the root Classification.
292      * (Meaning that it does not have a parent).
293      * @return true if root classification
294      */
295     public boolean isRoot()
296     {
297         return this.parent == null;
298     }
299 
300     /**
301      * Getter method for the instance variable {@link #multipleSelect}.
302      *
303      * @return value of instance variable {@link #multipleSelect}
304      * @throws CacheReloadException on error
305      */
306     public boolean isMultipleSelect()
307         throws CacheReloadException
308     {
309         final boolean ret;
310         if (isRoot()) {
311             ret = this.multipleSelect;
312         } else {
313             ret = getParentClassification().isMultipleSelect();
314         }
315         return ret;
316     }
317 
318     /**
319      * Check if the root classification of this classification is assigned to
320      * the given company.
321      *
322      * @see #companies
323      * @param _company copmany that will be checked for assignment
324      * @return true it the root classification of this classification is
325      *         assigned to the given company, else
326      * @throws CacheReloadException on error
327      */
328     public boolean isAssigendTo(final Company _company)
329         throws CacheReloadException
330     {
331         final boolean ret;
332         if (isRoot()) {
333             ret = this.companies.isEmpty() ? true : this.companies.contains(_company);
334         } else {
335             ret = getParentClassification().isAssigendTo(_company);
336         }
337         return ret;
338     }
339 
340     /**
341      * {@inheritDoc}
342      */
343     @Override
344     public Form getTypeForm()
345         throws EFapsException
346     {
347         Form ret = super.getTypeForm();
348         if (ret == null && getParentClassification() != null) {
349             ret = getParentClassification().getTypeForm();
350         }
351         return ret;
352     }
353 
354     /**
355      * {@inheritDoc}
356      */
357     @Override
358     protected void setLinkProperty(final UUID _linkTypeUUID,
359                                    final long _toId,
360                                    final UUID _toTypeUUID,
361                                    final String _toName)
362         throws EFapsException
363     {
364         if (_linkTypeUUID.equals(CIAdminDataModel.TypeClassifies.uuid)) {
365             final Type type = Type.get(_toId);
366             this.classifiesType = type.getId();
367             type.addClassifiedByType(this);
368         } else if (_linkTypeUUID.equals(CIAdminDataModel.TypeClassifyRelation.uuid)) {
369             this.classifyRelation = Type.get(_toId).getId();
370         } else if (_linkTypeUUID.equals(CIAdminDataModel.TypeClassifyCompany.uuid)) {
371             this.companies.add(Company.get(_toId));
372         }
373         super.setLinkProperty(_linkTypeUUID, _toId, _toTypeUUID, _toName);
374     }
375 
376     /**
377      * The instance method sets a new property value.
378      *
379      * @param _name name of the property
380      * @param _value value of the property
381      * @see #addUniqueKey
382      * @throws CacheReloadException on error
383      */
384     @Override
385     protected void setProperty(final String _name,
386                                final String _value)
387         throws CacheReloadException
388     {
389         if (_name.equals(Classification.Keys.LINKATTR.value)) {
390             this.linkAttributeName = _value;
391         } else if (_name.equals(Classification.Keys.RELLINKATTR.value)) {
392             this.relLinkAttributeName = _value;
393         } else if (_name.equals(Classification.Keys.RELTYPEATTR.value)) {
394             this.relTypeAttributeName = _value;
395         } else if (_name.equals(Classification.Keys.MULTI.value)) {
396             this.multipleSelect = !"FALSE".equalsIgnoreCase(_value);
397         }
398         super.setProperty(_name, _value);
399     }
400 
401     /**
402      * Returns for given parameter <i>_id</i> the instance of class {@link Classification}
403      * .
404      *
405      * @param _id id of the type to get
406      * @return instance of class {@link Classification}
407      * @throws CacheReloadException on error
408      */
409     public static Classification get(final long _id)
410         throws CacheReloadException
411     {
412         return (Classification) Type.get(_id);
413     }
414 
415     /**
416      * Returns for given parameter <i>_name</i> the instance of class {@link Classification}
417      * .
418      *
419      * @param _name name of the type to get
420      * @return instance of class {@link Classification}
421      * @throws CacheReloadException on error
422      */
423     public static Classification get(final String _name)
424         throws CacheReloadException
425     {
426         return (Classification) Type.get(_name);
427     }
428 
429     /**
430      * Returns for given parameter <i>_uuid</i> the instance of class {@link Classification}
431      * .
432      *
433      * @param _uuid UUID of the type to get
434      * @return instance of class {@link Classification}
435      * @throws CacheReloadException on error
436      */
437     public static Classification get(final UUID _uuid)
438         throws CacheReloadException
439     {
440         return (Classification) Type.get(_uuid);
441     }
442 }