Java tutorial
/** * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portlet.dynamicdatamapping.storage; import com.liferay.counter.service.CounterLocalServiceUtil; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.OrderByComparator; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.service.ServiceContext; import com.liferay.portal.util.PortalUtil; import com.liferay.portlet.dynamicdatamapping.model.DDMStorageLink; import com.liferay.portlet.dynamicdatamapping.model.DDMStructure; import com.liferay.portlet.dynamicdatamapping.service.DDMStorageLinkLocalServiceUtil; import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil; import com.liferay.portlet.dynamicdatamapping.storage.query.ComparisonOperator; import com.liferay.portlet.dynamicdatamapping.storage.query.Condition; import com.liferay.portlet.dynamicdatamapping.storage.query.FieldCondition; import com.liferay.portlet.dynamicdatamapping.storage.query.Junction; import com.liferay.portlet.dynamicdatamapping.storage.query.LogicalOperator; import com.liferay.portlet.expando.NoSuchTableException; import com.liferay.portlet.expando.model.ExpandoColumn; import com.liferay.portlet.expando.model.ExpandoColumnConstants; import com.liferay.portlet.expando.model.ExpandoRow; import com.liferay.portlet.expando.model.ExpandoTable; import com.liferay.portlet.expando.model.ExpandoValue; import com.liferay.portlet.expando.service.ExpandoColumnLocalServiceUtil; import com.liferay.portlet.expando.service.ExpandoRowLocalServiceUtil; import com.liferay.portlet.expando.service.ExpandoTableLocalServiceUtil; import com.liferay.portlet.expando.service.ExpandoValueLocalServiceUtil; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.springframework.expression.EvaluationException; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.ParseException; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; /** * @author Eduardo Lundgren * @author Brian Wing Shun Chan * @author Marcellus Tavares */ public class ExpandoStorageAdapter extends BaseStorageAdapter { @Override protected long doCreate(long companyId, long ddmStructureId, Fields fields, ServiceContext serviceContext) throws Exception { ExpandoTable expandoTable = _getExpandoTable(companyId, ddmStructureId, fields); ExpandoRow expandoRow = ExpandoRowLocalServiceUtil.addRow(expandoTable.getTableId(), CounterLocalServiceUtil.increment()); _updateFields(expandoTable, expandoRow.getClassPK(), fields); DDMStorageLinkLocalServiceUtil.addStorageLink(expandoTable.getClassNameId(), expandoRow.getRowId(), ddmStructureId, serviceContext); return expandoRow.getRowId(); } @Override protected void doDeleteByClass(long classPK) throws Exception { ExpandoRowLocalServiceUtil.deleteRow(classPK); DDMStorageLinkLocalServiceUtil.deleteClassStorageLink(classPK); } @Override protected void doDeleteByDDMStructure(long ddmStructureId) throws Exception { List<DDMStorageLink> ddmStorageLinks = DDMStorageLinkLocalServiceUtil .getStructureStorageLinks(ddmStructureId); for (DDMStorageLink ddmStorageLink : ddmStorageLinks) { ExpandoRowLocalServiceUtil.deleteRow(ddmStorageLink.getClassPK()); } DDMStorageLinkLocalServiceUtil.deleteStructureStorageLinks(ddmStructureId); } @Override protected List<Fields> doGetFieldsListByClasses(long ddmStructureId, long[] classPKs, List<String> fieldNames, OrderByComparator orderByComparator) throws Exception { return _doQuery(ddmStructureId, classPKs, fieldNames, null, orderByComparator); } @Override protected List<Fields> doGetFieldsListByDDMStructure(long ddmStructureId, List<String> fieldNames, OrderByComparator orderByComparator) throws Exception { return _doQuery(ddmStructureId, fieldNames, null, orderByComparator); } @Override protected Map<Long, Fields> doGetFieldsMapByClasses(long ddmStructureId, long[] classPKs, List<String> fieldNames) throws Exception { return _doQuery(ddmStructureId, classPKs, fieldNames); } @Override protected List<Fields> doQuery(long ddmStructureId, List<String> fieldNames, Condition condition, OrderByComparator orderByComparator) throws Exception { return _doQuery(ddmStructureId, fieldNames, condition, orderByComparator); } @Override protected int doQueryCount(long ddmStructureId, Condition condition) throws Exception { Expression expression = null; if (condition != null) { expression = _parseExpression(condition); } int count = 0; long[] expandoRowIds = _getExpandoRowIds(ddmStructureId); for (long expandoRowId : expandoRowIds) { List<ExpandoValue> expandoValues = ExpandoValueLocalServiceUtil.getRowValues(expandoRowId); if ((expression == null) || ((expression != null) && _booleanValueOf(expression, expandoValues))) { count++; } } return count; } @Override protected void doUpdate(long classPK, Fields fields, boolean mergeFields, ServiceContext serviceContext) throws Exception { ExpandoRow expandoRow = ExpandoRowLocalServiceUtil.getRow(classPK); DDMStorageLink ddmStorageLink = DDMStorageLinkLocalServiceUtil.getClassStorageLink(expandoRow.getRowId()); ExpandoTable expandoTable = _getExpandoTable(expandoRow.getCompanyId(), ddmStorageLink.getStructureId(), fields); List<ExpandoColumn> expandoColumns = ExpandoColumnLocalServiceUtil.getColumns(expandoTable.getTableId()); if (!mergeFields) { for (ExpandoColumn expandoColumn : expandoColumns) { if (!fields.contains(expandoColumn.getName())) { ExpandoValueLocalServiceUtil.deleteValue(expandoColumn.getColumnId(), expandoRow.getRowId()); } } } _updateFields(expandoTable, expandoRow.getClassPK(), fields); } private boolean _booleanValueOf(Expression expression, List<ExpandoValue> expandoValues) { try { StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(); standardEvaluationContext.setBeanResolver(new ExpandoValueBeanResolver(expandoValues)); return expression.getValue(standardEvaluationContext, Boolean.class); } catch (EvaluationException ee) { _log.error("Unable to evaluate expression", ee); } return false; } private void _checkExpandoColumns(long ddmStructureId, ExpandoTable expandoTable, Fields fields) throws PortalException, SystemException { for (String name : fields.getNames()) { ExpandoColumn expandoColumn = ExpandoColumnLocalServiceUtil.getColumn(expandoTable.getTableId(), name); if (expandoColumn != null) { continue; } int type = _getExpandoColumnType(ddmStructureId, name); ExpandoColumnLocalServiceUtil.addColumn(expandoTable.getTableId(), name, type); } } private List<Fields> _doQuery(long ddmStructureId, List<String> fieldNames, Condition condition, OrderByComparator orderByComparator) throws Exception { return _doQuery(ddmStructureId, _getExpandoRowIds(ddmStructureId), fieldNames, condition, orderByComparator); } private Map<Long, Fields> _doQuery(long ddmStructureId, long[] classPKs, List<String> fieldNames) throws Exception { Map<Long, Fields> fieldsMap = new HashMap<Long, Fields>(); List<Fields> fieldsList = _doQuery(ddmStructureId, classPKs, fieldNames, null, null); for (int i = 0; i < fieldsList.size(); i++) { Fields fields = fieldsList.get(i); fieldsMap.put(classPKs[i], fields); } return fieldsMap; } private List<Fields> _doQuery(long ddmStructureId, long[] expandoRowIds, List<String> fieldNames, Condition condition, OrderByComparator orderByComparator) throws Exception { List<Fields> fieldsList = new ArrayList<Fields>(); Expression expression = null; if (condition != null) { expression = _parseExpression(condition); } DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(ddmStructureId); for (long expandoRowId : expandoRowIds) { List<ExpandoValue> expandoValues = ExpandoValueLocalServiceUtil.getRowValues(expandoRowId); if ((expression == null) || ((expression != null) && _booleanValueOf(expression, expandoValues))) { Fields fields = new Fields(); for (ExpandoValue expandoValue : expandoValues) { ExpandoColumn column = expandoValue.getColumn(); String fieldName = column.getName(); Serializable fieldValue = expandoValue.getSerializable(); if (ddmStructure.hasField(fieldName) && ((fieldNames == null) || ((fieldNames != null) && fieldNames.contains(fieldName)))) { Field field = new Field(ddmStructureId, fieldName, fieldValue); fields.put(field); } } fieldsList.add(fields); } } if (orderByComparator != null) { Collections.sort(fieldsList, orderByComparator); } return fieldsList; } private int _getExpandoColumnType(long ddmStructureId, String name) throws PortalException, SystemException { DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(ddmStructureId); String fieldDataType = ddmStructure.getFieldDataType(name); if (fieldDataType.equals(FieldConstants.BOOLEAN)) { return ExpandoColumnConstants.BOOLEAN; } else if (fieldDataType.equals(FieldConstants.DATE)) { return ExpandoColumnConstants.DATE; } else if (fieldDataType.equals(FieldConstants.DOUBLE)) { return ExpandoColumnConstants.DOUBLE; } else if (fieldDataType.equals(FieldConstants.FLOAT)) { return ExpandoColumnConstants.FLOAT; } else if (fieldDataType.equals(FieldConstants.INTEGER)) { return ExpandoColumnConstants.INTEGER; } else if (fieldDataType.equals(FieldConstants.LONG)) { return ExpandoColumnConstants.LONG; } else if (fieldDataType.equals(FieldConstants.NUMBER)) { return ExpandoColumnConstants.NUMBER; } else if (fieldDataType.equals(FieldConstants.SHORT)) { return ExpandoColumnConstants.SHORT; } else { return ExpandoColumnConstants.STRING; } } private long[] _getExpandoRowIds(long ddmStructureId) throws SystemException { List<Long> expandoRowIds = new ArrayList<Long>(); List<DDMStorageLink> ddmStorageLinks = DDMStorageLinkLocalServiceUtil .getStructureStorageLinks(ddmStructureId); for (DDMStorageLink ddmStorageLink : ddmStorageLinks) { expandoRowIds.add(ddmStorageLink.getClassPK()); } return ArrayUtil.toArray(expandoRowIds.toArray(new Long[expandoRowIds.size()])); } private ExpandoTable _getExpandoTable(long companyId, long ddmStructureId, Fields fields) throws PortalException, SystemException { ExpandoTable expandoTable = null; long classNameId = PortalUtil.getClassNameId(ExpandoStorageAdapter.class.getName()); try { expandoTable = ExpandoTableLocalServiceUtil.getTable(companyId, classNameId, String.valueOf(ddmStructureId)); } catch (NoSuchTableException nste) { expandoTable = ExpandoTableLocalServiceUtil.addTable(companyId, classNameId, String.valueOf(ddmStructureId)); } _checkExpandoColumns(ddmStructureId, expandoTable, fields); return expandoTable; } private Expression _parseExpression(Condition condition) { String expression = _toExpression(condition); try { ExpressionParser expressionParser = new SpelExpressionParser(); return expressionParser.parseExpression(expression); } catch (ParseException pe) { _log.error("Unable to parse expression " + expression, pe); } return null; } private String _toExpression(Condition condition) { if (condition.isJunction()) { Junction junction = (Junction) condition; return StringPool.OPEN_PARENTHESIS.concat(_toExpression(junction)).concat(StringPool.CLOSE_PARENTHESIS); } else { FieldCondition fieldCondition = (FieldCondition) condition; return _toExpression(fieldCondition); } } private String _toExpression(FieldCondition fieldCondition) { StringBundler sb = new StringBundler(5); sb.append("(@"); sb.append(fieldCondition.getName()); ComparisonOperator comparisonOperator = fieldCondition.getComparisonOperator(); if (comparisonOperator.equals(ComparisonOperator.LIKE)) { sb.append(".data matches "); } else { sb.append(".data == "); } String value = StringUtil.quote(String.valueOf(fieldCondition.getValue())); sb.append(value); sb.append(StringPool.CLOSE_PARENTHESIS); return sb.toString(); } private String _toExpression(Junction junction) { StringBundler sb = new StringBundler(); LogicalOperator logicalOperator = junction.getLogicalOperator(); Iterator<Condition> itr = junction.iterator(); while (itr.hasNext()) { Condition condition = itr.next(); sb.append(_toExpression(condition)); if (itr.hasNext()) { sb.append(StringPool.SPACE); sb.append(logicalOperator.toString()); sb.append(StringPool.SPACE); } } return sb.toString(); } private void _updateFields(ExpandoTable expandoTable, long classPK, Fields fields) throws PortalException, SystemException { Iterator<Field> itr = fields.iterator(); while (itr.hasNext()) { Field field = itr.next(); ExpandoValueLocalServiceUtil.addValue(expandoTable.getCompanyId(), ExpandoStorageAdapter.class.getName(), expandoTable.getName(), field.getName(), classPK, field.getValue()); } } private static Log _log = LogFactoryUtil.getLog(ExpandoStorageAdapter.class); }