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;
22
23 import java.sql.SQLException;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31 import org.apache.commons.lang3.builder.ToStringBuilder;
32 import org.efaps.admin.datamodel.Attribute;
33 import org.efaps.admin.datamodel.AttributeSet;
34 import org.efaps.admin.datamodel.Type;
35 import org.efaps.db.AbstractPrintQuery;
36 import org.efaps.db.Instance;
37 import org.efaps.db.print.value.AbstractValueSelect;
38 import org.efaps.db.print.value.AttributeValueSelect;
39 import org.efaps.db.print.value.BaseValueSelect;
40 import org.efaps.db.print.value.ClassificationValueSelect;
41 import org.efaps.db.print.value.EsjpValueSelect;
42 import org.efaps.db.print.value.FormatValueSelect;
43 import org.efaps.db.print.value.IDValueSelect;
44 import org.efaps.db.print.value.InstanceValueSelect;
45 import org.efaps.db.print.value.KeyValueSelect;
46 import org.efaps.db.print.value.LabelValueSelect;
47 import org.efaps.db.print.value.LengthValueSelect;
48 import org.efaps.db.print.value.NameValueSelect;
49 import org.efaps.db.print.value.OIDValueSelect;
50 import org.efaps.db.print.value.StatusValueSelect;
51 import org.efaps.db.print.value.TypeValueSelect;
52 import org.efaps.db.print.value.UUIDValueSelect;
53 import org.efaps.db.print.value.UoMValueSelect;
54 import org.efaps.db.print.value.ValueValueSelect;
55 import org.efaps.db.wrapper.SQLSelect;
56 import org.efaps.util.EFapsException;
57 import org.efaps.util.cache.CacheReloadException;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61
62
63
64
65
66
67
68
69
70
71 public class OneSelect
72 {
73
74
75
76 private static final Logger LOG = LoggerFactory.getLogger(OneSelect.class);
77
78
79
80
81 private final String selectStmt;
82
83
84
85
86 private final List<ISelectPart> selectParts = new ArrayList<ISelectPart>();
87
88
89
90
91 private LinkFromSelect fromSelect;
92
93
94
95
96
97 private final List<Object> objectList = new ArrayList<Object>();
98
99
100
101
102
103
104 private final List<Long> idList = new ArrayList<Long>();
105
106
107
108
109
110 private final List<Long> relIdList = new ArrayList<Long>();
111
112
113
114
115
116 private int tableIndex;
117
118
119
120
121 private final AbstractPrintQuery query;
122
123
124
125
126 private Iterator<Object> objectIterator;
127
128
129
130
131 private Iterator<Long> idIterator;
132
133
134
135
136 private Long currentId;
137
138
139
140
141 private Object currentObject;
142
143
144
145
146 private AbstractValueSelect valueSelect;
147
148
149
150
151
152 public OneSelect(final AbstractPrintQuery _query,
153 final String _selectStmt)
154 {
155 this.query = _query;
156 this.selectStmt = _selectStmt;
157 }
158
159
160
161
162
163 public OneSelect(final AbstractPrintQuery _query,
164 final Attribute _attr)
165 {
166 this.query = _query;
167 this.selectStmt = null;
168 this.valueSelect = new AttributeValueSelect(this, _attr);
169 }
170
171
172
173
174
175
176 public AbstractValueSelect getValueSelect()
177 {
178 return this.valueSelect;
179 }
180
181
182
183
184
185
186 public void setValueSelect(final AbstractValueSelect _valueSelect)
187 {
188 this.valueSelect = _valueSelect;
189 }
190
191
192
193
194
195
196 public String getSelectStmt()
197 {
198 return this.selectStmt;
199 }
200
201
202
203
204
205
206 public List<ISelectPart> getSelectParts()
207 {
208 return this.selectParts;
209 }
210
211
212
213
214
215 public void setAttribute(final Attribute _attribute)
216 {
217 this.valueSelect = new AttributeValueSelect(this, _attribute);
218 }
219
220
221
222
223
224
225
226 public void addObject(final Object[] _row)
227 throws SQLException
228 {
229
230 this.idList.add((Long) _row[0]);
231
232 if (getFromSelect() != null) {
233 final int column = "id".equals(this.valueSelect.getValueType())
234 ? this.valueSelect.getColIndexs().get(0) : 2;
235 this.relIdList.add((Long) _row[column - 1]);
236 }
237 Object object = null;
238 AbstractValueSelect tmpValueSelect;
239 if (this.valueSelect == null) {
240 tmpValueSelect = this.fromSelect.getMainOneSelect().getValueSelect();
241 } else {
242 tmpValueSelect = this.valueSelect;
243 }
244 if (tmpValueSelect.getParentSelectPart() != null) {
245 tmpValueSelect.getParentSelectPart().addObject(_row);
246 }
247
248 if (tmpValueSelect.getColIndexs().size() > 1) {
249 final Object[] objArray = new Object[tmpValueSelect.getColIndexs().size()];
250 int i = 0;
251 for (final Integer colIndex : tmpValueSelect.getColIndexs()) {
252 objArray[i] = _row[colIndex - 1];
253 i++;
254 }
255 object = objArray;
256 } else if (tmpValueSelect.getColIndexs().size() > 0) {
257 object = _row[tmpValueSelect.getColIndexs().get(0) - 1];
258 }
259 this.objectList.add(object);
260 }
261
262
263
264
265
266
267
268 public void addClassificationSelectPart(final String _classificationName)
269 throws CacheReloadException
270 {
271 this.selectParts.add(new ClassSelectPart(_classificationName));
272 }
273
274
275
276
277
278
279 public void addLinkToSelectPart(final String _linkTo)
280 {
281 Type type;
282
283
284 if (this.selectParts.size() > 0) {
285 type = this.selectParts.get(this.selectParts.size() - 1).getType();
286 } else {
287 type = this.query.getMainType();
288 }
289 final LinkToSelectPart linkto = new LinkToSelectPart(_linkTo, type);
290 this.selectParts.add(linkto);
291 }
292
293
294
295
296 public void addFileSelectPart()
297 {
298 Type type;
299
300
301 if (this.selectParts.size() > 0) {
302 type = this.selectParts.get(this.selectParts.size() - 1).getType();
303 } else {
304 type = this.query.getMainType();
305 }
306 final FileSelectPart linkto = new FileSelectPart(type);
307 this.selectParts.add(linkto);
308 }
309
310
311
312
313 public void addGenInstSelectPart()
314 {
315 Type type;
316
317
318 if (this.selectParts.size() > 0) {
319 type = this.selectParts.get(this.selectParts.size() - 1).getType();
320 } else {
321 type = this.query.getMainType();
322 }
323 final GenInstSelectPart linkto = new GenInstSelectPart(type);
324 this.selectParts.add(linkto);
325 }
326
327
328
329
330
331
332 public void addAttributeSetSelectPart(final String _attributeSet)
333 {
334 Type type;
335
336
337 if (this.selectParts.size() > 0) {
338 type = this.selectParts.get(this.selectParts.size() - 1).getType();
339 } else {
340 type = this.query.getMainType();
341 }
342
343 try {
344 final AttributeSet set = AttributeSet.find(type.getName(), _attributeSet);
345 final String linkFrom = set.getName() + "#" + set.getAttributeName();
346 this.fromSelect = new LinkFromSelect(linkFrom, getQuery().isCacheEnabled() ? getQuery().getKey() : null);
347 } catch (final CacheReloadException e) {
348 OneSelect.LOG.error("Could not find AttributeSet for Type: {}, attribute: {}", type.getName(),
349 _attributeSet);
350 }
351 }
352
353
354
355
356
357
358
359
360 public void addLinkFromSelectPart(final String _linkFrom)
361 throws CacheReloadException
362 {
363 this.fromSelect = new LinkFromSelect(_linkFrom, getQuery().isCacheEnabled() ? getQuery().getKey() : null);
364 }
365
366
367
368
369
370
371
372 public void append2SQLFrom(final SQLSelect _select)
373 throws EFapsException
374 {
375
376 if (this.valueSelect != null && "attribute".equals(this.valueSelect.getValueType())) {
377 Type type;
378 if (this.selectParts.size() > 0) {
379 type = this.selectParts.get(this.selectParts.size() - 1).getType();
380 } else {
381 type = this.query.getMainType();
382 }
383 Attribute attr = this.valueSelect.getAttribute();
384 if (attr == null) {
385 attr = type.getAttribute(((AttributeValueSelect) this.valueSelect).getAttrName());
386 }
387
388
389 if (attr == null) {
390 for (final Type childType : type.getChildTypes()) {
391 attr = childType.getAttribute(((AttributeValueSelect) this.valueSelect).getAttrName());
392 if (attr != null) {
393 ((AttributeValueSelect) this.valueSelect).setAttribute(attr);
394 break;
395 }
396 }
397 }
398 if (attr != null && attr.getTable() != null && !attr.getTable().equals(type.getMainTable())) {
399 final ChildTableSelectPart childtable = new ChildTableSelectPart(type, attr.getTable());
400 this.selectParts.add(childtable);
401 }
402 }
403 for (final ISelectPart sel : this.selectParts) {
404 this.tableIndex = sel.join(this, _select, this.tableIndex);
405 }
406 }
407
408
409
410
411
412
413
414
415
416 public int append2SQLSelect(final SQLSelect _select,
417 final int _colIndex)
418 throws EFapsException
419 {
420 Type type;
421 if (this.selectParts.size() > 0) {
422 type = this.selectParts.get(this.selectParts.size() - 1).getType();
423 } else {
424 type = this.query.getMainType();
425 }
426 int ret;
427 if (this.valueSelect == null) {
428 ret = this.fromSelect.getMainOneSelect().getValueSelect().append2SQLSelect(type, _select, this.tableIndex,
429 _colIndex);
430 } else {
431 ret = this.valueSelect.append2SQLSelect(type, _select, this.tableIndex, _colIndex);
432 }
433
434 return ret;
435 }
436
437
438
439
440
441
442 public void append2SQLWhere(final SQLSelect _select)
443 {
444 for (final ISelectPart part : this.selectParts) {
445 part.add2Where(this, _select);
446 }
447 }
448
449
450
451
452
453
454 public void analyzeSelectStmt()
455 throws EFapsException
456 {
457 final Pattern mainPattern = Pattern.compile("[a-z]+\\[.+?\\]|[a-z]+");
458 final Pattern attrPattern = Pattern.compile("(?<=\\[)[0-9a-zA-Z_]*(?=\\])");
459 final Pattern esjpPattern = Pattern.compile("(?<=\\[)[\\w\\d\\s,.\"]*(?=\\])");
460 final Pattern linkfomPat = Pattern.compile("(?<=\\[)[0-9a-zA-Z_#:]*(?=\\])");
461 final Pattern formatPat = Pattern.compile("(?<=\\[).*(?=\\])");
462
463 final Matcher mainMatcher = mainPattern.matcher(this.selectStmt);
464
465 OneSelect currentSelect = this;
466 while (mainMatcher.find()) {
467 final String part = mainMatcher.group();
468 if (part.startsWith("class[")) {
469 final Matcher matcher = attrPattern.matcher(part);
470 if (matcher.find()) {
471 currentSelect.addClassificationSelectPart(matcher.group());
472 }
473 } else if (part.startsWith("linkto")) {
474 final Matcher matcher = attrPattern.matcher(part);
475 if (matcher.find()) {
476 currentSelect.addLinkToSelectPart(matcher.group());
477 }
478 } else if (part.startsWith("attributeset")) {
479 final Matcher matcher = attrPattern.matcher(part);
480 if (matcher.find()) {
481 currentSelect.addValueSelect(new IDValueSelect(currentSelect));
482 currentSelect.addAttributeSetSelectPart(matcher.group());
483 currentSelect = currentSelect.fromSelect.getMainOneSelect();
484 }
485 } else if (part.startsWith("attribute")) {
486 final Matcher matcher = attrPattern.matcher(part);
487 if (matcher.find()) {
488 currentSelect.addValueSelect(new AttributeValueSelect(currentSelect, matcher.group()));
489 }
490 } else if (part.startsWith("linkfrom")) {
491 final Matcher matcher = linkfomPat.matcher(part);
492 if (matcher.find()) {
493 currentSelect.addValueSelect(new IDValueSelect(currentSelect));
494 currentSelect.addLinkFromSelectPart(matcher.group());
495 currentSelect = currentSelect.fromSelect.getMainOneSelect();
496 }
497 } else if (part.startsWith("format")) {
498 final Matcher matcher = formatPat.matcher(part);
499 if (matcher.find()) {
500 currentSelect.addValueSelect(new FormatValueSelect(currentSelect, matcher.group()));
501 }
502 } else if (part.startsWith("esjp[")) {
503 final Matcher matcher = esjpPattern.matcher(part);
504 if (matcher.find()) {
505 currentSelect.addValueSelect(new EsjpValueSelect(currentSelect, matcher.group()));
506 }
507 } else
508 switch (part) {
509 case "oid":
510 currentSelect.addValueSelect(new OIDValueSelect(currentSelect));
511 break;
512 case "type":
513 currentSelect.addValueSelect(new TypeValueSelect(currentSelect));
514 break;
515 case "instance":
516 currentSelect.addValueSelect(new InstanceValueSelect(currentSelect));
517 break;
518 case "label":
519 currentSelect.addValueSelect(new LabelValueSelect(currentSelect));
520 break;
521 case "id":
522 currentSelect.addValueSelect(new IDValueSelect(currentSelect));
523 break;
524 case "uuid":
525 currentSelect.addValueSelect(new UUIDValueSelect(currentSelect));
526 break;
527 case "name":
528 currentSelect.addValueSelect(new NameValueSelect(currentSelect));
529 break;
530 case "class":
531 currentSelect.addValueSelect(new ClassificationValueSelect(currentSelect));
532 break;
533 case "value":
534 currentSelect.addValueSelect(new ValueValueSelect(currentSelect));
535 break;
536 case "base":
537 currentSelect.addValueSelect(new BaseValueSelect(currentSelect));
538 break;
539 case "uom":
540 currentSelect.addValueSelect(new UoMValueSelect(currentSelect));
541 break;
542 case "file":
543 currentSelect.addFileSelectPart();
544 break;
545 case "length":
546 currentSelect.addValueSelect(new LengthValueSelect(currentSelect));
547 break;
548 case "status":
549 currentSelect.addValueSelect(new StatusValueSelect(currentSelect));
550 break;
551 case "key":
552 currentSelect.addValueSelect(new KeyValueSelect(currentSelect));
553 break;
554 default:
555 break;
556 }
557 }
558 }
559
560
561
562
563
564 private void addValueSelect(final AbstractValueSelect _valueSelect)
565 throws EFapsException
566 {
567 if (this.valueSelect != null) {
568 this.valueSelect.addChildValueSelect(_valueSelect);
569 } else if (this.fromSelect != null && !(this.query instanceof LinkFromSelect)) {
570 this.fromSelect.getMainOneSelect().addValueSelect(_valueSelect);
571 } else {
572 this.valueSelect = _valueSelect;
573 }
574 }
575
576
577
578
579
580
581
582
583
584 private Object getObject(final Object _object)
585 throws EFapsException
586 {
587 final Object ret;
588
589 if (this.fromSelect != null && _object instanceof Number) {
590 final List<Object> tmpList = new ArrayList<Object>();
591 final Long id = ((Number) _object).longValue();
592 final Iterator<Long> relIter = this.relIdList.iterator();
593 final Iterator<Object> objIter = this.objectList.iterator();
594 while (relIter.hasNext()) {
595 final Long rel = relIter.next();
596 final Object obj = objIter.next();
597 if (rel.equals(id)) {
598 tmpList.add(obj);
599 }
600 }
601 ret = this.valueSelect.getValue(tmpList);
602 } else {
603 ret = this.getObject();
604 }
605 return ret;
606 }
607
608
609
610
611
612
613 public Object getObject()
614 throws EFapsException
615 {
616 Object ret = null;
617 if (this.valueSelect == null) {
618
619 if (this.fromSelect.hasResult()) {
620
621 if (this.idList.size() > 1 && this.currentObject != null) {
622 ret = this.fromSelect.getMainOneSelect().getObject(this.currentObject);
623
624 } else if (this.idList.size() == 1 && this.objectList.get(0) != null) {
625 ret = this.fromSelect.getMainOneSelect().getObject(this.currentObject);
626 }
627 }
628 } else {
629
630
631 if (this.currentId != null) {
632 ret = this.valueSelect.getValue(this.currentObject);
633 } else {
634 ret = this.valueSelect.getValue(this.objectList);
635 }
636 }
637 return ret;
638 }
639
640
641
642
643
644
645
646 @SuppressWarnings("unchecked")
647 public List<Instance> getInstances()
648 throws EFapsException
649 {
650 final List<Instance> ret = new ArrayList<Instance>();
651
652 if (this.valueSelect == null) {
653 ret.addAll(this.fromSelect.getMainOneSelect().getInstances());
654 } else {
655
656 if ("oid".equals(this.valueSelect.getValueType())) {
657 for (final Object object : this.objectList) {
658 final Instance inst = Instance.get((String) this.valueSelect.getValue(object));
659 if (inst.isValid()) {
660 ret.add(inst);
661 }
662 }
663 } else {
664 List<Long> idTmp;
665 if (this.valueSelect.getParentSelectPart() != null
666 && this.valueSelect.getParentSelectPart() instanceof LinkToSelectPart) {
667 idTmp = (List<Long>) this.valueSelect.getParentSelectPart().getObject();
668 } else {
669 idTmp = this.idList;
670 }
671 for (final Long id : idTmp) {
672 if (id != null) {
673 ret.add(Instance.get(this.valueSelect.getAttribute().getParent(), String.valueOf(id)));
674 }
675 }
676 }
677 }
678 return ret;
679 }
680
681
682
683
684
685
686 public Attribute getAttribute()
687 {
688 Attribute ret;
689 if (this.valueSelect == null) {
690 ret = this.fromSelect.getMainOneSelect().getAttribute();
691 } else {
692 ret = this.valueSelect.getAttribute();
693 }
694 return ret;
695 }
696
697
698
699
700
701
702 public LinkFromSelect getFromSelect()
703 {
704 return this.fromSelect;
705 }
706
707
708
709
710
711
712 public void setFromSelect(final LinkFromSelect _fromSelect)
713 {
714 this.fromSelect = _fromSelect;
715 }
716
717
718
719
720
721
722
723 private boolean isMultiple(final Object _object)
724 throws EFapsException
725 {
726 boolean ret;
727 if (_object instanceof Long && this.fromSelect != null) {
728 final Object object = this.getObject(_object);
729 if (object instanceof List<?>) {
730 ret = true;
731 } else {
732 ret = false;
733 }
734 } else {
735 ret = this.isMultiple();
736 }
737 return ret;
738 }
739
740
741
742
743
744
745 public boolean isMultiple()
746 throws EFapsException
747 {
748 boolean ret;
749 if (this.valueSelect == null) {
750 ret = this.fromSelect.getMainOneSelect().isMultiple(this.currentObject);
751 } else {
752 ret = this.objectList.size() > 1;
753 }
754 return ret;
755 }
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771 public Integer getNewTableIndex(final String _tableName,
772 final String _column,
773 final Integer _relIndex,
774 final Long _clazzId)
775 {
776 int ret;
777 if (this.valueSelect == null && this.fromSelect != null) {
778 ret = this.fromSelect.getNewTableIndex(_tableName, _column, _relIndex, _clazzId);
779 } else {
780 ret = this.query.getNewTableIndex(_tableName, _column, _relIndex, _clazzId);
781 }
782 return ret;
783 }
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799 public Integer getTableIndex(final String _tableName,
800 final String _column,
801 final int _relIndex,
802 final Long _clazzId)
803 {
804 Integer ret;
805 if (this.valueSelect == null && this.fromSelect != null) {
806 ret = this.fromSelect.getTableIndex(_tableName, _column, _relIndex, _clazzId);
807 } else {
808 ret = this.query.getTableIndex(_tableName, _column, _relIndex, _clazzId);
809 }
810 return ret;
811 }
812
813
814
815
816
817 public boolean next()
818 throws EFapsException
819 {
820 boolean ret = false;
821 if (this.objectIterator == null) {
822 this.objectIterator = this.objectList.iterator();
823 }
824 if (this.idIterator == null) {
825 this.idIterator = this.idList.iterator();
826 }
827 if (this.objectIterator.hasNext()) {
828 this.currentObject = this.objectIterator.next();
829 this.currentId = this.idIterator.next();
830 ret = true;
831 for (final ISelectPart part : getSelectParts()) {
832 part.next();
833 }
834 }
835 return ret;
836 }
837
838
839
840
841
842
843 public AbstractPrintQuery getQuery()
844 {
845 return this.query;
846 }
847
848
849
850
851
852
853 public List<Object> getObjectList()
854 {
855 return this.objectList;
856 }
857
858
859
860
861
862
863 public void sortByInstanceList(final List<Instance> _targetList,
864 final Map<Instance, Integer> _currentList)
865 {
866 final List<Long> idListNew = new ArrayList<Long>();
867 final List<Object> objectListNew = new ArrayList<Object>();
868 for (final Instance instance : _targetList) {
869 if (_currentList.containsKey(instance)) {
870 final Integer i = _currentList.get(instance);
871 idListNew.add(this.idList.get(i));
872 objectListNew.add(this.objectList.get(i));
873 }
874 }
875 this.idList.clear();
876 this.idList.addAll(idListNew);
877 this.objectList.clear();
878 this.objectList.addAll(objectListNew);
879 }
880
881 @Override
882 public String toString()
883 {
884 return ToStringBuilder.reflectionToString(this);
885 }
886 }