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  
22  package org.efaps.db.search.value;
23  
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Set;
29  import java.util.TreeMap;
30  
31  import org.efaps.admin.datamodel.IBitEnum;
32  import org.efaps.admin.datamodel.attributetype.BitEnumType;
33  import org.efaps.db.AbstractObjectQuery;
34  import org.efaps.db.search.AbstractQPart;
35  import org.efaps.db.search.compare.QEqual;
36  import org.efaps.db.wrapper.SQLPart;
37  import org.efaps.db.wrapper.SQLSelect;
38  import org.efaps.util.EFapsException;
39  
40  
41  /**
42   * TODO comment!
43   *
44   * @author The eFaps Team
45   * @version $Id$
46   */
47  public class QBitValue
48      extends AbstractQValue
49  {
50      /**
51       * BitEnum belonging to this value.
52       */
53      private final IBitEnum bitEnum;
54  
55      /**
56       * Set of integr allready added.
57       */
58      private final Set<Integer> added = new HashSet<Integer>();;
59  
60      /**
61       * @param _bitEnum bit enum to be used
62       */
63      public QBitValue(final IBitEnum _bitEnum)
64      {
65          this.bitEnum = _bitEnum;
66      }
67  
68      /**
69       * {@inheritDoc}
70       */
71      @Override
72      public AbstractQPart prepare(final AbstractObjectQuery<?> _query,
73                                   final AbstractQPart _part)
74          throws EFapsException
75      {
76          if (_part instanceof QEqual) {
77              final List<AbstractQValue> values = ((QEqual) _part).getValues();
78              final Map<Integer, IBitEnum>enums = new TreeMap<Integer, IBitEnum>();
79              for (final AbstractQValue value : values) {
80                  if (value instanceof QBitValue) {
81                      final IBitEnum abitEnum = ((QBitValue) value).getBitEnum();
82                      if (abitEnum.getInt() < this.bitEnum.getInt()) {
83                          enums.put(abitEnum.getInt(), abitEnum);
84                      }
85                  }
86              }
87              if (!enums.isEmpty()) {
88                  final IBitEnum aEnum = enums.values().iterator().next();
89                  final IBitEnum[] consts = aEnum.getClass().getEnumConstants();
90                  final int max = consts[consts.length - 1].getInt() * 2;
91                  for (int i = 0; i < max; i++) {
92                      final Iterator<IBitEnum> iter = enums.values().iterator();
93                      while (iter.hasNext()) {
94                          final IBitEnum oEnum = iter.next();
95                          if (BitEnumType.isSelected(i, oEnum)) {
96                              this.added.add(i);
97                          }
98                      }
99                  }
100             }
101         }
102         return this;
103     }
104 
105     /**
106      * {@inheritDoc}
107      */
108     @Override
109     public QBitValue appendSQL(final SQLSelect _sql)
110     {
111         final IBitEnum[] consts = this.bitEnum.getClass().getEnumConstants();
112         final int max = consts[consts.length - 1].getInt() * 2;
113         boolean first = true;
114         for (int i = 0; i < max; i++) {
115             if (!this.added.contains(i) && BitEnumType.isSelected(i, this.bitEnum)) {
116                 if (first) {
117                     first = false;
118                 } else {
119                     _sql.addPart(SQLPart.COMMA);
120                 }
121                 _sql.addValuePart(i);
122             }
123         }
124         return this;
125     }
126 
127     /**
128      * Getter method for the instance variable {@link #bitEnum}.
129      *
130      * @return value of instance variable {@link #bitEnum}
131      */
132     public IBitEnum getBitEnum()
133     {
134         return this.bitEnum;
135     }
136 }