1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.efaps.db.print.value;
22
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.sql.Statement;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Map.Entry;
32 import java.util.Set;
33
34 import org.efaps.admin.datamodel.Attribute;
35 import org.efaps.admin.datamodel.Classification;
36 import org.efaps.admin.datamodel.Type;
37 import org.efaps.db.Context;
38 import org.efaps.db.Instance;
39 import org.efaps.db.print.OneSelect;
40 import org.efaps.db.transaction.ConnectionResource;
41 import org.efaps.db.wrapper.SQLPart;
42 import org.efaps.db.wrapper.SQLSelect;
43 import org.efaps.util.EFapsException;
44 import org.efaps.util.cache.CacheReloadException;
45
46
47
48
49
50
51
52 public class ClassificationValueSelect
53 extends OIDValueSelect
54 {
55
56
57
58 private final Map<Instance, List<Long>> instances2classId = new HashMap<Instance, List<Long>>();
59
60
61
62
63 private boolean retrieved = false;
64
65
66
67
68 public ClassificationValueSelect(final OneSelect _oneSelect)
69 {
70 super(_oneSelect);
71 }
72
73
74
75
76 @Override
77 public String getValueType()
78 {
79 return "classification";
80 }
81
82
83
84
85 @Override
86 public Object getValue(final Object _object)
87 throws EFapsException
88 {
89 final ArrayList<Object> ret = new ArrayList<>();
90 final String oid = (String) super.getValue(_object);
91
92
93 if (!this.retrieved) {
94 getValues4Instances(oid);
95 this.retrieved = true;
96 }
97
98 if (getChildValueSelect() == null) {
99 throw new EFapsException(ClassificationValueSelect.class, "notyet");
100 } else {
101 if (oid != null) {
102 if ("type".equals(getChildValueSelect().getValueType())) {
103 final Instance instance = Instance.get(oid);
104 final Set<Classification> clazzes = getClassification(this.instances2classId.get(instance));
105 for (final Classification clazz : clazzes) {
106 final Object tmp = ((TypeValueSelect) getChildValueSelect())
107 .analyzeChildValue(getChildValueSelect(), clazz);
108 ret.add(tmp);
109 }
110 }
111 }
112 }
113 return ret.size() > 0 ? ret : null;
114 }
115
116
117
118
119 @Override
120 public Object getValue(final List<Object> _objectList)
121 throws EFapsException
122 {
123 final List<Object> ret = new ArrayList<Object>();
124 for (final Object object : _objectList) {
125 ret.add(getValue(object));
126 }
127 return _objectList.size() > 0 ? ret.size() > 1 ? ret : ret.get(0) : null;
128 }
129
130
131
132
133
134
135
136
137 private Set<Classification> getClassification(final List<Long> _classIds)
138 throws CacheReloadException
139 {
140 final Set<Classification> noadd = new HashSet<Classification>();
141 final Set<Classification> add = new HashSet<Classification>();
142 if (_classIds != null) {
143 for (final Long id : _classIds) {
144 Classification clazz = (Classification) Type.get(id);
145 if (!noadd.contains(clazz)) {
146 add.add(clazz);
147 while (clazz.getParentClassification() != null) {
148 clazz = clazz.getParentClassification();
149 if (add.contains(clazz)) {
150 add.remove(clazz);
151 }
152 noadd.add(clazz);
153 }
154 }
155 }
156 }
157 return add;
158 }
159
160
161
162
163
164
165
166 private void getValues4Instances(final String _oid)
167 throws EFapsException
168 {
169
170
171
172 final Map<Type, List<Instance>> type2instance = new HashMap<Type, List<Instance>>();
173 final Instance currentInst = Instance.get(_oid);
174 final List<Instance> instances = new ArrayList<Instance>();
175 if (getOneSelect().getQuery().getInstanceList().contains(currentInst)) {
176 instances.addAll(getOneSelect().getQuery().getInstanceList());
177 } else {
178 for (final Object object : getOneSelect().getObjectList()) {
179 final String oid = (String) super.getValue(object);
180 instances.add(Instance.get(oid));
181 }
182 }
183
184 for (final Instance instance : instances) {
185 List<Instance> tmpList;
186 if (type2instance.containsKey(instance.getType())) {
187 tmpList = type2instance.get(instance.getType());
188 } else {
189 tmpList = new ArrayList<Instance>();
190 type2instance.put(instance.getType(), tmpList);
191 }
192 tmpList.add(instance);
193 }
194
195
196 for (final Entry<Type, List<Instance>> entry : type2instance.entrySet()) {
197
198 boolean union = false;
199 final Set<Classification> classTypes = new HashSet<Classification>();
200 Type curr = entry.getKey();
201 while (curr.getParentType() != null) {
202 classTypes.addAll(curr.getClassifiedByTypes());
203 curr = curr.getParentType();
204 }
205 classTypes.addAll(curr.getClassifiedByTypes());
206 final SQLSelect unionSelect = new SQLSelect();
207 for (final Classification clazz : classTypes) {
208
209 final Attribute typeAttr = clazz.getClassifyRelationType()
210 .getAttribute(clazz.getRelTypeAttributeName());
211 final Attribute linkAttr = clazz.getClassifyRelationType()
212 .getAttribute(clazz.getRelLinkAttributeName());
213 final SQLSelect select;
214 if (union) {
215 unionSelect.addPart(SQLPart.UNION).addPart(SQLPart.ALL);
216 select = new SQLSelect();
217 } else {
218 select = unionSelect;
219 union = true;
220 }
221 select.column(0, "ID")
222 .column(0, linkAttr.getSqlColNames().get(0))
223 .column(0, typeAttr.getSqlColNames().get(0))
224 .from(clazz.getClassifyRelationType().getMainTable().getSqlTable(), 0)
225 .addPart(SQLPart.WHERE)
226 .addColumnPart(0, linkAttr.getSqlColNames().get(0))
227 .addPart(SQLPart.IN).addPart(SQLPart.PARENTHESIS_OPEN);
228
229 boolean first = true;
230 for (final Instance instance : entry.getValue()) {
231 if (first) {
232 first = false;
233 } else {
234 select.addPart(SQLPart.COMMA);
235 }
236 select.addValuePart(instance.getId());
237 }
238 select.addPart(SQLPart.PARENTHESIS_CLOSE);
239 if (clazz.getClassifyRelationType().getMainTable().getSqlColType() != null) {
240 select.addPart(SQLPart.AND)
241 .addColumnPart(0, clazz.getClassifyRelationType().getMainTable().getSqlColType())
242 .addPart(SQLPart.EQUAL).addValuePart(clazz.getClassifyRelationType().getId());
243 }
244 if (union && !select.equals(unionSelect)) {
245 unionSelect.addNestedSelectPart(select.getSQL());
246 }
247 }
248 if (classTypes.size() > 0) {
249 executeOneCompleteStmt(unionSelect.getSQL(), entry.getValue());
250 }
251 }
252 }
253
254
255
256
257
258
259
260
261
262 protected boolean executeOneCompleteStmt(final String _complStmt,
263 final List<Instance> _instances)
264 throws EFapsException
265 {
266 final boolean ret = false;
267 ConnectionResource con = null;
268 try {
269 con = Context.getThreadContext().getConnectionResource();
270
271 final Statement stmt = con.getConnection().createStatement();
272
273 final ResultSet rs = stmt.executeQuery(_complStmt.toString());
274 final Map<Long, List<Long>> link2clazz = new HashMap<Long, List<Long>>();
275 while (rs.next()) {
276 final long linkId = rs.getLong(2);
277 final long classificationID = rs.getLong(3);
278 List<Long> templ;
279 if (link2clazz.containsKey(linkId)) {
280 templ = link2clazz.get(linkId);
281 } else {
282 templ = new ArrayList<Long>();
283 link2clazz.put(linkId, templ);
284 }
285 templ.add(classificationID);
286 }
287 for (final Instance instance : _instances) {
288 this.instances2classId.put(instance, link2clazz.get(instance.getId()));
289 }
290 rs.close();
291 stmt.close();
292 con.commit();
293 } catch (final SQLException e) {
294 throw new EFapsException(ClassificationValueSelect.class, "executeOneCompleteStmt", e);
295 } finally {
296 if (con != null && con.isOpened()) {
297 con.abort();
298 }
299 }
300 return ret;
301 }
302 }