001    /**
002     * Copyright (c) 2000-2012 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.Document;
020    import com.liferay.portal.kernel.search.DocumentImpl;
021    import com.liferay.portal.kernel.search.Field;
022    import com.liferay.portal.kernel.search.IndexWriter;
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 LuceneIndexWriterImpl implements IndexWriter {
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, boolean tokenized, float boost, String value) {
138    
139                    org.apache.lucene.document.Fieldable luceneFieldable = null;
140    
141                    if (numeric) {
142                            luceneFieldable = LuceneFields.getNumber(name, value);
143                    }
144                    else {
145                            if (tokenized) {
146                                    luceneFieldable = LuceneFields.getText(name, value);
147                            }
148                            else {
149                                    luceneFieldable = LuceneFields.getKeyword(name, value);
150                            }
151                    }
152    
153                    luceneFieldable.setBoost(boost);
154    
155                    luceneDocument.add(luceneFieldable);
156            }
157    
158            private org.apache.lucene.document.Document _getLuceneDocument(
159                    Document document) {
160    
161                    org.apache.lucene.document.Document luceneDocument =
162                            new org.apache.lucene.document.Document();
163    
164                    Collection<Field> fields = document.getFields().values();
165    
166                    for (Field field : fields) {
167                            String name = field.getName();
168                            boolean numeric = field.isNumeric();
169                            boolean tokenized = field.isTokenized();
170                            float boost = field.getBoost();
171    
172                            if (!field.isLocalized()) {
173                                    for (String value : field.getValues()) {
174                                            if (Validator.isNull(value)) {
175                                                    continue;
176                                            }
177    
178                                            _addLuceneFieldable(
179                                                    luceneDocument, name, numeric, tokenized, boost, value);
180                                    }
181                            }
182                            else {
183                                    Map<Locale, String> localizedValues =
184                                            field.getLocalizedValues();
185    
186                                    for (Map.Entry<Locale, String> entry :
187                                                    localizedValues.entrySet()) {
188    
189                                            String value = entry.getValue();
190    
191                                            if (Validator.isNull(value)) {
192                                                    continue;
193                                            }
194    
195                                            Locale locale = entry.getKey();
196    
197                                            String languageId = LocaleUtil.toLanguageId(locale);
198    
199                                            String defaultLanguageId = LocaleUtil.toLanguageId(
200                                                    LocaleUtil.getDefault());
201    
202                                            if (languageId.equals(defaultLanguageId)) {
203                                                    _addLuceneFieldable(
204                                                            luceneDocument, name, numeric, tokenized, boost,
205                                                            value);
206                                            }
207    
208                                            String localizedName = DocumentImpl.getLocalizedName(
209                                                    locale, name);
210    
211                                            _addLuceneFieldable(
212                                                    luceneDocument, localizedName, numeric, tokenized,
213                                                    boost, value);
214                                    }
215                            }
216    
217                    }
218    
219                    return luceneDocument;
220            }
221    
222            private static Log _log = LogFactoryUtil.getLog(
223                    LuceneIndexWriterImpl.class);
224    
225    }