]> git.argeo.org Git - gpl/argeo-jcr.git/blob - org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/BasicSearchToQom.java
Optimisation and caching
[gpl/argeo-jcr.git] / org.argeo.cms.jcr / src / org / argeo / cms / jcr / acr / BasicSearchToQom.java
1 package org.argeo.cms.jcr.acr;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.jcr.RepositoryException;
7 import javax.jcr.Session;
8 import javax.jcr.query.QueryManager;
9 import javax.jcr.query.qom.DynamicOperand;
10 import javax.jcr.query.qom.QueryObjectModel;
11 import javax.jcr.query.qom.QueryObjectModelConstants;
12 import javax.jcr.query.qom.QueryObjectModelFactory;
13 import javax.jcr.query.qom.Selector;
14 import javax.jcr.query.qom.StaticOperand;
15 import javax.xml.namespace.QName;
16
17 import org.apache.jackrabbit.commons.query.sql2.QOMFormatter;
18 import org.argeo.api.acr.NamespaceUtils;
19 import org.argeo.api.acr.search.BasicSearch;
20 import org.argeo.api.acr.search.Constraint;
21 import org.argeo.api.acr.search.ContentFilter;
22 import org.argeo.api.acr.search.ContentFilter.Eq;
23 import org.argeo.api.acr.search.ContentFilter.IsContentClass;
24 import org.argeo.api.acr.search.ContentFilter.Not;
25 import org.argeo.api.cms.CmsLog;
26
27 /** Convert an ACR basic search to a JCR query. */
28 class BasicSearchToQom {
29 private final static CmsLog log = CmsLog.getLog(BasicSearchToQom.class);
30
31 private Session session;
32 private QueryManager queryManager;
33 private BasicSearch basicSearch;
34 QueryObjectModelFactory factory;
35
36 QName contentClass = null;
37
38 String selectorName = "content";
39
40 public BasicSearchToQom(Session session, BasicSearch basicSearch, String relPath) throws RepositoryException {
41 this.session = session;
42 this.queryManager = session.getWorkspace().getQueryManager();
43 this.basicSearch = basicSearch;
44 factory = queryManager.getQOMFactory();
45 }
46
47 public QueryObjectModel createQuery() throws RepositoryException {
48 ContentFilter<?> where = basicSearch.getWhere();
49 // scan for content classes
50 // TODO deal with complex cases of multiple types
51
52 javax.jcr.query.qom.Constraint qomConstraint = toQomConstraint(where);
53 if (contentClass == null)
54 throw new IllegalArgumentException("No content class specified");
55
56 Selector source = factory.selector(NamespaceUtils.toPrefixedName(contentClass), selectorName);
57
58 QueryObjectModel qom = factory.createQuery(source, qomConstraint, null, null);
59 if (log.isDebugEnabled()) {
60 String sql2 = QOMFormatter.format(qom);
61 log.debug("JCR query:\n" + sql2 + "\n");
62 }
63 return qom;
64 }
65
66 private javax.jcr.query.qom.Constraint toQomConstraint(Constraint constraint) throws RepositoryException {
67 javax.jcr.query.qom.Constraint qomConstraint;
68 if (constraint instanceof ContentFilter<?> where) {
69 List<Constraint> constraints = new ArrayList<>();
70 for (Constraint c : where.getConstraints()) {
71 if (c instanceof IsContentClass icc) {
72 if (icc.getContentClasses().length > 1 || contentClass != null)
73 throw new IllegalArgumentException("Multiple content class is not supported");
74 contentClass = icc.getContentClasses()[0];
75 } else {
76 constraints.add(c);
77 }
78 }
79
80 if (constraints.isEmpty()) {
81 qomConstraint = null;
82 } else if (constraints.size() == 1) {
83 qomConstraint = toQomConstraint(constraints.get(0));
84 } else {
85 javax.jcr.query.qom.Constraint currQomConstraint = toQomConstraint(constraints.get(0));
86 for (int i = 1; i < constraints.size(); i++) {
87 Constraint c = constraints.get(i);
88 if (where.isUnion()) {
89 currQomConstraint = factory.or(currQomConstraint, toQomConstraint(c));
90 } else {
91 currQomConstraint = factory.and(currQomConstraint, toQomConstraint(c));
92 }
93 }
94 qomConstraint = currQomConstraint;
95 }
96
97 } else if (constraint instanceof Eq comp) {
98 DynamicOperand dynamicOperand = factory.propertyValue(selectorName,
99 NamespaceUtils.toPrefixedName(comp.getProp()));
100 // TODO better convert attribute value
101 StaticOperand staticOperand = factory
102 .literal(session.getValueFactory().createValue(comp.getValue().toString()));
103 qomConstraint = factory.comparison(dynamicOperand, QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO,
104 staticOperand);
105 } else if (constraint instanceof Not not) {
106 qomConstraint = factory.not(toQomConstraint(not.getNegated()));
107 } else {
108 throw new IllegalArgumentException("Constraint " + constraint.getClass() + " is not supported");
109 }
110 return qomConstraint;
111 }
112 }