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_COUNT = "viewCount";
183    
184            public static boolean validateFieldName(String name) {
185                    if (name.contains(StringPool.COMMA) ||
186                            name.contains(StringPool.PERIOD) ||
187                            name.contains(StringPool.POUND) ||
188                            name.contains(StringPool.SLASH) || name.contains(StringPool.STAR)||
189                            name.startsWith(StringPool.UNDERLINE)) {
190    
191                            return false;
192                    }
193    
194                    return true;
195            }
196    
197            public Field(String name) {
198                    validate(name);
199    
200                    _name = name;
201            }
202    
203            public Field(String name, Map<Locale, String> localizedValues) {
204                    validate(name);
205    
206                    _name = name;
207                    _localizedValues = localizedValues;
208            }
209    
210            public Field(String name, String value) {
211                    this(name, new String[] {value});
212            }
213    
214            public Field(String name, String[] values) {
215                    validate(name);
216    
217                    _name = name;
218                    _values = values;
219            }
220    
221            public void addField(Field field) {
222                    _fields.add(field);
223            }
224    
225            /**
226             * @deprecated As of 7.0.0, replaced by {@link Query#getBoost}
227             */
228            @Deprecated
229            public float getBoost() {
230                    return _boost;
231            }
232    
233            public Date[] getDates() {
234                    return _dates;
235            }
236    
237            public List<Field> getFields() {
238                    return _fields;
239            }
240    
241            public GeoLocationPoint getGeoLocationPoint() {
242                    return _geoLocationPoint;
243            }
244    
245            public Map<Locale, String> getLocalizedValues() {
246                    return _localizedValues;
247            }
248    
249            public String getName() {
250                    return _name;
251            }
252    
253            public Class<? extends Number> getNumericClass() {
254                    return _numericClass;
255            }
256    
257            public Field getParentField() {
258                    return _parentField;
259            }
260    
261            public String getValue() {
262                    if (ArrayUtil.isNotEmpty(_values)) {
263                            return _values[0];
264                    }
265                    else {
266                            return null;
267                    }
268            }
269    
270            public String[] getValues() {
271                    return _values;
272            }
273    
274            public boolean hasChildren() {
275                    return !getFields().isEmpty();
276            }
277    
278            public boolean isArray() {
279                    return false;
280            }
281    
282            public boolean isDate() {
283                    if (_dates != null) {
284                            return true;
285                    }
286                    else {
287                            return false;
288                    }
289            }
290    
291            public boolean isLocalized() {
292                    if (_localizedValues != null) {
293                            return true;
294                    }
295                    else {
296                            return false;
297                    }
298            }
299    
300            public boolean isNested() {
301                    if (getParentField() != null) {
302                            return true;
303                    }
304    
305                    return false;
306            }
307    
308            public boolean isNumeric() {
309                    return _numeric;
310            }
311    
312            public boolean isSortable() {
313                    return _sortable;
314            }
315    
316            public boolean isTokenized() {
317                    return _tokenized;
318            }
319    
320            /**
321             * @deprecated As of 7.0.0, replaced by {@link Query#setBoost(float)}
322             */
323            @Deprecated
324            public void setBoost(float boost) {
325                    _boost = boost;
326            }
327    
328            public void setDates(Date[] dates) {
329                    _dates = dates;
330            }
331    
332            public void setGeoLocationPoint(GeoLocationPoint geoLocationPoint) {
333                    _geoLocationPoint = geoLocationPoint;
334            }
335    
336            public void setLocalizedValues(Map<Locale, String> localizedValues) {
337                    _localizedValues = localizedValues;
338            }
339    
340            public void setName(String name) {
341                    _name = name;
342            }
343    
344            public void setNumeric(boolean numeric) {
345                    _numeric = numeric;
346            }
347    
348            public void setNumericClass(Class<? extends Number> numericClass) {
349                    _numericClass = numericClass;
350            }
351    
352            public void setParentField(Field parentField) {
353                    _parentField = parentField;
354            }
355    
356            public void setSortable(boolean sortable) {
357                    _sortable = sortable;
358            }
359    
360            public void setTokenized(boolean tokenized) {
361                    _tokenized = tokenized;
362            }
363    
364            public void setValue(String value) {
365                    setValues(new String[] {value});
366            }
367    
368            public void setValues(String[] values) {
369                    _values = values;
370            }
371    
372            public static class NestedFieldBuilder {
373    
374                    public NestedFieldBuilder addNestedField(
375                            String name, String... values) {
376    
377                            Field field = new Field(name);
378    
379                            field.addField(new Field("value", values));
380    
381                            _addField(field);
382    
383                            return this;
384                    }
385    
386                    public NestedFieldBuilder endArray() {
387                            return endField();
388                    }
389    
390                    public NestedFieldBuilder endField() {
391                            if (_nestedFieldsBuilderFields.size() > 1) {
392                                    _nestedFieldsBuilderFields.removeLast();
393                            }
394    
395                            return this;
396                    }
397    
398                    public Field getField() {
399                            if (!_nestedFieldsBuilderFields.isEmpty()) {
400                                    return _nestedFieldsBuilderFields.getLast();
401                            }
402    
403                            return null;
404                    }
405    
406                    public NestedFieldBuilder startArray(String name) {
407                            FieldArray fieldArray = new FieldArray(name);
408    
409                            return _startField(fieldArray);
410                    }
411    
412                    public NestedFieldBuilder startField() {
413                            return startField(null);
414                    }
415    
416                    public NestedFieldBuilder startField(String name) {
417                            Field field = new Field(name);
418    
419                            return _startField(field);
420                    }
421    
422                    private void _addField(Field field) {
423                            Field lastField = _nestedFieldsBuilderFields.getLast();
424    
425                            lastField.addField(field);
426                    }
427    
428                    private NestedFieldBuilder _startField(Field field) {
429                            if (!_nestedFieldsBuilderFields.isEmpty()) {
430                                    _addField(field);
431                            }
432    
433                            _nestedFieldsBuilderFields.add(field);
434    
435                            return this;
436                    }
437    
438                    private final LinkedList<Field> _nestedFieldsBuilderFields =
439                            new LinkedList<>();
440    
441            }
442    
443            protected void validate(String name) {
444                    if (name.contains(StringPool.COMMA)) {
445                            throw new IllegalArgumentException(
446                                    "Name must not contain " + StringPool.COMMA + ": " + name);
447                    }
448    
449                    if (name.contains(StringPool.PERIOD)) {
450                            throw new IllegalArgumentException(
451                                    "Name must not contain " + StringPool.PERIOD + ": " + name);
452                    }
453    
454                    if (name.contains(StringPool.POUND)) {
455                            throw new IllegalArgumentException(
456                                    "Name must not contain " + StringPool.POUND + ": " + name);
457                    }
458    
459                    if (name.contains(StringPool.SLASH)) {
460                            throw new IllegalArgumentException(
461                                    "Name must not contain " + StringPool.SLASH + ": " + name);
462                    }
463    
464                    if (name.contains(StringPool.STAR)) {
465                            throw new IllegalArgumentException(
466                                    "Name must not contain " + StringPool.STAR + ": " + name);
467                    }
468    
469                    if (name.startsWith(StringPool.UNDERLINE)) {
470                            throw new IllegalArgumentException(
471                                    "Name must not start with " + StringPool.UNDERLINE + ": " +
472                                            name);
473                    }
474            }
475    
476            private float _boost = 1;
477            private Date[] _dates;
478            private final List<Field> _fields = new ArrayList<>();
479            private GeoLocationPoint _geoLocationPoint;
480            private Map<Locale, String> _localizedValues;
481            private String _name;
482            private boolean _numeric;
483            private Class<? extends Number> _numericClass;
484            private Field _parentField;
485            private boolean _sortable;
486            private boolean _tokenized;
487            private String[] _values;
488    
489    }