1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.messageboards.util;
24  
25  import com.liferay.portal.kernel.dao.orm.QueryUtil;
26  import com.liferay.portal.kernel.log.Log;
27  import com.liferay.portal.kernel.log.LogFactoryUtil;
28  import com.liferay.portal.kernel.search.BooleanQuery;
29  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
30  import com.liferay.portal.kernel.search.Document;
31  import com.liferay.portal.kernel.search.DocumentImpl;
32  import com.liferay.portal.kernel.search.DocumentSummary;
33  import com.liferay.portal.kernel.search.Field;
34  import com.liferay.portal.kernel.search.Hits;
35  import com.liferay.portal.kernel.search.SearchEngineUtil;
36  import com.liferay.portal.kernel.search.SearchException;
37  import com.liferay.portal.kernel.util.HtmlUtil;
38  import com.liferay.portal.kernel.util.StringUtil;
39  import com.liferay.portal.kernel.util.Validator;
40  import com.liferay.portal.model.Group;
41  import com.liferay.portal.service.GroupLocalServiceUtil;
42  import com.liferay.portal.util.PortalUtil;
43  import com.liferay.portal.util.PortletKeys;
44  import com.liferay.portlet.expando.model.ExpandoBridge;
45  import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
46  import com.liferay.portlet.messageboards.model.MBMessage;
47  import com.liferay.portlet.messageboards.model.MBThread;
48  import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
49  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
50  import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
51  
52  import java.util.Date;
53  
54  import javax.portlet.PortletURL;
55  
56  /**
57   * <a href="Indexer.java.html"><b><i>View Source</i></b></a>
58   *
59   * @author Brian Wing Shun Chan
60   * @author Harry Mark
61   * @author Bruno Farache
62   * @author Raymond Augé
63   */
64  public class Indexer implements com.liferay.portal.kernel.search.Indexer {
65  
66      public static final String PORTLET_ID = PortletKeys.MESSAGE_BOARDS;
67  
68      public static void addMessage(
69              long companyId, long groupId, long userId, String userName,
70              long categoryId, long threadId, long messageId, String title,
71              String content, boolean anonymous, Date modifiedDate,
72              String[] tagsEntries, ExpandoBridge expandoBridge)
73          throws SearchException {
74  
75          Document doc = getMessageDocument(
76              companyId, groupId, userId, userName, categoryId, threadId,
77              messageId, title, content, anonymous, modifiedDate, tagsEntries,
78              expandoBridge);
79  
80          SearchEngineUtil.addDocument(companyId, doc);
81      }
82  
83      public static void deleteMessage(long companyId, long messageId)
84          throws SearchException {
85  
86          SearchEngineUtil.deleteDocument(companyId, getMessageUID(messageId));
87      }
88  
89      public static void deleteMessages(long companyId, long threadId)
90          throws SearchException {
91  
92          BooleanQuery booleanQuery = BooleanQueryFactoryUtil.create();
93  
94          booleanQuery.addRequiredTerm(Field.PORTLET_ID, PORTLET_ID);
95  
96          booleanQuery.addRequiredTerm("threadId", threadId);
97  
98          Hits hits = SearchEngineUtil.search(
99              companyId, booleanQuery, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
100 
101         for (int i = 0; i < hits.getLength(); i++) {
102             Document doc = hits.doc(i);
103 
104             SearchEngineUtil.deleteDocument(companyId, doc.get(Field.UID));
105         }
106     }
107 
108     public static Document getMessageDocument(
109         long companyId, long groupId, long userId, String userName,
110         long categoryId, long threadId, long messageId, String title,
111         String content, boolean anonymous, Date modifiedDate,
112         String[] tagsEntries, ExpandoBridge expandoBridge) {
113 
114         long scopeGroupId = groupId;
115 
116         try {
117             Group group = GroupLocalServiceUtil.getGroup(groupId);
118 
119             if (group.isLayout()) {
120                 groupId = group.getParentGroupId();
121             }
122         }
123         catch (Exception e) {
124         }
125 
126         userName = PortalUtil.getUserName(userId, userName);
127 
128         try {
129             content = BBCodeUtil.getHTML(content);
130         }
131         catch (Exception e) {
132             _log.error(
133                 "Could not parse message " + messageId + ": " + e.getMessage());
134         }
135 
136         content = HtmlUtil.extractText(content);
137 
138         Document doc = new DocumentImpl();
139 
140         doc.addUID(PORTLET_ID, messageId);
141 
142         doc.addModifiedDate(modifiedDate);
143 
144         doc.addKeyword(Field.COMPANY_ID, companyId);
145         doc.addKeyword(Field.PORTLET_ID, PORTLET_ID);
146         doc.addKeyword(Field.GROUP_ID, groupId);
147         doc.addKeyword(Field.SCOPE_GROUP_ID, scopeGroupId);
148         doc.addKeyword(Field.USER_ID, userId);
149 
150         if (!anonymous) {
151             doc.addText(Field.USER_NAME, userName);
152         }
153 
154         doc.addText(Field.TITLE, title);
155         doc.addText(Field.CONTENT, content);
156         doc.addKeyword(Field.TAGS_ENTRIES, tagsEntries);
157 
158         doc.addKeyword("categoryId", categoryId);
159         doc.addKeyword("threadId", threadId);
160         doc.addKeyword(Field.ENTRY_CLASS_NAME, MBMessage.class.getName());
161         doc.addKeyword(Field.ENTRY_CLASS_PK, messageId);
162 
163         try {
164             MBThread thread = MBThreadLocalServiceUtil.getMBThread(threadId);
165 
166             doc.addKeyword(
167                 Field.ROOT_ENTRY_CLASS_PK, thread.getRootMessageId());
168         }
169         catch (Exception e) {
170         }
171 
172         ExpandoBridgeIndexerUtil.addAttributes(doc, expandoBridge);
173 
174         return doc;
175     }
176 
177     public static String getMessageUID(long messageId) {
178         Document doc = new DocumentImpl();
179 
180         doc.addUID(PORTLET_ID, messageId);
181 
182         return doc.get(Field.UID);
183     }
184 
185     public static void updateMessage(
186             long companyId, long groupId, long userId, String userName,
187             long categoryId, long threadId, long messageId, String title,
188             String content, boolean anonymous, Date modifiedDate,
189             String[] tagsEntries, ExpandoBridge expandoBridge)
190         throws SearchException {
191 
192         Document doc = getMessageDocument(
193             companyId, groupId, userId, userName, categoryId, threadId,
194             messageId, title, content, anonymous, modifiedDate, tagsEntries,
195             expandoBridge);
196 
197         SearchEngineUtil.updateDocument(companyId, doc.get(Field.UID), doc);
198     }
199 
200     public String[] getClassNames() {
201         return _CLASS_NAMES;
202     }
203 
204     public DocumentSummary getDocumentSummary(
205         Document doc, String snippet, PortletURL portletURL) {
206 
207         // Title
208 
209         String title = doc.get(Field.TITLE);
210 
211         // Content
212 
213         String content = snippet;
214 
215         if (Validator.isNull(snippet)) {
216             content = StringUtil.shorten(doc.get(Field.CONTENT), 200);
217         }
218 
219         // Portlet URL
220 
221         String messageId = doc.get(Field.ENTRY_CLASS_PK);
222 
223         portletURL.setParameter(
224             "struts_action", "/message_boards/view_message");
225         portletURL.setParameter("messageId", messageId);
226 
227         return new DocumentSummary(title, content, portletURL);
228     }
229 
230     public void reIndex(String className, long classPK) throws SearchException {
231         try {
232             MBMessageLocalServiceUtil.reIndex(classPK);
233         }
234         catch (Exception e) {
235             throw new SearchException(e);
236         }
237     }
238 
239     public void reIndex(String[] ids) throws SearchException {
240         try {
241             MBCategoryLocalServiceUtil.reIndex(ids);
242         }
243         catch (Exception e) {
244             throw new SearchException(e);
245         }
246     }
247 
248     private static final String[] _CLASS_NAMES = new String[] {
249         MBMessage.class.getName()
250     };
251 
252     private static Log _log = LogFactoryUtil.getLog(Indexer.class);
253 
254 }