/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/chat/trunk/chat-impl/impl/src/java/org/sakaiproject/chat2/model/impl/ChatContentProducer.java $
* $Id: ChatContentProducer.java 105079 2012-02-24 23:08:11Z ottenhoff@longsight.com $
***********************************************************************************
*
* Copyright (c) 2007, 2008 The Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
/**
*
*/
package org.sakaiproject.chat2.model.impl;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.chat2.model.ChatChannel;
import org.sakaiproject.chat2.model.ChatManager;
import org.sakaiproject.chat2.model.ChatMessage;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.entity.api.EntityManager;
import org.sakaiproject.entity.api.EntityProducer;
import org.sakaiproject.entity.api.Reference;
import org.sakaiproject.event.api.Event;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.search.api.EntityContentProducer;
import org.sakaiproject.search.api.SearchIndexBuilder;
import org.sakaiproject.search.api.SearchService;
import org.sakaiproject.search.api.SearchUtils;
import org.sakaiproject.search.model.SearchBuilderItem;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.user.api.ContextualUserDisplayService;
import org.sakaiproject.user.api.User;
import org.sakaiproject.user.api.UserNotDefinedException;
import org.sakaiproject.user.cover.UserDirectoryService;
import org.sakaiproject.util.ResourceLoader;
/**
* @author chrismaurer
*
*/
public class ChatContentProducer implements EntityContentProducer {
protected final Log logger = LogFactory.getLog(getClass());
private SearchService searchService = null;
private SearchIndexBuilder searchIndexBuilder = null;
private EntityManager entityManager = null;
private ChatManager chatManager = null;
private List addEvents = new ArrayList();
private List removeEvents = new ArrayList();
private ResourceLoader toolBundle;
private ContextualUserDisplayService contextualUserDisplayService;
private SiteService siteService;
public void setSiteService(SiteService siteService) {
this.siteService = siteService;
}
protected void init() throws Exception {
logger.info("init()");
if ("true".equals(ServerConfigurationService.getString( //$NON-NLS-1$
"search.enable", "false"))) //$NON-NLS-1$ //$NON-NLS-2$
{
for (Iterator i = addEvents.iterator(); i.hasNext();)
{
getSearchService().registerFunction((String) i.next());
}
for (Iterator i = removeEvents.iterator(); i.hasNext();)
{
getSearchService().registerFunction((String) i.next());
}
getSearchIndexBuilder().registerEntityContentProducer(this);
}
contextualUserDisplayService = (ContextualUserDisplayService) ComponentManager.get("org.sakaiproject.user.api.ContextualUserDisplayService");
}
/**
* Destroy
*/
protected void destroy()
{
logger.info("destroy()");
}
private Reference getReference(String reference) {
try {
return entityManager.newReference(reference);
} catch ( Exception ex ) {
}
return null;
}
private EntityProducer getProducer(Reference ref) {
try {
return ref.getEntityProducer();
} catch ( Exception ex ) {
}
return null;
}
private String getMessageFromBundle(String key) {
if (toolBundle == null)
toolBundle = new ResourceLoader("chat");
return toolBundle.getString(key);
}
/**
* {@inheritDoc}
*/
public boolean canRead(String reference)
{
Reference ref = getReference(reference);
EntityProducer ep = getProducer(ref);
if (ep instanceof ChatEntityProducer)
{
try
{
ChatEntityProducer cep = (ChatEntityProducer) ep;
cep.getMessage(ref);
return true;
}
catch (Exception ex)
{
}
}
return false;
}
/**
* {@inheritDoc}
*/
public Integer getAction(Event event)
{
String evt = event.getEvent();
if (evt == null) return SearchBuilderItem.ACTION_UNKNOWN;
for (Iterator i = addEvents.iterator(); i.hasNext();)
{
String match = (String) i.next();
if (evt.equals(match))
{
return SearchBuilderItem.ACTION_ADD;
}
}
for (Iterator i = removeEvents.iterator(); i.hasNext();)
{
String match = (String) i.next();
if (evt.equals(match))
{
return SearchBuilderItem.ACTION_DELETE;
}
}
return SearchBuilderItem.ACTION_UNKNOWN;
}
/**
* {@inheritDoc}
*/
public List getAllContent()
{
List all = new ArrayList();
List l = getChatManager().getContextChannels(null, false);
for (Iterator i = l.iterator(); i.hasNext();)
{
try
{
ChatChannel c = (ChatChannel) i.next();
Set messages = c.getMessages();
// WARNING: I think the implementation caches on thread, if this
// is
// a builder
// thread this may not work
for (Iterator mi = messages.iterator(); mi.hasNext();)
{
ChatMessage m = (ChatMessage) mi.next();
all.add(m.getReference());
}
}
catch (Exception ex)
{
logger.error("Got error on channel ", ex); //$NON-NLS-1$
}
}
return all;
}
/**
* {@inheritDoc}
*/
public String getContainer(String reference)
{
try {
return getReference(reference).getContainer();
} catch ( Exception ex ) {
return "";
}
}
protected String getMessageOwnerDisplayName(String user, String context)
{
User sender = null;
try {
sender = UserDirectoryService.getUser(user);
} catch(UserNotDefinedException e) {
logger.error(e);
return user;
}
if (contextualUserDisplayService == null) {
return sender.getDisplayName();
} else {
String ret = contextualUserDisplayService.getUserDisplayName(sender, siteService.siteReference(context));
if (ret == null)
ret = sender.getDisplayName();
return ret;
}
}
/**
* {@inheritDoc}
*/
public String getContent(String reference)
{
Reference ref = getReference(reference);
EntityProducer ep = getProducer(ref);
if (ep instanceof ChatEntityProducer)
{
try
{
ChatEntityProducer ms = (ChatEntityProducer) ep;
ChatMessage m = ms.getMessage(ref);
//MessageHeader mh = m.getHeader();
StringBuilder sb = new StringBuilder();
//Class c = mh.getClass();
sb.append(getMessageFromBundle("chat_header")); //$NON-NLS-1$
sb.append(getMessageFromBundle("chat_from"));
String context = m.getChatChannel().getContext();
SearchUtils.appendCleanString(getMessageOwnerDisplayName(m.getOwner(),context),sb); //$NON-NLS-1$
sb.append("\n"); //$NON-NLS-1$
sb.append(getMessageFromBundle("chat_body")); //$NON-NLS-1$
SearchUtils.appendCleanString(m.getBody(), sb);
//Chat messages do not contain html so this should be ignored...chmaurer
/*
for ( HTMLParser hp = new HTMLParser(mBody); hp.hasNext(); ) {
SearchUtils.appendCleanString(hp.next(), sb);
sb.append(" ");
}
*/
sb.append("\n"); //$NON-NLS-1$
logger.debug("Message Content for " + ref.getReference() + " is " //$NON-NLS-1$ //$NON-NLS-2$
+ sb.toString());
return sb.toString();
}
catch (IdUnusedException e)
{
throw new RuntimeException(" Failed to get message content ", e); //$NON-NLS-1$
}
catch (PermissionException e)
{
throw new RuntimeException(" Failed to get message content ", e); //$NON-NLS-1$
}
}
throw new RuntimeException(" Not a Message Entity " + reference); //$NON-NLS-1$
}
/**
* {@inheritDoc}
*/
public Reader getContentReader(String reference) {
return new StringReader(getContent(reference));
}
/**
* {@inheritDoc}
*/
public Map getCustomProperties(String ref) {
return null;
}
/**
* {@inheritDoc}
*/
public String getCustomRDF(String ref) {
return null;
}
/**
* {@inheritDoc}
*/
public String getId(String reference)
{
try {
return getReference(reference).getId();
} catch ( Exception ex ) {
return "";
}
}
/**
* {@inheritDoc}
*/
public List getSiteContent(String context)
{
List all = new ArrayList();
List l = getChatManager().getContextChannels(context, false);
for (Iterator i = l.iterator(); i.hasNext();)
{
ChatChannel c = (ChatChannel) i.next();
try
{
Set messages = c.getMessages();
// WARNING: I think the implementation caches on thread, if this
// is
// a builder
// thread this may not work
for (Iterator mi = messages.iterator(); mi.hasNext();)
{
ChatMessage m = (ChatMessage) mi.next();
all.add(m.getReference());
}
}
catch (Exception ex)
{
ex.printStackTrace();
logger.warn("Failed to get channel " + c.getId()); //$NON-NLS-1$
}
}
return all;
}
/**
* {@inheritDoc}
*/
public Iterator getSiteContentIterator(final String context)
{
List l = getChatManager().getContextChannels(context, false);
final Iterator ci = l.iterator();
return new Iterator()
{
Iterator mi = null;
public boolean hasNext()
{
if (mi == null)
{
return nextIterator();
}
else
{
if (mi.hasNext())
{
return true;
}
else
{
return nextIterator();
}
}
}
private boolean nextIterator()
{
while (ci.hasNext())
{
ChatChannel c = (ChatChannel) ci.next();
try
{
Set messages = c.getMessages();
mi = messages.iterator();
if (mi.hasNext())
{
return true;
}
}
catch (Exception ex)
{
ex.printStackTrace();
logger.warn("Failed to get channel " + c.getId()); //$NON-NLS-1$
}
}
return false;
}
public Object next()
{
ChatMessage m = (ChatMessage) mi.next();
return m.getReference();
}
public void remove()
{
throw new UnsupportedOperationException(
"Remove not implemented"); //$NON-NLS-1$
}
};
}
private String getSiteId(Reference ref)
{
return ref.getContext();
}
/**
* {@inheritDoc}
*/
public String getSiteId(String reference) {
return getSiteId(entityManager.newReference(reference));
}
/**
* {@inheritDoc}
*/
public String getSubType(String reference)
{
try {
return getReference(reference).getSubType();
} catch ( Exception ex ) {
return "";
}
}
/**
* {@inheritDoc}
*/
public String getTitle(String reference)
{
Reference ref = getReference(reference);
EntityProducer ep = getProducer(ref);
if (ep instanceof ChatEntityProducer)
{
try
{
ChatEntityProducer ms = (ChatEntityProducer) ep;
ChatMessage m = ms.getMessage(ref);
String subject = getMessageFromBundle("chat_message"); //$NON-NLS-1$
String title = subject + getMessageFromBundle("chat_from") //$NON-NLS-1$
+ getMessageOwnerDisplayName(m.getOwner(), m.getChatChannel().getContext());
return SearchUtils.appendCleanString(title,null).toString();
}
catch (IdUnusedException e)
{
throw new RuntimeException(" Failed to get message content ", e); //$NON-NLS-1$
}
catch (PermissionException e)
{
throw new RuntimeException(" Failed to get message content ", e); //$NON-NLS-1$
}
}
throw new RuntimeException(" Not a Message Entity " + reference); //$NON-NLS-1$
}
/**
* {@inheritDoc}
*/
public String getTool() {
return ChatManager.CHAT;
}
/**
* {@inheritDoc}
*/
public String getType(String ref) {
try {
return getReference(ref).getType();
} catch ( Exception ex ) {
return "";
}
}
/**
* {@inheritDoc}
*/
public String getUrl(String reference) {
Reference ref = getReference(reference);
return ref.getUrl();
}
/**
* {@inheritDoc}
*/
public boolean isContentFromReader(String reference) {
return false;
}
/**
* {@inheritDoc}
*/
public boolean isForIndex(String reference)
{
Reference ref = getReference(reference);
EntityProducer ep = getProducer(ref);
if (ep instanceof ChatEntityProducer)
{
try
{
ChatEntityProducer cep = (ChatEntityProducer) ep;
ChatMessage m = cep.getMessage(ref);
if (m == null)
{
logger.debug("Rejected null message " + ref.getReference()); //$NON-NLS-1$
return false;
}
}
catch (IdUnusedException e)
{
logger.debug("Rejected Missing message or Collection " //$NON-NLS-1$
+ ref.getReference());
return false;
}
catch (PermissionException e)
{
logger.warn("Rejected private message " + ref.getReference()); //$NON-NLS-1$
return false;
}
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
public boolean matches(String reference)
{
Reference ref = getReference(reference);
EntityProducer ep = getProducer(ref);
if (ep instanceof ChatEntityProducer)
{
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
public boolean matches(Event event)
{
return matches(event.getResource());
}
public SearchService getSearchService() {
return searchService;
}
public void setSearchService(SearchService searchService) {
this.searchService = searchService;
}
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public ChatManager getChatManager() {
return chatManager;
}
public void setChatManager(ChatManager chatManager) {
this.chatManager = chatManager;
}
public List getAddEvents() {
return addEvents;
}
public void setAddEvents(List addEvents) {
this.addEvents = addEvents;
}
public List getRemoveEvents() {
return removeEvents;
}
public void setRemoveEvents(List removeEvents) {
this.removeEvents = removeEvents;
}
public SearchIndexBuilder getSearchIndexBuilder() {
return searchIndexBuilder;
}
public void setSearchIndexBuilder(SearchIndexBuilder searchIndexBuilder) {
this.searchIndexBuilder = searchIndexBuilder;
}
}