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.text.Format;
040    
041    import java.util.Date;
042    import java.util.Locale;
043    
044    /**
045     * @author Alexander Chow
046     */
047    public class DDMIndexerImpl implements DDMIndexer {
048    
049            @Override
050            public void addAttributes(
051                    Document document, DDMStructure ddmStructure, Fields fields) {
052    
053                    long groupId = GetterUtil.getLong(
054                            document.get(com.liferay.portal.kernel.search.Field.GROUP_ID));
055    
056                    Locale[] locales = LanguageUtil.getAvailableLocales(groupId);
057    
058                    for (Field field : fields) {
059                            try {
060                                    String indexType = ddmStructure.getFieldProperty(
061                                            field.getName(), "indexType");
062    
063                                    String structureKey = ddmStructure.getStructureKey();
064    
065                                    if (structureKey.equals("TIKARAWMETADATA")) {
066                                            indexType = "text";
067                                    }
068    
069                                    if (Validator.isNull(indexType)) {
070                                            continue;
071                                    }
072    
073                                    for (Locale locale : locales) {
074                                            String name = encodeName(
075                                                    ddmStructure.getStructureId(), field.getName(), locale);
076    
077                                            Serializable value = field.getValue(locale);
078    
079                                            if (value instanceof Boolean) {
080                                                    document.addKeyword(name, (Boolean)value);
081                                            }
082                                            else if (value instanceof Boolean[]) {
083                                                    document.addKeyword(name, (Boolean[])value);
084                                            }
085                                            else if (value instanceof Date) {
086                                                    document.addDate(name, (Date)value);
087                                            }
088                                            else if (value instanceof Date[]) {
089                                                    document.addDate(name, (Date[])value);
090                                            }
091                                            else if (value instanceof Double) {
092                                                    document.addNumber(name, (Double)value);
093                                            }
094                                            else if (value instanceof Double[]) {
095                                                    document.addNumber(name, (Double[])value);
096                                            }
097                                            else if (value instanceof Integer) {
098                                                    document.addNumber(name, (Integer)value);
099                                            }
100                                            else if (value instanceof Integer[]) {
101                                                    document.addNumber(name, (Integer[])value);
102                                            }
103                                            else if (value instanceof Long) {
104                                                    document.addNumber(name, (Long)value);
105                                            }
106                                            else if (value instanceof Long[]) {
107                                                    document.addNumber(name, (Long[])value);
108                                            }
109                                            else if (value instanceof Float) {
110                                                    document.addNumber(name, (Float)value);
111                                            }
112                                            else if (value instanceof Float[]) {
113                                                    document.addNumber(name, (Float[])value);
114                                            }
115                                            else if (value instanceof Object[]) {
116                                                    String[] valuesString = ArrayUtil.toStringArray(
117                                                            (Object[])value);
118    
119                                                    if (indexType.equals("keyword")) {
120                                                            document.addKeyword(name, valuesString);
121                                                    }
122                                                    else {
123                                                            document.addText(name, valuesString);
124                                                    }
125                                            }
126                                            else {
127                                                    String valueString = String.valueOf(value);
128    
129                                                    String type = field.getType();
130    
131                                                    if (type.equals(DDMImpl.TYPE_RADIO) ||
132                                                            type.equals(DDMImpl.TYPE_SELECT)) {
133    
134                                                            JSONArray jsonArray =
135                                                                    JSONFactoryUtil.createJSONArray(valueString);
136    
137                                                            String[] stringArray = ArrayUtil.toStringArray(
138                                                                    jsonArray);
139    
140                                                            if (indexType.equals("keyword")) {
141                                                                    document.addKeyword(name, stringArray);
142                                                            }
143                                                            else {
144                                                                    document.addText(name, stringArray);
145                                                            }
146                                                    }
147                                                    else {
148                                                            if (type.equals(DDMImpl.TYPE_DDM_TEXT_HTML)) {
149                                                                    valueString = HtmlUtil.extractText(valueString);
150                                                            }
151    
152                                                            if (indexType.equals("keyword")) {
153                                                                    document.addKeyword(name, valueString);
154                                                            }
155                                                            else {
156                                                                    document.addText(name, valueString);
157                                                            }
158                                                    }
159                                            }
160                                    }
161                            }
162                            catch (Exception e) {
163                                    if (_log.isWarnEnabled()) {
164                                            _log.warn(e, e);
165                                    }
166                            }
167                    }
168            }
169    
170            @Override
171            public String encodeName(long ddmStructureId, String fieldName) {
172                    return encodeName(ddmStructureId, fieldName, null);
173            }
174    
175            @Override
176            public String encodeName(
177                    long ddmStructureId, String fieldName, Locale locale) {
178    
179                    StringBundler sb = new StringBundler(7);
180    
181                    sb.append(DDM_FIELD_NAMESPACE);
182                    sb.append(StringPool.FORWARD_SLASH);
183                    sb.append(ddmStructureId);
184                    sb.append(StringPool.FORWARD_SLASH);
185                    sb.append(fieldName);
186    
187                    if (Validator.isNotNull(locale)) {
188                            sb.append(StringPool.UNDERLINE);
189                            sb.append(LocaleUtil.toLanguageId(locale));
190                    }
191    
192                    return sb.toString();
193            }
194    
195            @Override
196            public String extractIndexableAttributes(
197                    DDMStructure ddmStructure, Fields fields, Locale locale) {
198    
199                    Format dateFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
200                            PropsUtil.get(PropsKeys.INDEX_DATE_FORMAT_PATTERN));
201    
202                    StringBundler sb = new StringBundler();
203    
204                    for (Field field : fields) {
205                            try {
206                                    String indexType = ddmStructure.getFieldProperty(
207                                            field.getName(), "indexType");
208    
209                                    String structureKey = ddmStructure.getStructureKey();
210    
211                                    if (structureKey.equals("TIKARAWMETADATA")) {
212                                            indexType = "text";
213                                    }
214    
215                                    if (Validator.isNull(indexType)) {
216                                            continue;
217                                    }
218    
219                                    Serializable value = field.getValue(locale);
220    
221                                    if ((value instanceof Boolean) || (value instanceof Double) ||
222                                            (value instanceof Integer) || (value instanceof Long) ||
223                                            (value instanceof Float)) {
224    
225                                            sb.append(value);
226                                            sb.append(StringPool.SPACE);
227                                    }
228                                    else if (value instanceof Date) {
229                                            sb.append(dateFormat.format(value));
230                                            sb.append(StringPool.SPACE);
231                                    }
232                                    else if (value instanceof Date[]) {
233                                            Date[] dates = (Date[])value;
234    
235                                            for (Date date : dates) {
236                                                    sb.append(dateFormat.format(date));
237                                                    sb.append(StringPool.SPACE);
238                                            }
239                                    }
240                                    else if (value instanceof Object[]) {
241                                            Object[] values = (Object[])value;
242    
243                                            for (Object object : values) {
244                                                    sb.append(object);
245                                                    sb.append(StringPool.SPACE);
246                                            }
247                                    }
248                                    else {
249                                            String valueString = String.valueOf(value);
250    
251                                            String type = field.getType();
252    
253                                            if (type.equals(DDMImpl.TYPE_RADIO) ||
254                                                    type.equals(DDMImpl.TYPE_SELECT)) {
255    
256                                                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray(
257                                                            valueString);
258    
259                                                    String[] stringArray = ArrayUtil.toStringArray(
260                                                            jsonArray);
261    
262                                                    sb.append(stringArray);
263                                                    sb.append(StringPool.SPACE);
264                                            }
265                                            else {
266                                                    if (type.equals(DDMImpl.TYPE_DDM_TEXT_HTML)) {
267                                                            valueString = HtmlUtil.extractText(valueString);
268                                                    }
269    
270                                                    sb.append(valueString);
271                                                    sb.append(StringPool.SPACE);
272                                            }
273                                    }
274                            }
275                            catch (Exception e) {
276                                    if (_log.isWarnEnabled()) {
277                                            _log.warn(e, e);
278                                    }
279                            }
280                    }
281    
282                    return sb.toString();
283            }
284    
285            private static Log _log = LogFactoryUtil.getLog(DDMIndexerImpl.class);
286    
287    }