001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/chat/tags/sakai_2-4-1/chat-impl/impl/src/java/org/sakaiproject/chat2/model/impl/ChatContentProducer.java $
003: * $Id: ChatContentProducer.java 29602 2007-04-26 13:53:55Z ajpoland@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2007 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/
021:
022: /**
023: *
024: */package org.sakaiproject.chat2.model.impl;
025:
026: import java.io.Reader;
027: import java.io.StringReader;
028: import java.util.ArrayList;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.Set;
033:
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036: import org.sakaiproject.chat2.model.ChatChannel;
037: import org.sakaiproject.chat2.model.ChatManager;
038: import org.sakaiproject.chat2.model.ChatMessage;
039: import org.sakaiproject.component.cover.ServerConfigurationService;
040: import org.sakaiproject.entity.api.EntityManager;
041: import org.sakaiproject.entity.api.EntityProducer;
042: import org.sakaiproject.entity.api.Reference;
043: import org.sakaiproject.event.api.Event;
044: import org.sakaiproject.exception.IdUnusedException;
045: import org.sakaiproject.exception.PermissionException;
046: import org.sakaiproject.search.api.EntityContentProducer;
047: import org.sakaiproject.search.api.SearchIndexBuilder;
048: import org.sakaiproject.search.api.SearchService;
049: import org.sakaiproject.search.api.SearchUtils;
050: import org.sakaiproject.search.model.SearchBuilderItem;
051: import org.sakaiproject.user.api.User;
052: import org.sakaiproject.user.api.UserNotDefinedException;
053: import org.sakaiproject.user.cover.UserDirectoryService;
054: import org.sakaiproject.util.ResourceLoader;
055:
056: /**
057: * @author chrismaurer
058: *
059: */
060: public class ChatContentProducer implements EntityContentProducer {
061:
062: protected final Log logger = LogFactory.getLog(getClass());
063: private SearchService searchService = null;
064: private SearchIndexBuilder searchIndexBuilder = null;
065: private EntityManager entityManager = null;
066: private ChatManager chatManager = null;
067: private List addEvents = new ArrayList();
068: private List removeEvents = new ArrayList();
069:
070: private ResourceLoader toolBundle;
071:
072: protected void init() throws Exception {
073: logger.info("init()");
074:
075: if ("true".equals(ServerConfigurationService.getString( //$NON-NLS-1$
076: "search.enable", "false"))) //$NON-NLS-1$ //$NON-NLS-2$
077: {
078: for (Iterator i = addEvents.iterator(); i.hasNext();) {
079: getSearchService().registerFunction((String) i.next());
080: }
081: for (Iterator i = removeEvents.iterator(); i.hasNext();) {
082: getSearchService().registerFunction((String) i.next());
083: }
084: getSearchIndexBuilder().registerEntityContentProducer(this );
085: }
086: }
087:
088: /**
089: * Destroy
090: */
091: protected void destroy() {
092: logger.info("destroy()");
093: }
094:
095: private Reference getReference(String reference) {
096: try {
097: return entityManager.newReference(reference);
098: } catch (Exception ex) {
099: }
100: return null;
101: }
102:
103: private EntityProducer getProducer(Reference ref) {
104: try {
105: return ref.getEntityProducer();
106: } catch (Exception ex) {
107: }
108: return null;
109: }
110:
111: private String getMessageFromBundle(String key) {
112: if (toolBundle == null)
113: toolBundle = new ResourceLoader("chat");
114:
115: return toolBundle.getString(key);
116: }
117:
118: /**
119: * {@inheritDoc}
120: */
121: public boolean canRead(String reference) {
122: Reference ref = getReference(reference);
123: EntityProducer ep = getProducer(ref);
124: if (ep instanceof ChatEntityProducer) {
125: try {
126: ChatEntityProducer cep = (ChatEntityProducer) ep;
127: cep.getMessage(ref);
128: return true;
129: } catch (Exception ex) {
130: }
131: }
132: return false;
133: }
134:
135: /**
136: * {@inheritDoc}
137: */
138: public Integer getAction(Event event) {
139: String evt = event.getEvent();
140: if (evt == null)
141: return SearchBuilderItem.ACTION_UNKNOWN;
142: for (Iterator i = addEvents.iterator(); i.hasNext();) {
143: String match = (String) i.next();
144: if (evt.equals(match)) {
145: return SearchBuilderItem.ACTION_ADD;
146: }
147: }
148: for (Iterator i = removeEvents.iterator(); i.hasNext();) {
149: String match = (String) i.next();
150: if (evt.equals(match)) {
151: return SearchBuilderItem.ACTION_DELETE;
152: }
153: }
154: return SearchBuilderItem.ACTION_UNKNOWN;
155: }
156:
157: /**
158: * {@inheritDoc}
159: */
160: public List getAllContent() {
161: List all = new ArrayList();
162: List l = getChatManager().getContextChannels(null, false);
163: for (Iterator i = l.iterator(); i.hasNext();) {
164:
165: try {
166: ChatChannel c = (ChatChannel) i.next();
167:
168: Set messages = c.getMessages();
169: // WARNING: I think the implementation caches on thread, if this
170: // is
171: // a builder
172: // thread this may not work
173: for (Iterator mi = messages.iterator(); mi.hasNext();) {
174: ChatMessage m = (ChatMessage) mi.next();
175: all.add(m.getReference());
176: }
177: } catch (Exception ex) {
178: logger.error("Got error on channel ", ex); //$NON-NLS-1$
179:
180: }
181: }
182: return all;
183: }
184:
185: /**
186: * {@inheritDoc}
187: */
188: public String getContainer(String reference) {
189: try {
190: return getReference(reference).getContainer();
191: } catch (Exception ex) {
192: return "";
193: }
194: }
195:
196: protected String getMessageOwnerDisplayName(String user) {
197: User sender = null;
198: try {
199: sender = UserDirectoryService.getUser(user);
200: } catch (UserNotDefinedException e) {
201: logger.error(e);
202: return user;
203: }
204: return sender.getDisplayName();
205: }
206:
207: /**
208: * {@inheritDoc}
209: */
210: public String getContent(String reference) {
211: Reference ref = getReference(reference);
212: EntityProducer ep = getProducer(ref);
213:
214: if (ep instanceof ChatEntityProducer) {
215: try {
216: ChatEntityProducer ms = (ChatEntityProducer) ep;
217: ChatMessage m = ms.getMessage(ref);
218: //MessageHeader mh = m.getHeader();
219: StringBuilder sb = new StringBuilder();
220: //Class c = mh.getClass();
221:
222: sb.append(getMessageFromBundle("chat_header")); //$NON-NLS-1$
223: sb.append(getMessageFromBundle("chat_from"));
224: SearchUtils.appendCleanString(
225: getMessageOwnerDisplayName(m.getOwner()), sb); //$NON-NLS-1$
226: sb.append("\n"); //$NON-NLS-1$
227: sb.append(getMessageFromBundle("chat_body")); //$NON-NLS-1$
228: SearchUtils.appendCleanString(m.getBody(), sb);
229:
230: //Chat messages do not contain html so this should be ignored...chmaurer
231: /*
232: for ( HTMLParser hp = new HTMLParser(mBody); hp.hasNext(); ) {
233: SearchUtils.appendCleanString(hp.next(), sb);
234: sb.append(" ");
235: }
236: */
237:
238: sb.append("\n"); //$NON-NLS-1$
239: logger
240: .debug("Message Content for " + ref.getReference() + " is " //$NON-NLS-1$ //$NON-NLS-2$
241: + sb.toString());
242:
243: return sb.toString();
244: } catch (IdUnusedException e) {
245: throw new RuntimeException(
246: " Failed to get message content ", e); //$NON-NLS-1$
247: } catch (PermissionException e) {
248: throw new RuntimeException(
249: " Failed to get message content ", e); //$NON-NLS-1$
250: }
251: }
252:
253: throw new RuntimeException(" Not a Message Entity " + reference); //$NON-NLS-1$
254: }
255:
256: /**
257: * {@inheritDoc}
258: */
259: public Reader getContentReader(String reference) {
260: return new StringReader(getContent(reference));
261: }
262:
263: /**
264: * {@inheritDoc}
265: */
266: public Map getCustomProperties() {
267: return null;
268: }
269:
270: /**
271: * {@inheritDoc}
272: */
273: public String getCustomRDF() {
274: return null;
275: }
276:
277: /**
278: * {@inheritDoc}
279: */
280: public String getId(String reference) {
281: try {
282: return getReference(reference).getId();
283: } catch (Exception ex) {
284: return "";
285: }
286: }
287:
288: /**
289: * {@inheritDoc}
290: */
291: public List getSiteContent(String context) {
292: List all = new ArrayList();
293: List l = getChatManager().getContextChannels(context, false);
294: for (Iterator i = l.iterator(); i.hasNext();) {
295: ChatChannel c = (ChatChannel) i.next();
296: try {
297: Set messages = c.getMessages();
298: // WARNING: I think the implementation caches on thread, if this
299: // is
300: // a builder
301: // thread this may not work
302: for (Iterator mi = messages.iterator(); mi.hasNext();) {
303: ChatMessage m = (ChatMessage) mi.next();
304: all.add(m.getReference());
305: }
306: } catch (Exception ex) {
307: ex.printStackTrace();
308: logger.warn("Failed to get channel " + c.getId()); //$NON-NLS-1$
309:
310: }
311: }
312: return all;
313: }
314:
315: /**
316: * {@inheritDoc}
317: */
318: public Iterator getSiteContentIterator(final String context) {
319: List l = getChatManager().getContextChannels(context, false);
320: final Iterator ci = l.iterator();
321: return new Iterator() {
322: Iterator mi = null;
323:
324: public boolean hasNext() {
325: if (mi == null) {
326: return nextIterator();
327: } else {
328: if (mi.hasNext()) {
329: return true;
330: } else {
331: return nextIterator();
332: }
333: }
334: }
335:
336: private boolean nextIterator() {
337: while (ci.hasNext()) {
338:
339: ChatChannel c = (ChatChannel) ci.next();
340: try {
341: Set messages = c.getMessages();
342: mi = messages.iterator();
343: if (mi.hasNext()) {
344: return true;
345: }
346: } catch (Exception ex) {
347: ex.printStackTrace();
348: logger
349: .warn("Failed to get channel " + c.getId()); //$NON-NLS-1$
350:
351: }
352: }
353: return false;
354: }
355:
356: public Object next() {
357: ChatMessage m = (ChatMessage) mi.next();
358: return m.getReference();
359: }
360:
361: public void remove() {
362: throw new UnsupportedOperationException(
363: "Remove not implemented"); //$NON-NLS-1$
364: }
365:
366: };
367: }
368:
369: private String getSiteId(Reference ref) {
370: return ref.getContext();
371: }
372:
373: /**
374: * {@inheritDoc}
375: */
376: public String getSiteId(String reference) {
377: return getSiteId(entityManager.newReference(reference));
378: }
379:
380: /**
381: * {@inheritDoc}
382: */
383: public String getSubType(String reference) {
384: try {
385: return getReference(reference).getSubType();
386: } catch (Exception ex) {
387: return "";
388: }
389: }
390:
391: /**
392: * {@inheritDoc}
393: */
394: public String getTitle(String reference) {
395: Reference ref = getReference(reference);
396: EntityProducer ep = getProducer(ref);
397: if (ep instanceof ChatEntityProducer) {
398: try {
399: ChatEntityProducer ms = (ChatEntityProducer) ep;
400: ChatMessage m = ms.getMessage(ref);
401: //MessageHeader mh = m.getHeader();
402: Class c = m.getClass();
403: String subject = getMessageFromBundle("chat_message"); //$NON-NLS-1$
404: String title = subject
405: + getMessageFromBundle("chat_from") //$NON-NLS-1$
406: + getMessageOwnerDisplayName(m.getOwner());
407: return SearchUtils.appendCleanString(title, null)
408: .toString();
409:
410: } catch (IdUnusedException e) {
411: throw new RuntimeException(
412: " Failed to get message content ", e); //$NON-NLS-1$
413: } catch (PermissionException e) {
414: throw new RuntimeException(
415: " Failed to get message content ", e); //$NON-NLS-1$
416: }
417: }
418: throw new RuntimeException(" Not a Message Entity " + reference); //$NON-NLS-1$
419:
420: }
421:
422: /**
423: * {@inheritDoc}
424: */
425: public String getTool() {
426: return ChatManager.CHAT;
427: }
428:
429: /**
430: * {@inheritDoc}
431: */
432: public String getType(String ref) {
433: try {
434: return getReference(ref).getType();
435: } catch (Exception ex) {
436: return "";
437: }
438: }
439:
440: /**
441: * {@inheritDoc}
442: */
443: public String getUrl(String reference) {
444: Reference ref = getReference(reference);
445: return ref.getUrl();
446: }
447:
448: /**
449: * {@inheritDoc}
450: */
451: public boolean isContentFromReader(String reference) {
452: return false;
453: }
454:
455: /**
456: * {@inheritDoc}
457: */
458: public boolean isForIndex(String reference) {
459:
460: Reference ref = getReference(reference);
461: EntityProducer ep = getProducer(ref);
462: if (ep instanceof ChatEntityProducer) {
463: try {
464: ChatEntityProducer cep = (ChatEntityProducer) ep;
465: ChatMessage m = cep.getMessage(ref);
466: if (m == null) {
467: logger
468: .debug("Rejected null message " + ref.getReference()); //$NON-NLS-1$
469: return false;
470: }
471: } catch (IdUnusedException e) {
472: logger.debug("Rejected Missing message or Collection " //$NON-NLS-1$
473: + ref.getReference());
474: return false;
475: } catch (PermissionException e) {
476: logger
477: .warn("Rejected private message " + ref.getReference()); //$NON-NLS-1$
478: return false;
479: }
480: return true;
481: }
482: return false;
483: }
484:
485: /**
486: * {@inheritDoc}
487: */
488: public boolean matches(String reference) {
489: Reference ref = getReference(reference);
490: EntityProducer ep = getProducer(ref);
491:
492: if (ep instanceof ChatEntityProducer) {
493: return true;
494: }
495: return false;
496: }
497:
498: /**
499: * {@inheritDoc}
500: */
501: public boolean matches(Event event) {
502: return matches(event.getResource());
503: }
504:
505: public SearchService getSearchService() {
506: return searchService;
507: }
508:
509: public void setSearchService(SearchService searchService) {
510: this .searchService = searchService;
511: }
512:
513: public EntityManager getEntityManager() {
514: return entityManager;
515: }
516:
517: public void setEntityManager(EntityManager entityManager) {
518: this .entityManager = entityManager;
519: }
520:
521: public ChatManager getChatManager() {
522: return chatManager;
523: }
524:
525: public void setChatManager(ChatManager chatManager) {
526: this .chatManager = chatManager;
527: }
528:
529: public List getAddEvents() {
530: return addEvents;
531: }
532:
533: public void setAddEvents(List addEvents) {
534: this .addEvents = addEvents;
535: }
536:
537: public List getRemoveEvents() {
538: return removeEvents;
539: }
540:
541: public void setRemoveEvents(List removeEvents) {
542: this .removeEvents = removeEvents;
543: }
544:
545: public SearchIndexBuilder getSearchIndexBuilder() {
546: return searchIndexBuilder;
547: }
548:
549: public void setSearchIndexBuilder(
550: SearchIndexBuilder searchIndexBuilder) {
551: this.searchIndexBuilder = searchIndexBuilder;
552: }
553:
554: }
|