001
014
015 package com.liferay.portlet.dynamicdatamapping.storage;
016
017 import com.liferay.portal.kernel.util.ArrayUtil;
018 import com.liferay.portal.kernel.util.HtmlUtil;
019 import com.liferay.portal.kernel.util.OrderByComparator;
020 import com.liferay.portal.kernel.util.StringBundler;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.kernel.util.StringUtil;
023 import com.liferay.portal.kernel.xml.Document;
024 import com.liferay.portal.kernel.xml.SAXReaderUtil;
025 import com.liferay.portal.kernel.xml.XPath;
026 import com.liferay.portal.service.ServiceContext;
027 import com.liferay.portal.util.PortalUtil;
028 import com.liferay.portlet.dynamicdatamapping.model.DDMContent;
029 import com.liferay.portlet.dynamicdatamapping.model.DDMStorageLink;
030 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
031 import com.liferay.portlet.dynamicdatamapping.service.DDMContentLocalServiceUtil;
032 import com.liferay.portlet.dynamicdatamapping.service.DDMStorageLinkLocalServiceUtil;
033 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
034 import com.liferay.portlet.dynamicdatamapping.storage.query.ComparisonOperator;
035 import com.liferay.portlet.dynamicdatamapping.storage.query.Condition;
036 import com.liferay.portlet.dynamicdatamapping.storage.query.FieldCondition;
037 import com.liferay.portlet.dynamicdatamapping.storage.query.FieldConditionImpl;
038 import com.liferay.portlet.dynamicdatamapping.storage.query.Junction;
039 import com.liferay.portlet.dynamicdatamapping.storage.query.LogicalOperator;
040 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
041 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
042
043 import java.util.ArrayList;
044 import java.util.Collections;
045 import java.util.HashMap;
046 import java.util.Iterator;
047 import java.util.List;
048 import java.util.Map;
049
050
054 public class XMLStorageAdapter extends BaseStorageAdapter {
055
056 @Override
057 protected long doCreate(
058 long companyId, long ddmStructureId, Fields fields,
059 ServiceContext serviceContext)
060 throws Exception {
061
062 long classNameId = PortalUtil.getClassNameId(
063 DDMContent.class.getName());
064
065 DDMContent ddmContent = DDMContentLocalServiceUtil.addContent(
066 serviceContext.getUserId(), serviceContext.getScopeGroupId(),
067 DDMStorageLink.class.getName(), null, DDMXMLUtil.getXML(fields),
068 serviceContext);
069
070 DDMStorageLinkLocalServiceUtil.addStorageLink(
071 classNameId, ddmContent.getPrimaryKey(), ddmStructureId,
072 serviceContext);
073
074 return ddmContent.getPrimaryKey();
075 }
076
077 @Override
078 protected void doDeleteByClass(long classPK) throws Exception {
079 DDMContentLocalServiceUtil.deleteDDMContent(classPK);
080
081 DDMStorageLinkLocalServiceUtil.deleteClassStorageLink(classPK);
082 }
083
084 @Override
085 protected void doDeleteByDDMStructure(long ddmStructureId)
086 throws Exception {
087
088 List<DDMStorageLink> ddmStorageLinks =
089 DDMStorageLinkLocalServiceUtil.getStructureStorageLinks(
090 ddmStructureId);
091
092 for (DDMStorageLink ddmStorageLink : ddmStorageLinks) {
093 DDMContentLocalServiceUtil.deleteDDMContent(
094 ddmStorageLink.getClassPK());
095 }
096
097 DDMStorageLinkLocalServiceUtil.deleteStructureStorageLinks(
098 ddmStructureId);
099 }
100
101 @Override
102 protected List<Fields> doGetFieldsListByClasses(
103 long ddmStructureId, long[] classPKs, List<String> fieldNames,
104 OrderByComparator orderByComparator)
105 throws Exception {
106
107 return _doQuery(
108 ddmStructureId, classPKs, fieldNames, null, orderByComparator);
109 }
110
111 @Override
112 protected List<Fields> doGetFieldsListByDDMStructure(
113 long ddmStructureId, List<String> fieldNames,
114 OrderByComparator orderByComparator)
115 throws Exception {
116
117 return _doQuery(ddmStructureId, fieldNames, null, orderByComparator);
118 }
119
120 @Override
121 protected Map<Long, Fields> doGetFieldsMapByClasses(
122 long ddmStructureId, long[] classPKs, List<String> fieldNames)
123 throws Exception {
124
125 return _doQuery(ddmStructureId, classPKs, fieldNames);
126 }
127
128 @Override
129 protected List<Fields> doQuery(
130 long ddmStructureId, List<String> fieldNames, Condition condition,
131 OrderByComparator orderByComparator)
132 throws Exception {
133
134 return _doQuery(
135 ddmStructureId, fieldNames, condition, orderByComparator);
136 }
137
138 @Override
139 protected int doQueryCount(long ddmStructureId, Condition condition)
140 throws Exception {
141
142 XPath conditionXPath = null;
143
144 if (condition != null) {
145 conditionXPath = _parseCondition(condition);
146 }
147
148 int count = 0;
149
150 long[] classPKs = _getStructureClassPKs(ddmStructureId);
151
152 for (long classPK : classPKs) {
153 DDMContent ddmContent = DDMContentLocalServiceUtil.getContent(
154 classPK);
155
156 Document document = SAXReaderUtil.read(ddmContent.getXml());
157
158 if ((conditionXPath == null) ||
159 ((conditionXPath != null) &&
160 conditionXPath.booleanValueOf(document))) {
161
162 count++;
163 }
164 }
165
166 return count;
167 }
168
169 @Override
170 protected void doUpdate(
171 long classPK, Fields fields, boolean mergeFields,
172 ServiceContext serviceContext)
173 throws Exception {
174
175 DDMContent ddmContent = DDMContentLocalServiceUtil.getContent(classPK);
176
177 ddmContent.setModifiedDate(serviceContext.getModifiedDate(null));
178
179 if (mergeFields) {
180 fields = DDMUtil.mergeFields(fields, getFields(classPK));
181 }
182
183 ddmContent.setXml(DDMXMLUtil.getXML(fields));
184
185 DDMContentLocalServiceUtil.updateContent(
186 ddmContent.getPrimaryKey(), ddmContent.getName(),
187 ddmContent.getDescription(), ddmContent.getXml(), serviceContext);
188 }
189
190 private List<Fields> _doQuery(
191 long ddmStructureId, List<String> fieldNames, Condition condition,
192 OrderByComparator orderByComparator)
193 throws Exception {
194
195 return _doQuery(
196 ddmStructureId, _getStructureClassPKs(ddmStructureId), fieldNames,
197 condition, orderByComparator);
198 }
199
200 private Map<Long, Fields> _doQuery(
201 long ddmStructureId, long[] classPKs, List<String> fieldNames)
202 throws Exception {
203
204 Map<Long, Fields> fieldsMap = new HashMap<Long, Fields>();
205
206 List<Fields> fieldsList = _doQuery(
207 ddmStructureId, classPKs, fieldNames, null, null);
208
209 for (int i = 0; i < fieldsList.size(); i++) {
210 Fields fields = fieldsList.get(i);
211
212 fieldsMap.put(classPKs[i], fields);
213 }
214
215 return fieldsMap;
216 }
217
218 private List<Fields> _doQuery(
219 long ddmStructureId, long[] classPKs, List<String> fieldNames,
220 Condition condition, OrderByComparator orderByComparator)
221 throws Exception {
222
223 List<Fields> fieldsList = new ArrayList<Fields>();
224
225 XPath conditionXPath = null;
226
227 if (condition != null) {
228 conditionXPath = _parseCondition(condition);
229 }
230
231 DDMStructure ddmStructure =
232 DDMStructureLocalServiceUtil.getDDMStructure(ddmStructureId);
233
234 for (long classPK : classPKs) {
235 DDMContent ddmContent = DDMContentLocalServiceUtil.getContent(
236 classPK);
237
238 Fields fields = DDMXMLUtil.getFields(
239 ddmStructure, conditionXPath, ddmContent.getXml(), fieldNames);
240
241 fieldsList.add(fields);
242 }
243
244 if (orderByComparator != null) {
245 Collections.sort(fieldsList, orderByComparator);
246 }
247
248 return fieldsList;
249 }
250
251 private long[] _getStructureClassPKs(long ddmStructureId) throws Exception {
252 List<Long> classPKs = new ArrayList<Long>();
253
254 List<DDMStorageLink> ddmStorageLinks =
255 DDMStorageLinkLocalServiceUtil.getStructureStorageLinks(
256 ddmStructureId);
257
258 for (DDMStorageLink ddmStorageLink : ddmStorageLinks) {
259 classPKs.add(ddmStorageLink.getClassPK());
260 }
261
262 return ArrayUtil.toArray(classPKs.toArray(new Long[classPKs.size()]));
263 }
264
265 private XPath _parseCondition(Condition condition) {
266 StringBundler sb = new StringBundler(4);
267
268 sb.append("
269 sb.append(StringPool.OPEN_BRACKET);
270 sb.append(_toXPath(condition));
271 sb.append(StringPool.CLOSE_BRACKET);
272
273 return SAXReaderUtil.createXPath(sb.toString());
274 }
275
276 private String _toXPath(Condition condition) {
277 StringBundler sb = new StringBundler();
278
279 if (condition.isJunction()) {
280 sb.append(StringPool.OPEN_PARENTHESIS);
281 sb.append(_toXPath((Junction)condition));
282 sb.append(StringPool.CLOSE_PARENTHESIS);
283 }
284 else {
285 sb.append(_toXPath((FieldConditionImpl)condition));
286 }
287
288 return sb.toString();
289 }
290
291 private String _toXPath(FieldCondition fieldCondition) {
292 StringBundler sb = new StringBundler(6);
293
294 sb.append("(@name=");
295
296 String name = HtmlUtil.escapeXPathAttribute(
297 String.valueOf(fieldCondition.getName()));
298
299 sb.append(name);
300
301 ComparisonOperator comparisonOperator =
302 fieldCondition.getComparisonOperator();
303
304 if (comparisonOperator.equals(ComparisonOperator.LIKE)) {
305 sb.append(" and matches(dynamic-content, ");
306 }
307 else {
308 sb.append(" and dynamic-content= ");
309 }
310
311 String value = HtmlUtil.escapeXPathAttribute(
312 String.valueOf(fieldCondition.getValue()));
313
314 sb.append(value);
315
316 if (comparisonOperator.equals(ComparisonOperator.LIKE)) {
317 sb.append(StringPool.CLOSE_PARENTHESIS);
318 }
319
320 sb.append(StringPool.CLOSE_PARENTHESIS);
321
322 return sb.toString();
323 }
324
325 private String _toXPath(Junction junction) {
326 StringBundler sb = new StringBundler();
327
328 LogicalOperator logicalOperator = junction.getLogicalOperator();
329
330 String logicalOperatorString = logicalOperator.toString();
331
332 Iterator<Condition> itr = junction.iterator();
333
334 while (itr.hasNext()) {
335 Condition condition = itr.next();
336
337 sb.append(_toXPath(condition));
338
339 if (itr.hasNext()) {
340 sb.append(StringPool.SPACE);
341 sb.append(StringUtil.toLowerCase(logicalOperatorString));
342 sb.append(StringPool.SPACE);
343 }
344 }
345
346 return sb.toString();
347 }
348
349 }