001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.addNumber(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.addNumber(name, doubleValues);
096                                            }
097                                            else if (value instanceof Boolean) {
098                                                    document.addKeyword(name, (Boolean)value);
099                                            }
100                                            else if (value instanceof Boolean[]) {
101                                                    document.addKeyword(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.addNumber(name, (Double)value);
111                                            }
112                                            else if (value instanceof Double[]) {
113                                                    document.addNumber(name, (Double[])value);
114                                            }
115                                            else if (value instanceof Integer) {
116                                                    document.addNumber(name, (Integer)value);
117                                            }
118                                            else if (value instanceof Integer[]) {
119                                                    document.addNumber(name, (Integer[])value);
120                                            }
121                                            else if (value instanceof Long) {
122                                                    document.addNumber(name, (Long)value);
123                                            }
124                                            else if (value instanceof Long[]) {
125                                                    document.addNumber(name, (Long[])value);
126                                            }
127                                            else if (value instanceof Float) {
128                                                    document.addNumber(name, (Float)value);
129                                            }
130                                            else if (value instanceof Float[]) {
131                                                    document.addNumber(name, (Float[])value);
132                                            }
133                                            else if (value instanceof Object[]) {
134                                                    String[] valuesString = ArrayUtil.toStringArray(
135                                                            (Object[])value);
136    
137                                                    if (indexType.equals("keyword")) {
138                                                            document.addKeyword(name, valuesString);
139                                                    }
140                                                    else {
141                                                            document.addText(name, valuesString);
142                                                    }
143                                            }
144                                            else {
145                                                    String valueString = String.valueOf(value);
146    
147                                                    String type = field.getType();
148    
149                                                    if (type.equals(DDMImpl.TYPE_RADIO) ||
150                                                            type.equals(DDMImpl.TYPE_SELECT)) {
151    
152                                                            JSONArray jsonArray =
153                                                                    JSONFactoryUtil.createJSONArray(valueString);
154    
155                                                            String[] stringArray = ArrayUtil.toStringArray(
156                                                                    jsonArray);
157    
158                                                            if (indexType.equals("keyword")) {
159                                                                    document.addKeyword(name, stringArray);
160                                                            }
161                                                            else {
162                                                                    document.addText(name, stringArray);
163                                                            }
164                                                    }
165                                                    else {
166                                                            if (type.equals(DDMImpl.TYPE_DDM_TEXT_HTML)) {
167                                                                    valueString = HtmlUtil.extractText(valueString);
168                                                            }
169    
170                                                            if (indexType.equals("keyword")) {
171                                                                    document.addKeyword(name, valueString);
172                                                            }
173                                                            else {
174                                                                    document.addText(name, valueString);
175                                                            }
176                                                    }
177                                            }
178                                    }
179                            }
180                            catch (Exception e) {
181                                    if (_log.isWarnEnabled()) {
182                                            _log.warn(e, e);
183                                    }
184                            }
185                    }
186            }
187    
188            @Override
189            public String encodeName(long ddmStructureId, String fieldName) {
190                    return encodeName(ddmStructureId, fieldName, null);
191            }
192    
193            @Override
194            public String encodeName(
195                    long ddmStructureId, String fieldName, Locale locale) {
196    
197                    StringBundler sb = new StringBundler(7);
198    
199                    sb.append(DDM_FIELD_PREFIX);
200                    sb.append(ddmStructureId);
201                    sb.append(DDM_FIELD_SEPARATOR);
202                    sb.append(fieldName);
203    
204                    if (Validator.isNotNull(locale)) {
205                            sb.append(StringPool.UNDERLINE);
206                            sb.append(LocaleUtil.toLanguageId(locale));
207                    }
208    
209                    return sb.toString();
210            }
211    
212            @Override
213            public String extractIndexableAttributes(
214                    DDMStructure ddmStructure, Fields fields, Locale locale) {
215    
216                    Format dateFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
217                            PropsUtil.get(PropsKeys.INDEX_DATE_FORMAT_PATTERN));
218    
219                    StringBundler sb = new StringBundler();
220    
221                    for (Field field : fields) {
222                            try {
223                                    String indexType = ddmStructure.getFieldProperty(
224                                            field.getName(), "indexType");
225    
226                                    String structureKey = ddmStructure.getStructureKey();
227    
228                                    if (structureKey.equals("TIKARAWMETADATA")) {
229                                            indexType = "text";
230                                    }
231    
232                                    if (Validator.isNull(indexType)) {
233                                            continue;
234                                    }
235    
236                                    Serializable value = field.getValue(locale);
237    
238                                    if ((value instanceof Boolean) || (value instanceof Double) ||
239                                            (value instanceof Integer) || (value instanceof Long) ||
240                                            (value instanceof Float)) {
241    
242                                            sb.append(value);
243                                            sb.append(StringPool.SPACE);
244                                    }
245                                    else if (value instanceof Date) {
246                                            sb.append(dateFormat.format(value));
247                                            sb.append(StringPool.SPACE);
248                                    }
249                                    else if (value instanceof Date[]) {
250                                            Date[] dates = (Date[])value;
251    
252                                            for (Date date : dates) {
253                                                    sb.append(dateFormat.format(date));
254                                                    sb.append(StringPool.SPACE);
255                                            }
256                                    }
257                                    else if (value instanceof Object[]) {
258                                            Object[] values = (Object[])value;
259    
260                                            for (Object object : values) {
261                                                    sb.append(object);
262                                                    sb.append(StringPool.SPACE);
263                                            }
264                                    }
265                                    else {
266                                            String valueString = String.valueOf(value);
267    
268                                            String type = field.getType();
269    
270                                            if (type.equals(DDMImpl.TYPE_RADIO) ||
271                                                    type.equals(DDMImpl.TYPE_SELECT)) {
272    
273                                                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray(
274                                                            valueString);
275    
276                                                    String[] stringArray = ArrayUtil.toStringArray(
277                                                            jsonArray);
278    
279                                                    sb.append(stringArray);
280                                                    sb.append(StringPool.SPACE);
281                                            }
282                                            else {
283                                                    if (type.equals(DDMImpl.TYPE_DDM_TEXT_HTML)) {
284                                                            valueString = HtmlUtil.extractText(valueString);
285                                                    }
286    
287                                                    sb.append(valueString);
288                                                    sb.append(StringPool.SPACE);
289                                            }
290                                    }
291                            }
292                            catch (Exception e) {
293                                    if (_log.isWarnEnabled()) {
294                                            _log.warn(e, e);
295                                    }
296                            }
297                    }
298    
299                    return sb.toString();
300            }
301    
302            private static Log _log = LogFactoryUtil.getLog(DDMIndexerImpl.class);
303    
304    }