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.portal.search.lucene;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.search.BaseIndexWriter;
020    import com.liferay.portal.kernel.search.Document;
021    import com.liferay.portal.kernel.search.DocumentImpl;
022    import com.liferay.portal.kernel.search.Field;
023    import com.liferay.portal.kernel.search.SearchContext;
024    import com.liferay.portal.kernel.search.SearchException;
025    import com.liferay.portal.kernel.util.LocaleUtil;
026    import com.liferay.portal.kernel.util.Validator;
027    
028    import java.io.IOException;
029    
030    import java.util.Collection;
031    import java.util.Locale;
032    import java.util.Map;
033    
034    import org.apache.lucene.index.Term;
035    
036    /**
037     * @author Bruno Farache
038     * @author Brian Wing Shun Chan
039     * @author Allen Chiang
040     * @author Alex Wallace
041     */
042    public class LuceneIndexWriter extends BaseIndexWriter {
043    
044            public void addDocument(SearchContext searchContext, Document document)
045                    throws SearchException {
046    
047                    try {
048                            LuceneHelperUtil.addDocument(
049                                    searchContext.getCompanyId(), _getLuceneDocument(document));
050    
051                            if (_log.isDebugEnabled()) {
052                                    _log.debug("Added document " + document.get(Field.UID));
053                            }
054                    }
055                    catch (IOException ioe) {
056                            throw new SearchException(ioe);
057                    }
058            }
059    
060            public void addDocuments(
061                            SearchContext searchContext, Collection<Document> documents)
062                    throws SearchException {
063    
064                    for (Document document : documents) {
065                            addDocument(searchContext, document);
066                    }
067            }
068    
069            public void deleteDocument(SearchContext searchContext, String uid)
070                    throws SearchException {
071    
072                    try {
073                            LuceneHelperUtil.deleteDocuments(
074                                    searchContext.getCompanyId(), new Term(Field.UID, uid));
075    
076                            if (_log.isDebugEnabled()) {
077                                    _log.debug("Deleted document " + uid);
078                            }
079                    }
080                    catch (IOException ioe) {
081                            throw new SearchException(ioe);
082                    }
083            }
084    
085            public void deleteDocuments(
086                            SearchContext searchContext, Collection<String> uids)
087                    throws SearchException {
088    
089                    for (String uid : uids) {
090                            deleteDocument(searchContext, uid);
091                    }
092            }
093    
094            public void deletePortletDocuments(
095                            SearchContext searchContext, String portletId)
096                    throws SearchException {
097    
098                    try {
099                            LuceneHelperUtil.deleteDocuments(
100                                    searchContext.getCompanyId(), new Term(Field.PORTLET_ID,
101                                    portletId));
102                    }
103                    catch (IOException ioe) {
104                            throw new SearchException(ioe);
105                    }
106            }
107    
108            public void updateDocument(SearchContext searchContext, Document document)
109                    throws SearchException {
110    
111                    try {
112                            LuceneHelperUtil.updateDocument(
113                                    searchContext.getCompanyId(),
114                                    new Term(Field.UID, document.getUID()),
115                                    _getLuceneDocument(document));
116    
117                            if (_log.isDebugEnabled()) {
118                                    _log.debug("Updated document " + document.get(Field.UID));
119                            }
120                    }
121                    catch (IOException ioe) {
122                            throw new SearchException(ioe);
123                    }
124            }
125    
126            public void updateDocuments(
127                            SearchContext searchContext, Collection<Document> documents)
128                    throws SearchException {
129    
130                    for (Document document : documents) {
131                            updateDocument(searchContext, document);
132                    }
133            }
134    
135            private void _addLuceneFieldable(
136                    org.apache.lucene.document.Document luceneDocument, String name,
137                    boolean numeric, Class<? extends Number> numericClass,
138                    boolean tokenized, float boost, String value) {
139    
140                    org.apache.lucene.document.Fieldable luceneFieldable = null;
141    
142                    if (numeric) {
143                            luceneFieldable = LuceneFields.getNumber(name, value, numericClass);
144                    }
145                    else {
146                            if (tokenized) {
147                                    luceneFieldable = LuceneFields.getText(name, value);
148                            }
149                            else {
150                                    luceneFieldable = LuceneFields.getKeyword(name, value);
151                            }
152                    }
153    
154                    luceneFieldable.setBoost(boost);
155    
156                    luceneDocument.add(luceneFieldable);
157            }
158    
159            private org.apache.lucene.document.Document _getLuceneDocument(
160                    Document document) {
161    
162                    org.apache.lucene.document.Document luceneDocument =
163                            new org.apache.lucene.document.Document();
164    
165                    Collection<Field> fields = document.getFields().values();
166    
167                    for (Field field : fields) {
168                            String name = field.getName();
169                            boolean numeric = field.isNumeric();
170                            Class<? extends Number> numericClass = field.getNumericClass();
171                            boolean tokenized = field.isTokenized();
172                            float boost = field.getBoost();
173    
174                            if (!field.isLocalized()) {
175                                    for (String value : field.getValues()) {
176                                            if (Validator.isNull(value)) {
177                                                    continue;
178                                            }
179    
180                                            _addLuceneFieldable(
181                                                    luceneDocument, name, numeric, numericClass, tokenized,
182                                                    boost, value);
183                                    }
184                            }
185                            else {
186                                    Map<Locale, String> localizedValues =
187                                            field.getLocalizedValues();
188    
189                                    for (Map.Entry<Locale, String> entry :
190                                                    localizedValues.entrySet()) {
191    
192                                            String value = entry.getValue();
193    
194                                            if (Validator.isNull(value)) {
195                                                    continue;
196                                            }
197    
198                                            Locale locale = entry.getKey();
199    
200                                            String languageId = LocaleUtil.toLanguageId(locale);
201    
202                                            String defaultLanguageId = LocaleUtil.toLanguageId(
203                                                    LocaleUtil.getDefault());
204    
205                                            if (languageId.equals(defaultLanguageId)) {
206                                                    _addLuceneFieldable(
207                                                            luceneDocument, name, numeric, numericClass,
208                                                            tokenized, boost, value);
209                                            }
210    
211                                            String localizedName = DocumentImpl.getLocalizedName(
212                                                    locale, name);
213    
214                                            _addLuceneFieldable(
215                                                    luceneDocument, localizedName, numeric, numericClass,
216                                                    tokenized, boost, value);
217                                    }
218                            }
219    
220                    }
221    
222                    return luceneDocument;
223            }
224    
225            private static Log _log = LogFactoryUtil.getLog(LuceneIndexWriter.class);
226    
227    }