1 package org.exoplatform.wiki.service.search.jcr;
2
3 import org.apache.commons.lang.StringUtils;
4 import org.chromattic.api.NoSuchNodeException;
5 import org.chromattic.api.UndeclaredRepositoryException;
6 import org.exoplatform.container.ExoContainerContext;
7 import org.exoplatform.portal.config.model.PortalConfig;
8 import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
9 import org.exoplatform.wiki.mow.core.api.wiki.WikiNodeType;
10 import org.exoplatform.wiki.service.search.WikiSearchData;
11 import org.exoplatform.wiki.utils.JCRUtils;
12 import org.exoplatform.wiki.utils.WikiConstants;
13
14 import javax.jcr.Node;
15 import javax.jcr.PathNotFoundException;
16 import java.util.ArrayList;
17 import java.util.List;
18
19
20
21
22 public class JCRWikiSearchQueryBuilder {
23
24 public static final String ALL_PATH = "%/";
25
26 protected static String PORTAL_PATH = "/exo:applications/"
27 + WikiNodeType.Definition.WIKI_APPLICATION + "/"
28 + WikiNodeType.Definition.WIKIS + "/%/";
29
30 protected static String GROUP_PATH = "/Groups/%/ApplicationData/"
31 + WikiNodeType.Definition.WIKI_APPLICATION + "/";
32
33 protected String USER_PATH = "/Users/%/ApplicationData/" + WikiNodeType.Definition.WIKI_APPLICATION + "/";
34
35 public static String ALL_PAGESPATH = ALL_PATH + WikiConstants.WIKI_HOME_NAME;
36
37 public static String PORTAL_PAGESPATH = PORTAL_PATH + WikiConstants.WIKI_HOME_NAME;
38
39 public static String GROUP_PAGESPATH = GROUP_PATH + WikiConstants.WIKI_HOME_NAME;
40
41 public static String ASC_ORDER = "ASC";
42
43 public static String DESC_ORDER = "DESC";
44
45 private WikiSearchData wikiSearchData;
46
47 private String pagePath = "";
48
49 protected List<String> propertyConstraints = new ArrayList<>();
50
51 public JCRWikiSearchQueryBuilder(WikiSearchData wikiSearchData) {
52 this.wikiSearchData = wikiSearchData;
53
54 if (PortalConfig.USER_TYPE.equals(wikiSearchData.getWikiType())) {
55 NodeHierarchyCreator nodeHierachyCreator = ExoContainerContext.getCurrentContainer().getComponentInstanceOfType(NodeHierarchyCreator.class);
56 try {
57 if (wikiSearchData.getWikiOwner() != null && wikiSearchData.getWikiOwner().length() > 0) {
58 Node userNode = nodeHierachyCreator.getUserApplicationNode(JCRUtils.createSystemProvider(), wikiSearchData.getWikiOwner());
59 USER_PATH = userNode.getPath() + "/" + WikiNodeType.Definition.WIKI_APPLICATION + "/";
60 }
61 } catch (Exception e) {
62 if (e instanceof PathNotFoundException) {
63 throw new NoSuchNodeException(e);
64 } else {
65 throw new UndeclaredRepositoryException(e.getMessage());
66 }
67 }
68 }
69 this.propertyConstraints = new ArrayList<>();
70
71 initJcrQueryPath();
72 }
73
74 public List<String> getPropertyConstraints() {
75 return new ArrayList<String>(this.propertyConstraints);
76 }
77
78 public void addPropertyConstraints(List<String> value) {
79 if (value != null) {
80 propertyConstraints.addAll(value);
81 }
82 }
83
84 public void addPropertyConstraint(String value) {
85 if (StringUtils.isNotBlank(value)) {
86 propertyConstraints.add(value);
87 }
88 }
89
90 public void initJcrQueryPath() {
91 if (wikiSearchData.getWikiType() == null && wikiSearchData.getWikiOwner() == null) {
92 pagePath = ALL_PAGESPATH;
93 } else if (wikiSearchData.getWikiType() != null) {
94 if (wikiSearchData.getWikiType().equals(PortalConfig.USER_TYPE)){
95 pagePath = USER_PATH + WikiConstants.WIKI_HOME_NAME;
96 } else {
97 if (wikiSearchData.getWikiType().equals(PortalConfig.PORTAL_TYPE)) {
98 pagePath = PORTAL_PAGESPATH;
99 } else if (wikiSearchData.getWikiType().equals(PortalConfig.GROUP_TYPE)) {
100 pagePath = GROUP_PAGESPATH;
101 }
102
103 if (wikiSearchData.getWikiOwner() != null && wikiSearchData.getWikiOwner().length() > 0) {
104 pagePath = pagePath.replaceFirst("%", wikiSearchData.getWikiOwner());
105 }
106 }
107 }
108 }
109
110 public String getStatementForSearchingTitle() {
111 StringBuilder statement = new StringBuilder();
112 statement.append("SELECT title, jcr:primaryType, path, excerpt(.) FROM nt:base WHERE ");
113 statement.append(createJcrQueryPathClause());
114 statement.append(searchTitleCondition());
115 statement.append(createOrderClause());
116 return statement.toString();
117 }
118
119 public String getStatementForSearchingContent() {
120 StringBuilder statement = new StringBuilder();
121 statement.append("SELECT jcr:primaryType, path, excerpt(.) FROM wiki:attachment WHERE ");
122 statement.append(createJcrQueryPathClause());
123 statement.append(searchContentCondition());
124 statement.append(createOrderClause());
125 return statement.toString();
126 }
127
128 private String createJcrQueryPathClause() {
129 return "(jcr:path LIKE '" + pagePath + "/%')";
130 }
131
132 private String createOrderClause() {
133 StringBuffer clause = new StringBuffer();
134 if (isOrderValid(wikiSearchData.getOrder()) && StringUtils.isNotEmpty(wikiSearchData.getSort())) {
135 clause.append(" ORDER BY ");
136 clause.append(wikiSearchData.getSort());
137 clause.append(" ");
138 clause.append(wikiSearchData.getOrder());
139 }
140 return clause.toString();
141 }
142
143 private boolean isOrderValid(String order) {
144 return ASC_ORDER.equals(order) || DESC_ORDER.equals(order) || "".equals(order);
145 }
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 public String getPageConstraint() {
163 StringBuilder constraint = new StringBuilder();
164
165 String absPagePath = pagePath + "/" + wikiSearchData.getPageId();
166 String pageLikePath = pagePath + "/%/" + wikiSearchData.getPageId();
167 boolean isWikiHome = false;
168 if (WikiConstants.WIKI_HOME_NAME.equals(wikiSearchData.getPageId())) {
169 absPagePath = pagePath;
170 isWikiHome = true;
171 }
172 if (wikiSearchData.getWikiType() == null || wikiSearchData.getWikiOwner() == null) {
173 absPagePath = "/" + wikiSearchData.getPageId();
174 pageLikePath = "/%/" + wikiSearchData.getPageId();
175 }
176 constraint.append('(').append('(').append("jcr:path LIKE '").append(pageLikePath).append('\'');
177 if (!isWikiHome)
178 constraint.append(" or (jcr:path = '").append(absPagePath).append('\'').append(')');
179 constraint.append(")")
180 .append(" AND ")
181 .append("(jcr:mixinTypes IS NULL OR NOT (jcr:mixinTypes = 'wiki:removed'))")
182 .append(')');
183 return constraint.toString();
184 }
185
186 private String searchContentCondition() {
187 StringBuilder clause = new StringBuilder();
188 if (wikiSearchData.getContent() != null && wikiSearchData.getContent().length() > 0 && !"*".equals(wikiSearchData.getContent())) {
189 clause.append(" AND ");
190 clause.append(" CONTAINS(*, '").append(wikiSearchData.getContent()).append("')");
191 }
192 return clause.toString();
193 }
194
195 private String searchTitleCondition() {
196 StringBuilder clause = new StringBuilder();
197 if (wikiSearchData.getTitle() != null && wikiSearchData.getTitle().length() > 0) {
198 clause.append(" AND ");
199 clause.append(" CONTAINS(title, '").append(wikiSearchData.getTitle()).append("')");
200 }
201 return clause.toString();
202 }
203
204 }