001    /**
002     * Copyright (c) 2000-present 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.portal.kernel.search;
016    
017    import com.liferay.portal.kernel.search.geolocation.GeoLocationPoint;
018    import com.liferay.portal.kernel.util.ArrayUtil;
019    import com.liferay.portal.kernel.util.StringPool;
020    
021    import java.io.Serializable;
022    
023    import java.util.ArrayList;
024    import java.util.Date;
025    import java.util.LinkedList;
026    import java.util.List;
027    import java.util.Locale;
028    import java.util.Map;
029    
030    /**
031     * @author Bruno Farache
032     * @author Brian Wing Shun Chan
033     * @author Allen Chiang
034     * @author Alex Wallace
035     */
036    public class Field implements Serializable {
037    
038            public static final String ANY = StringPool.STAR;
039    
040            public static final String ARTICLE_ID = "articleId";
041    
042            public static final String ASSET_CATEGORY_ID = "assetCategoryId";
043    
044            public static final String ASSET_CATEGORY_IDS = "assetCategoryIds";
045    
046            public static final String ASSET_CATEGORY_TITLE = "assetCategoryTitle";
047    
048            public static final String ASSET_CATEGORY_TITLES = "assetCategoryTitles";
049    
050            public static final String ASSET_PARENT_CATEGORY_ID = "parentCategoryId";
051    
052            public static final String ASSET_PARENT_CATEGORY_IDS = "parentCategoryIds";
053    
054            public static final String ASSET_TAG_IDS = "assetTagIds";
055    
056            public static final String ASSET_TAG_NAMES = "assetTagNames";
057    
058            public static final String ASSET_VOCABULARY_ID = "assetVocabularyId";
059    
060            public static final String ASSET_VOCABULARY_IDS = "assetVocabularyIds";
061    
062            public static final String CAPTION = "caption";
063    
064            public static final String CATEGORY_ID = "categoryId";
065    
066            public static final String CLASS_NAME_ID = "classNameId";
067    
068            public static final String CLASS_PK = "classPK";
069    
070            public static final String CLASS_TYPE_ID = "classTypeId";
071    
072            public static final String COMMENTS = "comments";
073    
074            public static final String COMPANY_ID = "companyId";
075    
076            public static final String CONTENT = "content";
077    
078            public static final String CREATE_DATE = "createDate";
079    
080            public static final String DEFAULT_LANGUAGE_ID = "defaultLanguageId";
081    
082            public static final String DESCRIPTION = "description";
083    
084            public static final String ENTRY_CLASS_NAME = "entryClassName";
085    
086            public static final String ENTRY_CLASS_PK = "entryClassPK";
087    
088            public static final String EXPIRATION_DATE = "expirationDate";
089    
090            public static final String FOLDER_ID = "folderId";
091    
092            public static final String GEO_LOCATION = "geoLocation";
093    
094            public static final String GROUP_ID = "groupId";
095    
096            public static final String GROUP_ROLE_ID = "groupRoleId";
097    
098            public static final String HIDDEN = "hidden";
099    
100            public static final String KEYWORD_SEARCH = "keywordSearch";
101    
102            public static final String[] KEYWORDS = {
103                    Field.ASSET_CATEGORY_TITLES, Field.ASSET_TAG_NAMES, Field.COMMENTS,
104                    Field.CONTENT, Field.DESCRIPTION, Field.PROPERTIES, Field.TITLE,
105                    Field.URL, Field.USER_NAME
106            };
107    
108            public static final String LANGUAGE_ID = "languageId";
109    
110            public static final String LAYOUT_UUID = "layoutUuid";
111    
112            public static final String MODIFIED_DATE = "modified";
113    
114            public static final String NAME = "name";
115    
116            public static final String NODE_ID = "nodeId";
117    
118            public static final String ORGANIZATION_ID = "organizationId";
119    
120            /**
121             * @deprecated As of 7.0.0, replaced by {@link #ENTRY_CLASS_NAME}
122             */
123            @Deprecated
124            public static final String PORTLET_ID = "portletId";
125    
126            public static final String PRIORITY = "priority";
127    
128            public static final String PROPERTIES = "properties";
129    
130            public static final String PUBLISH_DATE = "publishDate";
131    
132            public static final String RATINGS = "ratings";
133    
134            public static final String RELATED_ENTRY = "relatedEntry";
135    
136            public static final String REMOVED_BY_USER_NAME = "removedByUserName";
137    
138            public static final String REMOVED_DATE = "removedDate";
139    
140            public static final String ROLE_ID = "roleId";
141    
142            public static final String ROOT_ENTRY_CLASS_NAME = "rootEntryClassName";
143    
144            public static final String ROOT_ENTRY_CLASS_PK = "rootEntryClassPK";
145    
146            public static final String SCOPE_GROUP_ID = "scopeGroupId";
147    
148            public static final String SNIPPET = "snippet";
149    
150            public static final String SPELL_CHECK_WORD = "spellCheckWord";
151    
152            public static final String STAGING_GROUP = "stagingGroup";
153    
154            public static final String STATUS = "status";
155    
156            public static final String SUBTITLE = "subtitle";
157    
158            public static final String TITLE = "title";
159    
160            public static final String TREE_PATH = "treePath";
161    
162            public static final String TYPE = "type";
163    
164            public static final String UID = "uid";
165    
166            public static final String[] UNSCORED_FIELD_NAMES = {
167                    Field.ASSET_CATEGORY_IDS, Field.COMPANY_ID, Field.ENTRY_CLASS_NAME,
168                    Field.ENTRY_CLASS_PK, Field.FOLDER_ID, Field.GROUP_ID,
169                    Field.GROUP_ROLE_ID, Field.ROLE_ID, Field.SCOPE_GROUP_ID, Field.USER_ID
170            };
171    
172            public static final String URL = "url";
173    
174            public static final String USER_GROUP_ID = "userGroupId";
175    
176            public static final String USER_ID = "userId";
177    
178            public static final String USER_NAME = "userName";
179    
180            public static final String VERSION = "version";
181    
182            public static final String VIEW_ACTION_ID = "viewActionId";
183    
184            public static final String VIEW_COUNT = "viewCount";
185    
186            public static boolean validateFieldName(String name) {
187                    if (name.contains(StringPool.COMMA) ||
188                            name.contains(StringPool.PERIOD) ||
189                            name.contains(StringPool.POUND) ||
190                            name.contains(StringPool.SLASH) || name.contains(StringPool.STAR)||
191                            name.startsWith(StringPool.UNDERLINE)) {
192    
193                            return false;
194                    }
195    
196                    return true;
197            }
198    
199            public Field(String name) {
200                    validate(name);
201    
202                    _name = name;
203            }
204    
205            public Field(String name, Map<Locale, String> localizedValues) {
206                    validate(name);
207    
208                    _name = name;
209                    _localizedValues = localizedValues;
210            }
211    
212            public Field(String name, String value) {
213                    this(name, new String[] {value});
214            }
215    
216            public Field(String name, String[] values) {
217                    validate(name);
218    
219                    _name = name;
220                    _values = values;
221            }
222    
223            public void addField(Field field) {
224                    _fields.add(field);
225            }
226    
227            /**
228             * @deprecated As of 7.0.0, replaced by {@link Query#getBoost}
229             */
230            @Deprecated
231            public float getBoost() {
232                    return _boost;
233            }
234    
235            public Date[] getDates() {
236                    return _dates;
237            }
238    
239            public List<Field> getFields() {
240                    return _fields;
241            }
242    
243            public GeoLocationPoint getGeoLocationPoint() {
244                    return _geoLocationPoint;
245            }
246    
247            public Map<Locale, String> getLocalizedValues() {
248                    return _localizedValues;
249            }
250    
251            public String getName() {
252                    return _name;
253            }
254    
255            public Class<? extends Number> getNumericClass() {
256                    return _numericClass;
257            }
258    
259            public Field getParentField() {
260                    return _parentField;
261            }
262    
263            public String getValue() {
264                    if (ArrayUtil.isNotEmpty(_values)) {
265                            return _values[0];
266                    }
267                    else {
268                            return null;
269                    }
270            }
271    
272            public String[] getValues() {
273                    return _values;
274            }
275    
276            public boolean hasChildren() {
277                    return !getFields().isEmpty();
278            }
279    
280            public boolean isArray() {
281                    return false;
282            }
283    
284            public boolean isDate() {
285                    if (_dates != null) {
286                            return true;
287                    }
288                    else {
289                            return false;
290                    }
291            }
292    
293            public boolean isLocalized() {
294                    if (_localizedValues != null) {
295                            return true;
296                    }
297                    else {
298                            return false;
299                    }
300            }
301    
302            public boolean isNested() {
303                    if (getParentField() != null) {
304                            return true;
305                    }
306    
307                    return false;
308            }
309    
310            public boolean isNumeric() {
311                    return _numeric;
312            }
313    
314            public boolean isSortable() {
315                    return _sortable;
316            }
317    
318            public boolean isTokenized() {
319                    return _tokenized;
320            }
321    
322            /**
323             * @deprecated As of 7.0.0, replaced by {@link Query#setBoost(float)}
324             */
325            @Deprecated
326            public void setBoost(float boost) {
327                    _boost = boost;
328            }
329    
330            public void setDates(Date[] dates) {
331                    _dates = dates;
332            }
333    
334            public void setGeoLocationPoint(GeoLocationPoint geoLocationPoint) {
335                    _geoLocationPoint = geoLocationPoint;
336    
337                    if (geoLocationPoint == null) {
338                            _values = null;
339                    }
340                    else {
341                            setValue(
342                                    "lat: " + geoLocationPoint.getLatitude() + ", lon: " +
343                                            geoLocationPoint.getLongitude());
344                    }
345            }
346    
347            public void setLocalizedValues(Map<Locale, String> localizedValues) {
348                    _localizedValues = localizedValues;
349            }
350    
351            public void setName(String name) {
352                    _name = name;
353            }
354    
355            public void setNumeric(boolean numeric) {
356                    _numeric = numeric;
357            }
358    
359            public void setNumericClass(Class<? extends Number> numericClass) {
360                    _numericClass = numericClass;
361            }
362    
363            public void setParentField(Field parentField) {
364                    _parentField = parentField;
365            }
366    
367            public void setSortable(boolean sortable) {
368                    _sortable = sortable;
369            }
370    
371            public void setTokenized(boolean tokenized) {
372                    _tokenized = tokenized;
373            }
374    
375            public void setValue(String value) {
376                    setValues(new String[] {value});
377            }
378    
379            public void setValues(String[] values) {
380                    _values = values;
381            }
382    
383            public static class NestedFieldBuilder {
384    
385                    public NestedFieldBuilder addNestedField(
386                            String name, String... values) {
387    
388                            Field field = new Field(name);
389    
390                            field.addField(new Field("value", values));
391    
392                            _addField(field);
393    
394                            return this;
395                    }
396    
397                    public NestedFieldBuilder endArray() {
398                            return endField();
399                    }
400    
401                    public NestedFieldBuilder endField() {
402                            if (_nestedFieldsBuilderFields.size() > 1) {
403                                    _nestedFieldsBuilderFields.removeLast();
404                            }
405    
406                            return this;
407                    }
408    
409                    public Field getField() {
410                            if (!_nestedFieldsBuilderFields.isEmpty()) {
411                                    return _nestedFieldsBuilderFields.getLast();
412                            }
413    
414                            return null;
415                    }
416    
417                    public NestedFieldBuilder startArray(String name) {
418                            FieldArray fieldArray = new FieldArray(name);
419    
420                            return _startField(fieldArray);
421                    }
422    
423                    public NestedFieldBuilder startField() {
424                            return startField(null);
425                    }
426    
427                    public NestedFieldBuilder startField(String name) {
428                            Field field = new Field(name);
429    
430                            return _startField(field);
431                    }
432    
433                    private void _addField(Field field) {
434                            Field lastField = _nestedFieldsBuilderFields.getLast();
435    
436                            lastField.addField(field);
437                    }
438    
439                    private NestedFieldBuilder _startField(Field field) {
440                            if (!_nestedFieldsBuilderFields.isEmpty()) {
441                                    _addField(field);
442                            }
443    
444                            _nestedFieldsBuilderFields.add(field);
445    
446                            return this;
447                    }
448    
449                    private final LinkedList<Field> _nestedFieldsBuilderFields =
450                            new LinkedList<>();
451    
452            }
453    
454            protected void validate(String name) {
455                    if (name.contains(StringPool.COMMA)) {
456                            throw new IllegalArgumentException(
457                                    "Name must not contain " + StringPool.COMMA + ": " + name);
458                    }
459    
460                    if (name.contains(StringPool.PERIOD)) {
461                            throw new IllegalArgumentException(
462                                    "Name must not contain " + StringPool.PERIOD + ": " + name);
463                    }
464    
465                    if (name.contains(StringPool.POUND)) {
466                            throw new IllegalArgumentException(
467                                    "Name must not contain " + StringPool.POUND + ": " + name);
468                    }
469    
470                    if (name.contains(StringPool.SLASH)) {
471                            throw new IllegalArgumentException(
472                                    "Name must not contain " + StringPool.SLASH + ": " + name);
473                    }
474    
475                    if (name.contains(StringPool.STAR)) {
476                            throw new IllegalArgumentException(
477                                    "Name must not contain " + StringPool.STAR + ": " + name);
478                    }
479    
480                    if (name.startsWith(StringPool.UNDERLINE)) {
481                            throw new IllegalArgumentException(
482                                    "Name must not start with " + StringPool.UNDERLINE + ": " +
483                                            name);
484                    }
485            }
486    
487            private float _boost = 1;
488            private Date[] _dates;
489            private final List<Field> _fields = new ArrayList<>();
490            private GeoLocationPoint _geoLocationPoint;
491            private Map<Locale, String> _localizedValues;
492            private String _name;
493            private boolean _numeric;
494            private Class<? extends Number> _numericClass;
495            private Field _parentField;
496            private boolean _sortable;
497            private boolean _tokenized;
498            private String[] _values;
499    
500    }