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.print.value;
22  
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.efaps.admin.datamodel.Attribute;
28  import org.efaps.admin.datamodel.Type;
29  import org.efaps.db.Instance;
30  import org.efaps.db.print.LinkToSelectPart;
31  import org.efaps.db.print.OneSelect;
32  import org.efaps.db.wrapper.SQLSelect;
33  import org.efaps.util.EFapsException;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  /**
38   * TODO comment!
39   *
40   * @author The eFaps Team
41   * @version $Id: AttributeValueSelect.java 3520 2009-12-21 12:37:44Z tim.moxter
42   *          $
43   */
44  public class AttributeValueSelect
45      extends AbstractValueSelect
46  {
47  
48      /**
49       * Logging instance used in this class.
50       */
51      private static final Logger LOG = LoggerFactory.getLogger(OneSelect.class);
52  
53      /**
54       * Attribute belonging to this AttributeValueSelect.
55       */
56      private Attribute attribute;
57  
58      /**
59       * Name of the Attribute belonging to this AttributeValueSelect.
60       */
61      private String attrName;
62  
63      /**
64       * @param _oneSelect OneSelect
65       * @param _attrName name of the attribute
66       */
67      public AttributeValueSelect(final OneSelect _oneSelect,
68                                  final String _attrName)
69      {
70          super(_oneSelect);
71          this.attrName = _attrName;
72      }
73  
74      /**
75       * @param _oneSelect OneSelect
76       * @param _attr Attribute
77       */
78      public AttributeValueSelect(final OneSelect _oneSelect,
79                                  final Attribute _attr)
80      {
81          super(_oneSelect);
82          this.attribute = _attr;
83      }
84  
85      /**
86       * Getter method for instance variable {@link #attrName}.
87       *
88       * @return value of instance variable {@link #attrName}
89       */
90      public String getAttrName()
91      {
92          return this.attrName;
93      }
94  
95      /**
96       * {@inheritDoc}
97       */
98      @Override
99      public Attribute getAttribute()
100     {
101         return this.attribute;
102     }
103 
104     /**
105      * Setter method for instance variable {@link #attribute}.
106      *
107      * @param _attribute value for instance variable {@link #attribute}
108      */
109     public void setAttribute(final Attribute _attribute)
110     {
111         this.attribute = _attribute;
112     }
113 
114     /**
115      * {@inheritDoc}
116      */
117     @Override
118     public Object getValue(final Object _object)
119         throws EFapsException
120     {
121         final ArrayList<Object> tempList = new ArrayList<Object>();
122         tempList.add(_object);
123         return getValue(tempList);
124     }
125 
126     /**
127      * {@inheritDoc}
128      */
129     @Override
130     public Object getValue(final List<Object> _objectList)
131         throws EFapsException
132     {
133         // check it the right attribute was selected during preparation
134         if (getParentSelectPart() != null && getParentSelectPart() instanceof LinkToSelectPart) {
135             final Instance linkInstance = ((LinkToSelectPart) getParentSelectPart()).getCurrentInstance();
136             if (linkInstance != null && linkInstance.isValid()) {
137                 if (linkInstance.getType().getId() != this.attribute.getParentId()) {
138                     this.attribute = linkInstance.getType().getAttribute(this.attribute.getName());
139                 }
140             }
141         }
142         Object ret = this.attribute.readDBValue(_objectList);
143         int i = this.attribute.getSqlColNames().size();
144         for (final Attribute attr : this.attribute.getDependencies().values()) {
145             final List<Object> tmpObjectList = new ArrayList<Object>();
146             for (final Object object : _objectList) {
147                 final Object[] inner = new Object[attr.getSqlColNames().size()];
148                 tmpObjectList.add(inner);
149                 for (int j = 0; j < attr.getSqlColNames().size(); j++) {
150                     inner[j] = ((Object[]) object)[i + j];
151                 }
152             }
153 
154             final Object tmpRet  = attr.readDBValue(tmpObjectList);
155             if (ret instanceof List<?>) {
156                 final Iterator<?> iter = ((List<?>) tmpRet).iterator();
157                 for (Object object : (List<?>) ret) {
158                     object = getVal(object, iter.next());
159                 }
160             } else {
161                 ret = getVal(ret, tmpRet);
162             }
163             i++;
164         }
165         if (getChildValueSelect() != null) {
166             if (getChildValueSelect() instanceof IAttributeChildValueSelect) {
167                 final IAttributeChildValueSelect val = (IAttributeChildValueSelect) getChildValueSelect();
168                 ret = val.get(this.attribute, ret);
169             }
170         }
171         return ret;
172     }
173 
174     /**
175      * @param _existingVal alllready existing
176      * @param _toAdd to add
177      * @return objetc
178      */
179     private Object getVal(final Object _existingVal,
180                           final Object _toAdd)
181     {
182         final List<Object> tmpRetList = new ArrayList<Object>();
183         if (_existingVal instanceof Object[]) {
184             for (final Object object : (Object[]) _existingVal) {
185                 tmpRetList.add(object);
186             }
187         } else {
188             tmpRetList.add(_existingVal);
189         }
190         if (_toAdd instanceof Object[]) {
191             for (final Object object : (Object[]) _toAdd) {
192                 tmpRetList.add(object);
193             }
194         } else {
195             tmpRetList.add(_toAdd);
196         }
197         return tmpRetList.toArray();
198     }
199 
200     /**
201      * {@inheritDoc}
202      */
203     @Override
204     public int append2SQLSelect(final Type _type,
205                                 final SQLSelect _select,
206                                 final int _tableIndex,
207                                 final int _colIndex)
208         throws EFapsException
209     {
210         if (this.attribute == null) {
211             this.attribute = _type.getAttribute(this.attrName);
212         }
213         if (this.attribute == null) {
214             AttributeValueSelect.LOG.error("Could not get an attribute with name '{} 'for type: '{}'", this.attrName,
215                             _type);
216             throw new EFapsException(AttributeValueSelect.class, "appendNoAttribute");
217         }
218         int ret = 0;
219         for (final String colName : this.attribute.getSqlColNames()) {
220             _select.column(_tableIndex, colName);
221             getColIndexs().add(_colIndex + ret);
222             ret++;
223         }
224         // in case of dependencies for the attribute they must be selected also
225         for (final Attribute attr : this.attribute.getDependencies().values()) {
226             for (final String colName : attr.getSqlColNames()) {
227                 _select.column(_tableIndex, colName);
228                 getColIndexs().add(_colIndex + ret);
229                 ret++;
230             }
231         }
232         return ret;
233     }
234 
235     /**
236      * {@inheritDoc}
237      */
238     @Override
239     public String getValueType()
240     {
241         return "attribute";
242     }
243 }