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.db;
22  
23  import java.io.Serializable;
24  import java.util.UUID;
25  
26  import org.apache.commons.lang3.builder.ToStringBuilder;
27  import org.efaps.admin.datamodel.Type;
28  import org.efaps.util.EFapsException;
29  import org.efaps.util.cache.CacheReloadException;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  /**
34   * The class is used to store one object id of an instance (defined with type and id). The string representation is the
35   * type id plus point plus id.
36   *
37   * @author The eFaps Team
38   * @version $Id$
39   */
40  public final class Instance
41      implements Serializable
42  {
43      /**
44       * Logging instance used in this class.
45       */
46      private static final Logger LOG = LoggerFactory.getLogger(Instance.class);
47  
48      /**
49       * Serial Version unique identifier.
50       */
51      private static final long serialVersionUID = -5587167060980613742L;
52  
53      /**
54       * The instance variable stores the type definition for which this class is the instance.
55       */
56      private final UUID uuid;
57  
58      /**
59       * The instance variable stores the database id of the instance in the database.
60       *
61       * @see #getId()
62       */
63      private final long id;
64  
65      /**
66       * Key for this instance.
67       */
68      private final String key;
69  
70      /**
71       * Is the information of GeneralId retrieved from the eFaps DataBase.
72       */
73      private boolean generalised;
74  
75      /**
76       * The generalId of this Instance.
77       */
78      private long generalId = 0;
79  
80      /**
81       * The ExhangeID of this Instance.
82       */
83      private long exchangeId = 0;
84  
85      /**
86       * The ExchangeSystemID of this Instance.
87       */
88      private long exchangeSystemId = 0;
89  
90      /**
91       * Constructor used if the type and the database id is known.
92       *
93       * @param _uuid uuid of the type of the instance
94       * @param _id id in the database of the instance
95       * @param _instanceKey key to this instance
96       */
97      private Instance(final UUID _uuid,
98                       final long _id,
99                       final String _instanceKey)
100     {
101         this.uuid = _uuid;
102         this.id = _id;
103         this.key = _instanceKey;
104     }
105 
106     /**
107      * @return id represented by this instance
108      * @see #id
109      */
110     @Override
111     public int hashCode()
112     {
113         return (int) this.id;
114     }
115 
116     /**
117      * @param _obj Object to compare
118      * @return <i>true</i> if the given object in _obj is an instance and holds the same type and id
119      * @see #id
120      * @see #type
121      */
122     @Override
123     public boolean equals(final Object _obj)
124     {
125         boolean ret = false;
126         if (_obj instanceof Instance) {
127             final Instance other = (Instance) _obj;
128             if (other.uuid != null && this.uuid != null) {
129                 ret = (other.getId() == getId()) && (other.uuid.equals(this.uuid));
130             } else {
131                 ret = super.equals(_obj);
132             }
133         }
134         return ret;
135     }
136 
137     /**
138      * This is the getter method for the instance variable {@link #type}.
139      *
140      * @return value of instance variable {@link #type}
141      * @see #type
142      */
143     public Type getType()
144     {
145         Type ret = null;
146         try {
147             if (this.uuid != null) {
148                 ret = Type.get(this.uuid);
149             }
150         } catch (final CacheReloadException e) {
151             Instance.LOG.error("Could not load Type for UUID: {}", this.uuid);
152         }
153         return ret;
154     }
155 
156     /**
157      * Getter method for the instance variable {@link #uuid}.
158      *
159      * @return value of instance variable {@link #uuid}
160      */
161     public UUID getTypeUUID()
162     {
163         return this.uuid;
164     }
165 
166     /**
167      * This is the getter method for the instance variable {@link #id}.
168      *
169      * @return value of instance variable {@link #id}
170      * @see #id
171      */
172     public long getId()
173     {
174         return this.id;
175     }
176 
177     /**
178      * The string representation which is defined by this instance is returned.
179      *
180      * @return string representation of the object id
181      */
182     public String getOid()
183     {
184         String ret = null;
185         if (isValid()) {
186             ret = getType().getId() + "." + getId();
187         }
188         return ret;
189     }
190 
191     /**
192      * Getter method for instance variable {@link #key}.
193      *
194      * @return value of instance variable {@link #key}
195      */
196     public String getKey()
197     {
198         return this.key == null ? getOid() : this.key;
199     }
200 
201     /**
202      * Method to evaluate if this instance is an valid instance. Meaning that it has a valid type and a valid id.
203      *
204      * @return true if valid, else false
205      */
206     public boolean isValid()
207     {
208         return this.uuid != null && this.id > 0;
209     }
210 
211     /**
212      * @throws EFapsException on error
213      */
214     private void check4Generalised()
215         throws EFapsException
216     {
217         if (getType().isGeneralInstance() && !this.generalised) {
218             GeneralInstance.generaliseInstance(this);
219             this.generalised = true;
220         }
221     }
222 
223     /**
224      * Setter method for instance variable {@link #generalised}.
225      *
226      * @param _generalised value for instance variable {@link #generalised}
227      */
228 
229     protected void setGeneralised(final boolean _generalised)
230     {
231         this.generalised = _generalised;
232     }
233 
234     /**
235      * Get the id of the general instance for this instance.<br/>
236      * <b>Attention this method is actually executing a Query against the eFaps Database the first time this method or
237      * {@link #getExchangeSystemId()} or {@link #getExchangeId()}is called!</b>
238      *
239      * @return 0 if no general instance exits
240      * @throws EFapsException on error
241      */
242     public long getGeneralId()
243         throws EFapsException
244     {
245         check4Generalised();
246         return this.generalId;
247     }
248 
249     /**
250      * Setter method for instance variable {@link #generalId}.
251      *
252      * @param _generalId value for instance variable {@link #generalId}
253      */
254     protected void setGeneralId(final long _generalId)
255     {
256         this.generalId = _generalId;
257     }
258 
259     /**
260      * Getter method for the instance variable {@link #exchangeId}.<br/>
261      * <b>Attention this method is actually executing a Query against the eFaps Database the first time this method or
262      * {@link #getExchangeSystemId()} or {@link #getGeneralId()}is called!</b>
263      *
264      * @return value of instance variable {@link #exchangeId}
265      * @throws EFapsException on error
266      */
267     public long getExchangeId()
268         throws EFapsException
269     {
270         return this.getExchangeId(true);
271     }
272 
273     /**
274      * Getter method for the instance variable {@link #exchangeId}.<br/>
275      * <b>Attention this method is actually executing a Query against
276      * the eFaps Database the first time this method or
277      * {@link #getExchangeSystemId()} or {@link #getGeneralId()}is called!</b>
278      *
279      * @param _request must the eFaps Database be requested
280      * @return value of instance variable {@link #exchangeId}
281      * @throws EFapsException on error
282      */
283     protected long getExchangeId(final boolean _request)
284         throws EFapsException
285     {
286         if (_request) {
287             check4Generalised();
288         }
289         return this.exchangeId;
290     }
291 
292     /**
293      * Setter method for instance variable {@link #exchangeId}.
294      *
295      * @param _exchangeId value for instance variable {@link #exchangeId}
296      */
297     protected void setExchangeId(final long _exchangeId)
298     {
299         this.exchangeId = _exchangeId;
300     }
301 
302     /**
303      * Getter method for the instance variable {@link #exchangeSystemId}.<br/>
304      * <b>Attention this method is actually executing a Query against the
305      * eFaps Database the first time this method or
306      * {@link #getExchangeId()} or {@link #getGeneralId()}is called!</b>
307      *
308      * @return value of instance variable {@link #exchangeSystemId}
309      * @throws EFapsException on error
310      */
311     public long getExchangeSystemId()
312         throws EFapsException
313     {
314         return this.getExchangeSystemId(true);
315     }
316 
317     /**
318      * Getter method for the instance variable {@link #exchangeSystemId}.<br/>
319      * <b>Attention this method is actually executing a Query against the
320      * eFaps Database the first time this method or
321      * {@link #getExchangeId()} or {@link #getGeneralId()}is called!</b>
322      *
323      * @param _request must the eFaps Database be requested
324      * @return value of instance variable {@link #exchangeSystemId}
325      * @throws EFapsException on error
326      */
327     public long getExchangeSystemId(final boolean _request)
328         throws EFapsException
329     {
330         if (_request) {
331             check4Generalised();
332         }
333         return this.exchangeSystemId;
334     }
335 
336     /**
337      * Setter method for instance variable {@link #exchangeSystemId}.
338      *
339      * @param _exchangeSystemId value for instance variable {@link #exchangeSystemId}
340      */
341     protected void setExchangeSystemId(final long _exchangeSystemId)
342     {
343         this.exchangeSystemId = _exchangeSystemId;
344     }
345 
346     /**
347      * The method returns a string representation of the instance object. It does not replace method {@link #getOid}!.
348      *
349      * @return string representation of this instance object
350      */
351     @Override
352     public String toString()
353     {
354         return new ToStringBuilder(this)
355                         .appendSuper(super.toString())
356                         .append("oid", getOid())
357                         .append("type", getType())
358                         .append("id", getId())
359                         .toString();
360     }
361 
362     /**
363      *
364      * @param _type type of the instance
365      * @param _id id of the instance
366      * @return instance
367      */
368     public static Instance get(final Type _type,
369                                final long _id)
370     {
371         String keyTmp = null;
372         if ((_type != null) && (_id != 0)) {
373             keyTmp = _type.getId() + "." + _id;
374         }
375         return Instance.get(_type, _id, keyTmp);
376     }
377 
378     /**
379      *
380      * @param _typeUUID UUID of the instance
381      * @param _id id of the instance
382      * @return instance
383      */
384     public static Instance get(final UUID _typeUUID,
385                                final long _id)
386     {
387         return new Instance(_typeUUID, _id, null);
388     }
389 
390     /**
391      *
392      * @param _type type of the instance
393      * @param _id id of the instance
394      * @param _key key of the instance
395      * @return instance
396      */
397     public static Instance get(final Type _type,
398                                final long _id,
399                                final String _key)
400     {
401         return new Instance(_type == null ? null : _type.getUUID(), _id, _key);
402     }
403 
404     /**
405      *
406      * @param _type type of the instance
407      * @param _id id of the instance as string
408      * @return instance
409      */
410     public static Instance get(final Type _type,
411                                final String _id)
412     {
413         return Instance.get(_type, _id, null);
414     }
415 
416     /**
417      *
418      * @param _type type of the instance
419      * @param _id id of the instance
420      * @param _key key of the instance
421      * @return instance
422      */
423     public static Instance get(final Type _type,
424                                final String _id,
425                                final String _key)
426     {
427         final long idTmp;
428         if (_id != null && _id.length() > 0) {
429             idTmp = Long.parseLong(_id);
430         } else {
431             idTmp = 0;
432         }
433         return Instance.get(_type, idTmp, _key);
434     }
435 
436     /**
437      *
438      * @param _type type of the instance
439      * @param _id id of the instance
440      * @return instance
441      */
442     public static Instance get(final String _type,
443                                final String _id)
444     {
445         return Instance.get(_type, _id, null);
446     }
447 
448     /**
449      *
450      * @param _type type of the instance
451      * @param _id id of the instance
452      * @param _key key of the instance
453      * @return instance
454      */
455     public static Instance get(final String _type,
456                                final String _id,
457                                final String _key)
458     {
459         Type typeTmp = null;
460         if ((_type != null) && (_type.length() > 0)) {
461             try {
462                 typeTmp = Type.get(_type);
463             } catch (final CacheReloadException e) {
464                 Instance.LOG.error("Instance get error with Type: '{}', id: '{}' , key: '{}'",  _type, _id, _key);
465             }
466         }
467         return Instance.get(typeTmp, _id, _key);
468     }
469 
470     /**
471      *
472      * @param _oid eFaps object id of the instance
473      * @return instance
474      */
475     public static Instance get(final String _oid)
476     {
477         Type typeTmp = null;
478         final long idTmp;
479         if (_oid != null) {
480             final int index = _oid.indexOf(".");
481             if (index >= 0) {
482                 try {
483                     typeTmp = Type.get(Long.parseLong(_oid.substring(0, index)));
484                 } catch (final NumberFormatException e) {
485                     Instance.LOG.error("Instance get error with OID: '{}'", _oid);
486                 } catch (final CacheReloadException e) {
487                     Instance.LOG.error("Instance get error with OID: '{}'", _oid);
488                 }
489                 idTmp = Long.parseLong(_oid.substring(index + 1));
490             } else {
491                 typeTmp = null;
492                 idTmp = 0;
493             }
494         } else {
495             typeTmp = null;
496             idTmp = 0;
497         }
498         return Instance.get(typeTmp, idTmp);
499     }
500 }