001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.dynamicdatamapping.util;
016    
017    import com.liferay.portal.kernel.json.JSONArray;
018    import com.liferay.portal.kernel.json.JSONFactoryUtil;
019    import com.liferay.portal.kernel.language.LanguageUtil;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.search.Document;
023    import com.liferay.portal.kernel.util.ArrayUtil;
024    import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
025    import com.liferay.portal.kernel.util.GetterUtil;
026    import com.liferay.portal.kernel.util.HtmlUtil;
027    import com.liferay.portal.kernel.util.LocaleUtil;
028    import com.liferay.portal.kernel.util.PropsKeys;
029    import com.liferay.portal.kernel.util.PropsUtil;
030    import com.liferay.portal.kernel.util.StringBundler;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
034    import com.liferay.portlet.dynamicdatamapping.storage.Field;
035    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
036    
037    import java.io.Serializable;
038    
039    import java.math.BigDecimal;
040    
041    import java.text.Format;
042    
043    import java.util.Date;
044    import java.util.Locale;
045    
046    /**
047     * @author Alexander Chow
048     */
049    public class DDMIndexerImpl implements DDMIndexer {
050    
051            @Override
052            public void addAttributes(
053                    Document document, DDMStructure ddmStructure, Fields fields) {
054    
055                    long groupId = GetterUtil.getLong(
056                            document.get(com.liferay.portal.kernel.search.Field.GROUP_ID));
057    
058                    Locale[] locales = LanguageUtil.getAvailableLocales(groupId);
059    
060                    for (Field field : fields) {
061                            try {
062                                    String indexType = ddmStructure.getFieldProperty(
063                                            field.getName(), "indexType");
064    
065                                    String structureKey = ddmStructure.getStructureKey();
066    
067                                    if (structureKey.equals("TIKARAWMETADATA")) {
068                                            indexType = "text";
069                                    }
070    
071                                    if (Validator.isNull(indexType)) {
072                                            continue;
073                                    }
074    
075                                    for (Locale locale : locales) {
076                                            String name = encodeName(
077                                                    ddmStructure.getStructureId(), field.getName(), locale);
078    
079                                            Serializable value = field.getValue(locale);
080    
081                                            if (value instanceof BigDecimal) {
082                                                    Double doubleValue = ((BigDecimal)value).doubleValue();
083    
084                                                    document.addNumberSortable(name, doubleValue);
085                                            }
086                                            else if (value instanceof BigDecimal[]) {
087                                                    BigDecimal[] bigDecimals = (BigDecimal[])value;
088    
089                                                    Double[] doubleValues = new Double[bigDecimals.length];
090    
091                                                    for (int i = 0; i < bigDecimals.length; i++) {
092                                                            doubleValues[i] = bigDecimals[i].doubleValue();
093                                                    }
094    
095                                                    document.addNumberSortable(name, doubleValues);
096                                            }
097                                            else if (value instanceof Boolean) {
098                                                    document.addKeywordSortable(name, (Boolean)value);
099                                            }
100                                            else if (value instanceof Boolean[]) {
101                                                    document.addKeywordSortable(name, (Boolean[])value);
102                                            }
103                                            else if (value instanceof Date) {
104                                                    document.addDate(name, (Date)value);
105                                            }
106                                            else if (value instanceof Date[]) {
107                                                    document.addDate(name, (Date[])value);
108                                            }
109                                            else if (value instanceof Double) {
110                                                    document.addNumberSortable(name, (Double)value);
111                                            }
112                                            else if (value instanceof Double[]) {
113                                                    document.addNumberSortable(name, (Double[])value);
114                                            }
115                                            else if (value instanceof Integer) {
116                                                    document.addNumberSortable(name, (Integer)value);
117                                            }
118                                            else if (value instanceof Integer[]) {
119                                                    document.addNumberSortable(name, (Integer[])value);
120                                            }
121                                            else if (value instanceof Long) {
122                                                    document.addNumberSortable(name, (Long)value);
123                                            }
124                                            else if (value instanceof Long[]) {
125                                                    document.addNumberSortable(name, (Long[])value);
126                                            }
127                                            else if (value instanceof Float) {
128                                                    document.addNumberSortable(name, (Float)value);
129                                            }
130                                            else if (value instanceof Float[]) {
131                                                    document.addNumberSortable(name, (Float[])value);
132                                            }
133                                            else if (value instanceof Number[]) {
134                                                    Number[] numbers = (Number[])value;
135    
136                                                    Double[] doubles = new Double[numbers.length];
137    
138                                                    for (int i = 0; i < numbers.length; i++) {
139                                                            doubles[i] = numbers[i].doubleValue();
140                                                    }
141    
142                                                    document.addNumberSortable(name, doubles);
143                                            }
144                                            else if (value instanceof Object[]) {
145                                                    String[] valuesString = ArrayUtil.toStringArray(
146                                                            (Object[])value);
147    
148                                                    if (indexType.equals("keyword")) {
149                                                            document.addKeywordSortable(name, valuesString);
150                                                    }
151                                                    else {
152                                                            document.addTextSortable(name, valuesString);
153                                                    }
154                                            }
155                                            else {
156                                                    String valueString = String.valueOf(value);
157    
158                                                    String type = field.getType();
159    
160                                                    if (type.equals(DDMImpl.TYPE_RADIO) ||
161                                                            type.equals(DDMImpl.TYPE_SELECT)) {
162    
163                                                            JSONArray jsonArray =
164                                                                    JSONFactoryUtil.createJSONArray(valueString);
165    
166                                                            String[] stringArray = ArrayUtil.toStringArray(
167                                                                    jsonArray);
168    
169                                                            if (indexType.equals("keyword")) {
170                                                                    document.addKeywordSortable(name, stringArray);
171                                                            }
172                                                            else {
173                                                                    document.addTextSortable(name, stringArray);
174                                                            }
175                                                    }
176                                                    else {
177                                                            if (type.equals(DDMImpl.TYPE_DDM_TEXT_HTML)) {
178                                                                    valueString = HtmlUtil.extractText(valueString);
179                                                            }
180    
181                                                            if (indexType.equals("keyword")) {
182                                                                    document.addKeywordSortable(name, valueString);
183                                                            }
184                                                            else {
185                                                                    document.addTextSortable(name, valueString);
186                                                            }
187                                                    }
188                                            }
189                                    }
190                            }
191                            catch (Exception e) {
192                                    if (_log.isWarnEnabled()) {
193                                            _log.warn(e, e);
194                                    }
195                            }
196                    }
197            }
198    
199            @Override
200            public String encodeName(long ddmStructureId, String fieldName) {
201                    return encodeName(ddmStructureId, fieldName, null);
202            }
203    
204            @Override
205            public String encodeName(
206                    long ddmStructureId, String fieldName, Locale locale) {
207    
208                    StringBundler sb = new StringBundler(7);
209    
210                    sb.append(DDM_FIELD_PREFIX);
211                    sb.append(ddmStructureId);
212                    sb.append(DDM_FIELD_SEPARATOR);
213                    sb.append(fieldName);
214    
215                    if (Validator.isNotNull(locale)) {
216                            sb.append(StringPool.UNDERLINE);
217                            sb.append(LocaleUtil.toLanguageId(locale));
218                    }
219    
220                    return sb.toString();
221            }
222    
223            @Override
224            public String extractIndexableAttributes(
225                    DDMStructure ddmStructure, Fields fields, Locale locale) {
226    
227                    Format dateFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
228                            PropsUtil.get(PropsKeys.INDEX_DATE_FORMAT_PATTERN));
229    
230                    StringBundler sb = new StringBundler();
231    
232                    for (Field field : fields) {
233                            try {
234                                    String indexType = ddmStructure.getFieldProperty(
235                                            field.getName(), "indexType");
236    
237                                    String structureKey = ddmStructure.getStructureKey();
238    
239                                    if (structureKey.equals("TIKARAWMETADATA")) {
240                                            indexType = "text";
241                                    }
242    
243                                    if (Validator.isNull(indexType)) {
244                                            continue;
245                                    }
246    
247                                    Serializable value = field.getValue(locale);
248    
249                                    if ((value instanceof Boolean) || (value instanceof Number)) {
250                                            sb.append(value);
251                                            sb.append(StringPool.SPACE);
252                                    }
253                                    else if (value instanceof Date) {
254                                            sb.append(dateFormat.format(value));
255                                            sb.append(StringPool.SPACE);
256                                    }
257                                    else if (value instanceof Date[]) {
258                                            Date[] dates = (Date[])value;
259    
260                                            for (Date date : dates) {
261                                                    sb.append(dateFormat.format(date));
262                                                    sb.append(StringPool.SPACE);
263                                            }
264                                    }
265                                    else if (value instanceof Object[]) {
266                                            Object[] values = (Object[])value;
267    
268                                            for (Object object : values) {
269                                                    sb.append(object);
270                                                    sb.append(StringPool.SPACE);
271                                            }
272                                    }
273                                    else {
274                                            String valueString = String.valueOf(value);
275    
276                                            String type = field.getType();
277    
278                                            if (type.equals(DDMImpl.TYPE_RADIO) ||
279                                                    type.equals(DDMImpl.TYPE_SELECT)) {
280    
281                                                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray(
282                                                            valueString);
283    
284                                                    String[] stringArray = ArrayUtil.toStringArray(
285                                                            jsonArray);
286    
287                                                    sb.append(stringArray);
288                                                    sb.append(StringPool.SPACE);
289                                            }
290                                            else {
291                                                    if (type.equals(DDMImpl.TYPE_DDM_TEXT_HTML)) {
292                                                            valueString = HtmlUtil.extractText(valueString);
293                                                    }
294    
295                                                    sb.append(valueString);
296                                                    sb.append(StringPool.SPACE);
297                                            }
298                                    }
299                            }
300                            catch (Exception e) {
301                                    if (_log.isWarnEnabled()) {
302                                            _log.warn(e, e);
303                                    }
304                            }
305                    }
306    
307                    return sb.toString();
308            }
309    
310            private static Log _log = LogFactoryUtil.getLog(DDMIndexerImpl.class);
311    
312    }