/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.contrib.mailarchive.script.internal;
import java.io.IOException;
import java.util.ArrayList;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.mail.Message;
import javax.mail.MessagingException;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.codehaus.plexus.util.StringOutputStream;
import org.slf4j.Logger;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.component.phase.InitializationException;
import org.xwiki.contrib.mail.internal.FolderItem;
import org.xwiki.contrib.mailarchive.IMAUser;
import org.xwiki.contrib.mailarchive.IMailArchive;
import org.xwiki.contrib.mailarchive.IMailArchiveConfiguration;
import org.xwiki.contrib.mailarchive.LoadingSession;
import org.xwiki.contrib.mailarchive.exceptions.MailArchiveException;
import org.xwiki.contrib.mailarchive.internal.LoadingJob;
import org.xwiki.contrib.mailarchive.internal.data.IFactory;
import org.xwiki.contrib.mailarchive.internal.threads.ThreadMessageBean;
import org.xwiki.contrib.mailarchive.script.IMailArchiveScriptService;
import org.xwiki.contrib.mailarchive.timeline.ITimeLineGenerator;
import org.xwiki.contrib.mailarchive.utils.DecodedMailContent;
import org.xwiki.job.DefaultRequest;
import org.xwiki.job.Job;
import org.xwiki.job.JobManager;
import org.xwiki.script.service.ScriptService;
import com.xpn.xwiki.objects.BaseObject;
/**
* Make the IMailArchive API available to scripting.
*/
@Component
@Named("mailarchive")
@Singleton
/**
* Mail Archive Script Service.
*
* @version $Id$
*/
public class MailArchiveScriptService implements ScriptService, IMailArchiveScriptService
{
@Inject
private IMailArchive mailArchive;
@Inject
private ITimeLineGenerator timeline;
@Inject
private IFactory factory;
@Inject
private JobManager jobManager;
@Inject
private ComponentManager componentManager;
@Inject
private Logger logger;
/**
* {@inheritDoc}
*
* @see org.xwiki.contrib.mailarchive.script.IMailArchiveScriptService#session()
*/
@Override
public LoadingSession session()
{
return new LoadingSession();
}
@Override
public LoadingSession session(final String sessionPrefsDoc)
{
return factory.createLoadingSession(sessionPrefsDoc);
}
@Override
public LoadingSession sessionFromXObject(final BaseObject sessionObject)
{
logger.error("Create LoadingSession from BaseObject " + sessionObject);
return factory.createLoadingSession(sessionObject);
}
@Override
public int check(final String serverPrefsDoc)
{
return mailArchive.checkSource(serverPrefsDoc);
}
@Override
public ArrayList<FolderItem> getFolderTree(String serverPrefsDoc)
{
return mailArchive.getFolderTree(serverPrefsDoc);
}
@Override
public int load(final LoadingSession session)
{
LoadingJob job = createLoadingJob(session, true);
return job != null ? job.getStatus().getNbSuccess() : -1;
}
@Override
public Job startLoadingJob(final LoadingSession session)
{
return createLoadingJob(session, false);
}
@Override
public Job getCurrentJob()
{
return jobManager.getCurrentJob();
}
@Override
public ArrayList<ThreadMessageBean> thread(final String topicid)
{
// We "flatten" the output to avoid needing recursivity to display the thread(s).
return this.mailArchive.computeThreads(topicid).flatten();
}
@Override
public ArrayList<ThreadMessageBean> thread()
{
return thread(null);
}
@Override
public IMAUser parseUser(final String internetAddress)
{
return mailArchive.parseUser(internetAddress);
}
@Override
public ITimeLineGenerator getTimeline()
{
return this.timeline;
}
@Override
public DecodedMailContent getDecodedMailText(final String mailPage, final boolean cut)
{
try {
return this.mailArchive.getDecodedMailText(mailPage, cut);
} catch (Exception e) {
System.out.println("MailArchiveScriptService: failed to decode mail content");
e.printStackTrace();
return new DecodedMailContent(false, "<<invalid content>>");
}
}
@Override
public IMailArchiveConfiguration getConfig()
{
try {
return this.mailArchive.getConfiguration();
} catch (InitializationException e) {
e.printStackTrace();
return null;
} catch (MailArchiveException e) {
e.printStackTrace();
return null;
}
}
/**
* Creates a loading job either in synchronous or asynchronous mode.<br/>
* To check for progress/results, cf. {@link org.xwiki.contrib.}
*
* @param session The Loading Session description.
* @param synchronous If true creates a job and waits for its end, if false returns right away.
* @return Created LoadingJob, or null if a problem occurred.
*/
private LoadingJob createLoadingJob(final LoadingSession session, boolean synchronous)
{
if (mailArchive.isLocked()) {
logger.info("Archive is locked, not running new job");
return null;
}
if (session == null) {
logger.warn("Missing loading session object.");
return null;
}
LoadingJob job;
try {
job = this.componentManager.getInstance(Job.class, LoadingJob.JOBTYPE);
} catch (ComponentLookupException e) {
logger.error("Failed to lookup any Job for role hint [" + LoadingJob.JOBTYPE + "]", e);
return null;
}
final String id = LoadingJob.JOB_ID;
DefaultRequest request = new DefaultRequest();
// FIXME: ID of request might be mailarchive/<sessionId>/<namespace> ? ... to retrieve jobs later on ...
request.setId(id);
request.setProperty(LoadingJob.JOB_PROPERTY_TYPE, LoadingJob.JOBTYPE);
request.setInteractive(false);
request.setProperty(LoadingJob.JOB_PROPERTY_SESSION, session);
job.initialize(request);
jobManager.addJob(job);
if (synchronous) {
try {
job.join();
} catch (InterruptedException e) {
// Ignore
}
}
return job;
}
@Override
public String getOriginal(String serverId, String messageId)
{
String original = null;
try {
Message message = this.mailArchive.getFromStore(serverId, messageId);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
message.writeTo(baos);
// FIXME: not sure about utf-8 here...
original = baos.toString("UTF-8");
} catch (Exception e) {
logger.debug("Error retrieving original message", e);
}
return original;
}
}