com.liferay.portal.search.elasticsearch.internal.document.DefaultElasticsearchDocumentFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.portal.search.elasticsearch.internal.document.DefaultElasticsearchDocumentFactory.java

Source

/**
 * Copyright (c) 2000-present 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.portal.search.elasticsearch.internal.document;

import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.DocumentImpl;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.geolocation.GeoLocationPoint;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.search.elasticsearch.document.ElasticsearchDocumentFactory;

import java.io.IOException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang.time.FastDateFormat;

import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

import org.osgi.service.component.annotations.Component;

/**
 * @author Michael C. Han
 * @author Milen Dyankov
 */
@Component(immediate = true, service = ElasticsearchDocumentFactory.class)
public class DefaultElasticsearchDocumentFactory implements ElasticsearchDocumentFactory {

    public static final FastDateFormat DATE_FORMAT = FastDateFormat.getInstance("yyyyMMddHHmmss");

    public static final String DATE_MAX_VALUE = "99950812133000";

    @Override
    public String getElasticsearchDocument(Document document) throws IOException {

        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder();

        xContentBuilder.startObject();

        Map<String, Field> fields = document.getFields();

        addFields(fields.values(), xContentBuilder);

        xContentBuilder.endObject();

        return xContentBuilder.string();
    }

    protected void addDates(XContentBuilder xContentBuilder, Field field) throws IOException {

        for (Date date : field.getDates()) {
            String value;

            if (date.getTime() == Long.MAX_VALUE) {
                value = DATE_MAX_VALUE;
            } else {
                value = DATE_FORMAT.format(date);
            }

            xContentBuilder.value(value);
        }
    }

    protected void addField(XContentBuilder xContentBuilder, Field field) throws IOException {

        String name = field.getName();

        if (!field.isLocalized()) {
            String[] values = field.getValues();

            if (ArrayUtil.isEmpty(values)) {
                return;
            }

            List<String> valuesList = new ArrayList<>(values.length);

            for (String value : values) {
                if (value == null) {
                    continue;
                }

                valuesList.add(value.trim());
            }

            if (valuesList.isEmpty()) {
                return;
            }

            values = valuesList.toArray(new String[valuesList.size()]);

            addField(xContentBuilder, field, name, values);

            if (field.isSortable()) {
                String sortFieldName = DocumentImpl.getSortableFieldName(name);

                addField(xContentBuilder, field, sortFieldName, values);
            }
        } else {
            Map<Locale, String> localizedValues = field.getLocalizedValues();

            for (Map.Entry<Locale, String> entry : localizedValues.entrySet()) {
                String value = entry.getValue();

                if (Validator.isNull(value)) {
                    continue;
                }

                Locale locale = entry.getKey();

                String languageId = LocaleUtil.toLanguageId(locale);

                String defaultLanguageId = LocaleUtil.toLanguageId(LocaleUtil.getDefault());

                value = value.trim();

                if (languageId.equals(defaultLanguageId)) {
                    addField(xContentBuilder, field, name, value);
                }

                String localizedName = DocumentImpl.getLocalizedName(languageId, name);

                addField(xContentBuilder, field, localizedName, value);

                if (field.isSortable()) {
                    String sortableFieldName = DocumentImpl.getSortableFieldName(localizedName);

                    addField(xContentBuilder, field, sortableFieldName, value);
                }
            }
        }
    }

    protected void addField(XContentBuilder xContentBuilder, Field field, String fieldName, String... values)
            throws IOException {

        xContentBuilder.field(fieldName);

        if (field.isArray() || (values.length > 1)) {
            xContentBuilder.startArray();
        }

        GeoLocationPoint geoLocationPoint = field.getGeoLocationPoint();

        if (geoLocationPoint != null) {
            GeoPoint geoPoint = new GeoPoint(geoLocationPoint.getLatitude(), geoLocationPoint.getLongitude());

            xContentBuilder.value(geoPoint);
        } else if (field.isDate()) {
            addDates(xContentBuilder, field);
        } else {
            for (String value : values) {
                xContentBuilder.value(translateValue(field, value));
            }
        }

        if (field.isArray() || (values.length > 1)) {
            xContentBuilder.endArray();
        }
    }

    protected void addFields(Collection<Field> fields, XContentBuilder xContentBuilder) throws IOException {

        for (Field field : fields) {
            if (!field.hasChildren()) {
                addField(xContentBuilder, field);
            } else {
                addNestedField(xContentBuilder, field);
            }
        }
    }

    protected void addNestedField(XContentBuilder xContentBuilder, Field field) throws IOException {

        if (field.isArray()) {
            xContentBuilder.startArray(field.getName());
        } else {
            if (Validator.isNull(field.getName())) {
                xContentBuilder.startObject();
            } else {
                xContentBuilder.startObject(field.getName());
            }
        }

        addFields(field.getFields(), xContentBuilder);

        if (field.isArray()) {
            xContentBuilder.endArray();
        } else {
            xContentBuilder.endObject();
        }
    }

    protected Object translateValue(Field field, String value) {
        if (!field.isNumeric()) {
            return value;
        }

        Class<? extends Number> clazz = field.getNumericClass();

        if (clazz.equals(Float.class)) {
            return Float.valueOf(value);
        } else if (clazz.equals(Integer.class)) {
            return Integer.valueOf(value);
        } else if (clazz.equals(Long.class)) {
            return Long.valueOf(value);
        } else if (clazz.equals(Short.class)) {
            return Short.valueOf(value);
        }

        return Double.valueOf(value);
    }

}