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.ui;
22  
23  
24  
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.TreeMap;
30  
31  import org.efaps.admin.datamodel.Type;
32  import org.efaps.admin.ui.field.Field;
33  import org.efaps.admin.ui.field.FieldChart;
34  import org.efaps.admin.ui.field.FieldClassification;
35  import org.efaps.admin.ui.field.FieldCommand;
36  import org.efaps.admin.ui.field.FieldGroup;
37  import org.efaps.admin.ui.field.FieldHeading;
38  import org.efaps.admin.ui.field.FieldPicker;
39  import org.efaps.admin.ui.field.FieldSet;
40  import org.efaps.admin.ui.field.FieldTable;
41  import org.efaps.ci.CIAdminUserInterface;
42  import org.efaps.db.MultiPrintQuery;
43  import org.efaps.db.QueryBuilder;
44  import org.efaps.util.EFapsException;
45  import org.efaps.util.cache.CacheReloadException;
46  
47  /**
48   * @author The eFaps Team
49   * @version $Id$
50   *
51   */
52  public abstract class AbstractCollection
53      extends AbstractUserInterfaceObject
54  {
55      /**
56       * Needed for serialization.
57       */
58      private static final long serialVersionUID = 1L;
59  
60      /**
61       * Instance variable for all field expressions.
62       *
63       * @see #addFieldExpr
64       * @see #getFieldExprIndex
65       * @see #getAllFieldExpr
66       */
67      private final Map<String, Integer> allFieldExpr = new HashMap<String, Integer>();
68  
69      /**
70       * All fields of the collection are stored sorted belonging to the id of the
71       * field in a tree map.
72       *
73       * @see #getFields
74       * @see #add(Field)
75       */
76      private final Map<Long, Field> fields = new TreeMap<Long, Field>();
77  
78      /**
79       * Map to have the fields belonging to this collection accessible for name.
80       */
81      private final Map<String, Field> fieldName2Field = new TreeMap<String, Field>();
82  
83      /**
84       * Instance variable for the length of the field expression list.
85       *
86       * @see #allFieldExpr
87       */
88      private int selIndexLen = 1;
89  
90      /**
91       * Select string for the statement.
92       *
93       * @see #setSelect
94       * @see #getSelect
95       */
96      private String select = null;
97  
98      /**
99       * Constructor passing on to the super constructor.
100      *
101      * @param _id id of this collection
102      * @param _uuid uuid of this collection
103      * @param _name name of this collection
104      */
105     protected AbstractCollection(final long _id,
106                                  final String _uuid,
107                                  final String _name)
108     {
109         super(_id, _uuid, _name);
110     }
111 
112     /**
113      * Method to add a Field to this Collection.
114      *
115      * @param _field Field to add to this collection
116      */
117     public void add(final Field _field)
118     {
119         this.fields.put(_field.getId(), _field);
120         this.fieldName2Field.put(_field.getName(), _field);
121         if (_field.getReference() != null && _field.getReference().length() > 0) {
122             final String ref = _field.getReference();
123             int index;
124             int end = 0;
125             while ((index = ref.indexOf("$<", end)) > 0) {
126                 index += 2;
127                 end = ref.indexOf(">", index);
128                 addFieldExpr(ref.substring(index, end));
129             }
130         }
131         _field.setCollectionUUID(getUUID());
132     }
133 
134     /**
135      * Add a field expression to the select statement and the hash table of all
136      * field expressions. The method returns the index of the field expression.
137      * If the field expression is already added, the old index is returned, so a
138      * expression is only added once.
139      *
140      * @param _expr field expression to add
141      * @return index of the field expression
142      * @see #getFieldExprIndex
143      * @see #getAllFieldExpr
144      * @see #allFieldExpr
145      */
146     protected int addFieldExpr(final String _expr)
147     {
148         int ret = -1;
149         if (getAllFieldExpr().containsKey(_expr)) {
150             ret = getFieldExprIndex(_expr);
151         } else {
152             getAllFieldExpr().put(_expr, Integer.valueOf(getSelIndexLen()));
153             if (getSelect() == null) {
154                 setSelect(_expr);
155             } else {
156                 setSelect(getSelect() + "," + _expr);
157             }
158             ret = getSelIndexLen();
159             this.selIndexLen++;
160         }
161         return ret;
162     }
163 
164     /**
165      * For the parameter <i>_expr</i> the index in the list of all field
166      * expressions is returned.
167      *
168      * @param _expr expression for which the index is searched
169      * @return index of the field expression
170      * @see #addFieldExpr
171      * @see #getAllFieldExpr
172      * @see #allFieldExpr
173      */
174     public int getFieldExprIndex(final String _expr)
175     {
176         int ret = -1;
177         if (getAllFieldExpr().containsKey(_expr)) {
178             final Integer ident = getAllFieldExpr().get(_expr);
179             ret = ident.intValue();
180         }
181         return ret;
182     }
183 
184     /**
185      * The instance method reads all needed information for this user interface
186      * object.
187      *
188      * @see #readFromDB4Fields
189      * @throws CacheReloadException on error
190      */
191     @Override
192     protected void readFromDB()
193         throws CacheReloadException
194     {
195         super.readFromDB();
196         readFromDB4Fields();
197     }
198 
199     /**
200      * Read all fields related to this collection object.
201      *
202      * @throws CacheReloadException on error
203      */
204     private void readFromDB4Fields()
205         throws CacheReloadException
206     {
207         try {
208 
209             final QueryBuilder queryBldr = new QueryBuilder(CIAdminUserInterface.Field);
210             queryBldr.addWhereAttrEqValue(CIAdminUserInterface.Field.Collection, getId());
211             final MultiPrintQuery multi = queryBldr.getPrint();
212             multi.addAttribute(CIAdminUserInterface.Field.Type,
213                                CIAdminUserInterface.Field.Name);
214             multi.executeWithoutAccessCheck();
215 
216             while (multi.next()) {
217                 final long id = multi.getCurrentInstance().getId();
218                 final String name =  multi.<String>getAttribute(CIAdminUserInterface.Field.Name);
219                 final Type type = multi.<Type>getAttribute(CIAdminUserInterface.Field.Type);
220                 final Field field;
221                 if (type.equals(CIAdminUserInterface.FieldCommand.getType())) {
222                     field = new FieldCommand(id, null, name);
223                 } else if (type.equals(CIAdminUserInterface.FieldHeading.getType())) {
224                     field = new FieldHeading(id, null, name);
225                 } else if (type.equals(CIAdminUserInterface.FieldTable.getType())) {
226                     field = new FieldTable(id, null, name);
227                 } else if (type.equals(CIAdminUserInterface.FieldGroup.getType())) {
228                     field = new FieldGroup(id, null, name);
229                 } else if (type.equals(CIAdminUserInterface.FieldSet.getType())) {
230                     field = new FieldSet(id, null, name);
231                 } else if (type.equals(CIAdminUserInterface.FieldClassification.getType())) {
232                     field = new FieldClassification(id, null, name);
233                 } else if (type.equals(CIAdminUserInterface.FieldPicker.getType())) {
234                     field = new FieldPicker(id, null, name);
235                 } else if (type.equals(CIAdminUserInterface.FieldChart.getType())) {
236                     field = new FieldChart(id, null, name);
237                 } else {
238                     field = new Field(id, null, name);
239                 }
240                 field.readFromDB();
241                 add(field);
242             }
243         } catch (final EFapsException e) {
244             throw new CacheReloadException("could not read fields for '" + getName() + "'", e);
245         }
246     }
247 
248     /**
249      * The method takes values of the {@link #fields} and returnes them as
250      * {@link java.util.ArrayList}.
251      *
252      * @return the values of the {@link #fields} map instance as array list
253      * @see #fields
254      */
255     public List<Field> getFields()
256     {
257         return new ArrayList<Field>(this.fields.values());
258     }
259 
260     /**
261      * @see #allFieldExpr
262      * @return the hashtable which holds single field expression
263      */
264     private Map<String, Integer> getAllFieldExpr()
265     {
266         return this.allFieldExpr;
267     }
268 
269     /**
270      * Get the value of the attribute {@link #selIndexLen}.
271      *
272      * @return the value of the attribute {@link #selIndexLen}
273      * @see #selIndexLen
274      */
275     private int getSelIndexLen()
276     {
277         return this.selIndexLen;
278     }
279 
280     /**
281      * This is the setter method for instance variable {@link #select}.
282      *
283      * @param _select new value for instance variable {@link #select}
284      * @see #select
285      * @see #getSelect
286      */
287     protected void setSelect(final String _select)
288     {
289         this.select = _select;
290     }
291 
292     /**
293      * Get the value of the {@link #select} clause.
294      *
295      * @return the value of the {@link #select} clause
296      * @see #select
297      * @see #setSelect
298      */
299     public String getSelect()
300     {
301         return this.select;
302     }
303 
304     /**
305      * Method to get the whole map of fields.
306      *
307      * @return Map
308      */
309     public Map<Long, Field> getFieldsMap()
310     {
311         return this.fields;
312     }
313 
314     /**
315      * Method to get a field belonging to this collection by its name.
316      * @param _fieldName name of the field wanted
317      * @return Field if found, else null
318      */
319     public Field getField(final String _fieldName)
320     {
321         return this.fieldName2Field.get(_fieldName);
322     }
323 }