Package org.exist.xquery.modules.mail

Source Code of org.exist.xquery.modules.mail.MessageListFunctions

/*
*  eXist Mail Module Extension MessageListFunctions
*  Copyright (C) 2006-09 Adam Retter <adam.retter@devon.gov.uk>
*  www.adamretter.co.uk
*  This program 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
*  of the License, or (at your option) any later version.
*
*  This program 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 program; if not, write to the Free Software Foundation
*  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*  $Id$
*/

package org.exist.xquery.modules.mail;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import javax.mail.Address;
import javax.mail.FetchProfile;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Header;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.search.AndTerm;
import javax.mail.search.BodyTerm;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.FlagTerm;
import javax.mail.search.FromStringTerm;
import javax.mail.search.HeaderTerm;
import javax.mail.search.NotTerm;
import javax.mail.search.OrTerm;
import javax.mail.search.ReceivedDateTerm;
import javax.mail.search.RecipientStringTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SentDateTerm;
import javax.mail.search.SubjectTerm;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.exist.dom.QName;
import org.exist.memtree.MemTreeBuilder;
import org.exist.xquery.BasicFunction;
import org.exist.xquery.Cardinality;
import org.exist.xquery.FunctionSignature;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;
import org.exist.xquery.value.FunctionParameterSequenceType;
import org.exist.xquery.value.FunctionReturnSequenceType;
import org.exist.xquery.value.IntegerValue;
import org.exist.xquery.value.NodeValue;
import org.exist.xquery.value.Sequence;
import org.exist.xquery.value.SequenceType;
import org.exist.xquery.value.Type;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* eXist Mail Module Extension GetMessageList
*
* Get a mail store
*
* @author Andrzej Taramina <andrzej@chaeron.com>
* @serial 2009-03-12
* @version 1.3
*
* @see org.exist.xquery.BasicFunction#BasicFunction(org.exist.xquery.XQueryContext, org.exist.xquery.FunctionSignature)
*/
public class MessageListFunctions extends BasicFunction
{
  protected static final Logger logger = Logger.getLogger(MessageListFunctions.class);

  public final static FunctionSignature signatures[] = {
    new FunctionSignature(
      new QName( "get-message-list", MailModule.NAMESPACE_URI, MailModule.PREFIX ),
      "Returns a message list of all messages in a folder.",
      new SequenceType[]
      {
        new FunctionParameterSequenceType( "mail-folder-handle", Type.INTEGER, Cardinality.EXACTLY_ONE, "The mail folder handle retrieved from mail:get-mail-folder()" )
      },
      new FunctionReturnSequenceType( Type.LONG, Cardinality.ZERO_OR_ONE, "an xs:long representing the message list handle." )
      ),
   
    new FunctionSignature(
      new QName( "search-message-list", MailModule.NAMESPACE_URI, MailModule.PREFIX ),
      "Searches messages in a folder. " +
      "Search terms are of the form <searchTerm type=\"xxx\">...</searchTerm>.  Valid types include: not, and, or, from, subject, body, recipient, header, flag, sent, received. " +
      "<searchTerm type=\"not\"> requires a single nested child search term. <searchTerm type=\"and\"> and <searchTerm type=\"or\"> must have one or more nested child search terms. " +
      "<searchTerm type=\"from\" pattern=\"pat\">, <searchTerm type=\"subject\" pattern=\"pat\"> and <searchTerm type=\"body\" pattern=\"pat\">  require a pattern attribute and will search for a substring that matches the pattern. " +
      "<searchTerm type=\"recipient\" pattern=\"pat\" recipientType=\"to|cc|bcc\"> requires pattern and recipientType attributes. " +
      "<searchTerm type=\"header\" pattern=\"pat\" name=\"Content-Type\"> requires pattern and name attributes. " +
      "<searchTerm type=\"flag\" flag=\"answered|deleted|draft|recent|seen\" value=\"true|false\"> requires flag and value attributes. " +
      "<searchTerm type=\"sent\" comparison=\"eq|gt|ge|lt|le|ne\" format=\"format\" date=\"date\"> and <searchTerm type=\"received\" comparison=\"eq|gt|ge|lt|le|ne\" format=\"format\" date=\"date\"> require comparison, format and date attributes. " +
      "The format string should conform to Java SimpleDateFormat specifications and the date string must conform to the specified format string.",
      new SequenceType[]
      {
        new FunctionParameterSequenceType( "mail-folder-handle", Type.INTEGER, Cardinality.EXACTLY_ONE, "The mail folder handle retrieved from mail:get-mail-folder()" ),
        new FunctionParameterSequenceType( "search-parameters", Type.ELEMENT, Cardinality.EXACTLY_ONE, "The xml fragment defining the search terms" )
      },
      new FunctionReturnSequenceType( Type.LONG, Cardinality.ZERO_OR_ONE, "an xs:long representing the message list handle." )
      ),
   
    new FunctionSignature(
      new QName( "get-message-list-as-xml", MailModule.NAMESPACE_URI, MailModule.PREFIX ),
      "Returns a message list of all messages in a folder as XML.  If there are no messages in the list, an empty sequence will be returned",
      new SequenceType[]
      {
        new FunctionParameterSequenceType( "message-list-handle", Type.INTEGER, Cardinality.EXACTLY_ONE, "The message list handle retrieved from mail:get-message-list() or mail:search-message-list()" ),
        new FunctionParameterSequenceType( "include-headers", Type.BOOLEAN, Cardinality.EXACTLY_ONE, "A boolean specifying whether to include message headers" )
      },
      new FunctionReturnSequenceType( Type.ELEMENT, Cardinality.ZERO_OR_ONE, "the list of all messages in a folder as XML" )
      ),
   
    new FunctionSignature(
      new QName( "close-message-list", MailModule.NAMESPACE_URI, MailModule.PREFIX ),
      "Closes a message list.",
      new SequenceType[]
      {
        new FunctionParameterSequenceType( "message-list-handle", Type.INTEGER, Cardinality.EXACTLY_ONE, "The message list handle retrieved from mail:get-message-list() or mail:search-message-list()" )
      },
      new SequenceType( Type.ITEM, Cardinality.EMPTY )
      )
  };
 
  private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
 
  private static final String PREFETCH_HEADERS[] = {
    "Return-Path",
    "Delivered-To",
    "Received",
    "Date",
    "From",
    "To",
    "Message-ID",
    "Subject",
    "MIME-Version",
    "Content-Type",
    "Content-Transfer-Encoding",
    "X-Mailer",
    "X-Priority"
  };

  /**
   * MessageListFunctions Constructor
   *
   * @param context  The Context of the calling XQuery
   */
  public MessageListFunctions( XQueryContext context, FunctionSignature signature )
  {
    super( context, signature );
    }

  /**
   * evaluate the call to the xquery get-message-list function,
   * it is really the main entry point of this class
   *
   * @param args    arguments from the get-message-list() function call
   * @param contextSequence  the Context Sequence to operate on (not used here internally!)
   * @return    A sequence representing the result of the get-message-list() function call
   *
   * @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
   */
  public Sequence eval( Sequence[] args, Sequence contextSequence ) throws XPathException
  {
    if( isCalledAs( "get-message-list" ) ) {
      Sequence messageList = getMessageList( args, contextSequence );
      return messageList;
    } else if( isCalledAs( "search-message-list" ) ) {
      Sequence searchMessageList = searchMessageList( args, contextSequence );
      return searchMessageList;
    } else if( isCalledAs( "get-message-list-as-xml" ) ) {
      Sequence messageListAsXML = getMessageListAsXML( args, contextSequence );
      return messageListAsXML;
    } else if( isCalledAs( "close-message-list" ) ) {
      Sequence closeMessageList = closeMessageList( args, contextSequence );
      return closeMessageList;
    }
     
    throw( new XPathException(this, "Invalid function name" ) )
  }
 
 
  //***************************************************************************
  //*
  //*    Function Implementation Methods
  //*
  //***************************************************************************/
 
  private Sequence getMessageList( Sequence[] args, Sequence contextSequence ) throws XPathException
  {
    Message[] msgList;
   
    // was a folder handle specified?
    if( args[0].isEmpty() ) {
      throw( new XPathException(this, "Folder handle not specified" ) );
    }

    // get the Folder
    long folderHandle = ((IntegerValue)args[0].itemAt(0)).getLong();
    Folder folder= MailModule.retrieveFolder( context, folderHandle );
    if( folder == null ) {
      throw( new XPathException(this, "Invalid Folder handle specified" ) );
    }
   
    try {
      msgList = folder.getMessages();
      prefetchMessages( folder, msgList );
    }
    catch( MessagingException me ) {
      throw( new XPathException(this, "Failed to get mail list", me ) );
    }
   
    // save the message list and return the handle of the message list
     
    return( new IntegerValue( MailModule.storeMessageList( context, msgList, folderHandle ) ) );
  }
 
 
  private Sequence searchMessageList( Sequence[] args, Sequence contextSequence ) throws XPathException
  {
    Message[] msgList;
   
    // was a folder handle specified?
    if( args[0].isEmpty() || args[1].isEmpty() ) {
      throw( new XPathException(this, "Folder handle or Search Terms not specified" ) );
    }

    // get the Folder
    long folderHandle = ((IntegerValue)args[0].itemAt(0)).getLong();
    Folder folder= MailModule.retrieveFolder( context, folderHandle );
    if( folder == null ) {
      throw( new XPathException(this, "Invalid Folder handle specified" ) );
    }
   
    Node searchTermsXML = ( (NodeValue)args[1].itemAt( 0 ) ).getNode();
   
    try {
      msgList = folder.search( parseSearchTerms( searchTermsXML ) );
     
      prefetchMessages( folder, msgList );
    }
    catch( MessagingException me ) {
      throw( new XPathException(this, "Failed to get mail list", me ) );
    }
   
    // save the message list and return the handle of the message list
     
    return( new IntegerValue( MailModule.storeMessageList( context, msgList, folderHandle ) ) );
  }
 
 
  private void prefetchMessages( Folder folder, Message[] msgList ) throws MessagingException
  {
    // Prefetch all the key information and headers
   
    FetchProfile fp = new FetchProfile();
    fp.add( FetchProfile.Item.ENVELOPE );
   
        for (String PREFETCH_HEADER : PREFETCH_HEADERS) {
            fp.add(PREFETCH_HEADER);
        }
    folder.fetch( msgList, fp );
  }


  private Sequence getMessageListAsXML( Sequence[] args, Sequence contextSequence ) throws XPathException
  {
    Message[]      msgList;
    Sequence      ret    = Sequence.EMPTY_SEQUENCE;
   
    // was a msgList handle specified?
    if( args[0].isEmpty() ) {
      throw( new XPathException(this, "Message List handle not specified" ) );
    }

    // get the MessageList
    long msgListHandle = ((IntegerValue)args[0].itemAt(0)).getLong();
    msgList = MailModule.retrieveMessageList( context, msgListHandle );
    if( msgList == null ) {
      throw( new XPathException(this, "Invalid Message List handle specified" ) );
    }
   
    if( msgList.length > 0 ) {
     
      boolean includeHeaders = args[1].effectiveBooleanValue();
     
      MemTreeBuilder builder = context.getDocumentBuilder();
       
          builder.startDocument();
          builder.startElement( new QName( "messages", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
          builder.addAttribute( new QName( "count", null, null ), String.valueOf( msgList.length ) );
     
      try {
        for( int i = 0; i < msgList.length; i++ ) {
          Message message = msgList[ i ];
         
          builder.startElement( new QName( "message", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );

          builder.addAttribute( new QName( "number", null, null ), String.valueOf(message.getMessageNumber()) );
         
          // Sent Date
          if( message.getSentDate() != null ) {
            builder.startElement( new QName( "sent", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
            builder.characters( formatDate( message.getSentDate() ) );
            builder.endElement();
              }
         
          // Received Date
          if( message.getReceivedDate() != null ) {
            builder.startElement( new QName( "received", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
            builder.characters( formatDate( message.getReceivedDate() ) );
            builder.endElement();
              }
         
          // From
          if( message.getFrom() != null ) {
            builder.startElement( new QName( "from", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
            builder.characters( message.getFrom()[0].toString() );
            builder.endElement();
          }
         
          // Recipients
          builder.startElement( new QName( "recipients", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
            // To Recipients
            Address[] toAddresses = message.getRecipients( Message.RecipientType.TO );
            if( toAddresses != null ) {
                        for (Address to : toAddresses) {
                            builder.startElement( new QName( "recipient", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                            builder.addAttribute( new QName( "type", null, null ), "to" );
                            builder.characters(to.toString());
                            builder.endElement();
                        }
            }
           
            // cc Recipients
            Address[] ccAddresses = message.getRecipients( Message.RecipientType.CC );
            if( ccAddresses != null ) {
                        for (Address ccAddress : ccAddresses) {
                            builder.startElement( new QName( "recipient", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                            builder.addAttribute( new QName( "type", null, null ), "cc" );
                            builder.characters(ccAddress.toString());
                            builder.endElement();
                        }
            }
           
            // bcc Recipients
            Address[] bccAddresses = message.getRecipients( Message.RecipientType.BCC );
            if( bccAddresses != null ) {
                        for (Address bccAddress : bccAddresses) {
                            builder.startElement( new QName( "recipient", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                            builder.addAttribute( new QName( "type", null, null ), "bcc" );
                            builder.characters(bccAddress.toString());
                            builder.endElement();
                        }
            }
          builder.endElement();
         
          // Flags
         
          Flags       flags   = message.getFlags();
          Flags.Flag[]   systemFlags    = flags.getSystemFlags();
          String[]     userFlags     = flags.getUserFlags();
         
          if( systemFlags.length > 0 || userFlags.length > 0 ) {
            builder.startElement( new QName( "flags", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
           
                        for (Flags.Flag systemFlag : systemFlags) {
                            if (systemFlag == Flags.Flag.ANSWERED) {
                                builder.startElement( new QName( "flag", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                                builder.addAttribute( new QName( "type", null, null ), "answered" );
                                builder.endElement();
                            } else if (systemFlag == Flags.Flag.DELETED) {
                                builder.startElement( new QName( "flag", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                                builder.addAttribute( new QName( "type", null, null ), "deleted" );
                                builder.endElement();
                            } else if (systemFlag == Flags.Flag.DRAFT) {
                                builder.startElement( new QName( "flag", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                                builder.addAttribute( new QName( "type", null, null ), "draft" );
                                builder.endElement();
                            } else if (systemFlag == Flags.Flag.FLAGGED) {
                                builder.startElement( new QName( "flag", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                                builder.addAttribute( new QName( "type", null, null ), "flagged" );
                                builder.endElement();
                            } else if (systemFlag == Flags.Flag.RECENT) {
                                builder.startElement( new QName( "flag", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                                builder.addAttribute( new QName( "type", null, null ), "recent" );
                                builder.endElement();
                            } else if (systemFlag == Flags.Flag.SEEN) {
                                builder.startElement( new QName( "flag", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                                builder.addAttribute( new QName( "type", null, null ), "seen" );
                                builder.endElement();
                            }
                        }
           
                        for (String userFlag : userFlags) {
                            builder.startElement( new QName( "flag", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                            builder.addAttribute( new QName( "type", null, null ), "user" );
                            builder.addAttribute(new QName( "value", null, null ), userFlag);
                            builder.endElement();
                        }

            builder.endElement();
          }

          // Headers
         
          if( includeHeaders ) {
            Enumeration headers = message.getAllHeaders();
           
            if( headers.hasMoreElements() ) {
              builder.startElement( new QName( "headers", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
             
              while( headers.hasMoreElements() ) {
                Header header = (Header)headers.nextElement();
               
                builder.startElement( new QName( "header", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
                      builder.addAttribute( new QName( "name", null, null ), header.getName() );
                builder.addAttribute( new QName( "value", null, null ), header.getValue() );
                builder.endElement();
              }
             
              builder.endElement();
            }
          }
         
          // Subject
          builder.startElement( new QName( "subject", MailModule.NAMESPACE_URI, MailModule.PREFIX ), null );
          builder.characters( message.getSubject() );
          builder.endElement();
         
          builder.endElement();
        }
      }
      catch( MessagingException me ) {
        throw( new XPathException(this, "Failed to retrieve messages from list", me ) );
      }
     
      builder.endElement();
       
          ret = (NodeValue)builder.getDocument().getDocumentElement();
    }
   
    return( ret );
  }
 
  private String formatDate( Date date )
  {
    String formatted = "";
   
    SimpleDateFormat sdf = new SimpleDateFormat( DATE_FORMAT );
   
    String temp = sdf.format( date );
   
    formatted = temp.substring( 0, temp.length() - 2 ) + ":" + temp.substring( temp.length() - 2 );
   
    return( formatted );
  }
 
 
  private Sequence closeMessageList( Sequence[] args, Sequence contextSequence ) throws XPathException
  {
    // was a msgList handle specified?
    if( args[0].isEmpty() ) {
      throw( new XPathException(this, "Message List handle not specified" ) );
    }
   
    // get the msgList
    long msgListHandle = ((IntegerValue)args[0].itemAt(0)).getLong();
 
    MailModule.removeMessageList( context, msgListHandle );
     
    return( Sequence.EMPTY_SEQUENCE );
  }
 
 
  //***************************************************************************
  //*
  //*    Search Term Methods
  //*
  //***************************************************************************/
 
  private SearchTerm parseSearchTerms( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    if( terms.getNodeType() == Node.ELEMENT_NODE && terms.getLocalName().equalsIgnoreCase( "searchTerm" ) ) {
      String type  = ((Element)terms).getAttribute( "type" );
     
      if( type != null ) {
        if( type.equalsIgnoreCase( "not" ) ) {
          st = new NotTerm( parseChildSearchTerm( terms ) );
        } else if( type.equalsIgnoreCase( "and" ) ) {
          st = new AndTerm( parseChildSearchTerms( terms ) );
        } else if( type.equalsIgnoreCase( "or" ) ) {
          st = new OrTerm( parseChildSearchTerms( terms ) );
        } else if( type.equalsIgnoreCase( "from" ) ) {
          st = parseFromTerm( terms );
        } else if( type.equalsIgnoreCase( "subject" ) ) {
          st = parseSubjectTerm( terms );
        } else if( type.equalsIgnoreCase( "body" ) ) {
          st = parseBodyTerm( terms );
        } else if( type.equalsIgnoreCase( "to" ) || type.equalsIgnoreCase( "recipient" ) ) {
          st = parseRecipientTerm( terms );
        } else if( type.equalsIgnoreCase( "header" ) ) {
          st = parseHeaderTerm( terms );
        } else if( type.equalsIgnoreCase( "flag" ) ) {
          st = parseFlagTerm( terms );
        } else if( type.equalsIgnoreCase( "sent" ) ) {
          st = parseSentDateTerm( terms );
        } else if( type.equalsIgnoreCase( "received" ) ) {
          st = parseReceivedDateTerm( terms );
        } else {
          throw( new XPathException(this, "Invalid Search Term type specified: " + type ) );
        }
      } else {
        throw( new XPathException(this, "Invalid Search Term type specified: null" ) );
      }
    }
   
    if( st == null ) {
      throw( new XPathException(this, "Invalid Search Terms specified" ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm parseChildSearchTerm( Node terms ) throws XPathException
  {
    // Parent only allows a single child search term
   
    SearchTerm  st = null;
   
    NodeList children = terms.getChildNodes();
   
    if( children.getLength() == 1 ) {
      Node child = children.item( 0 );
     
      st = parseSearchTerms( child );
    } else {
      throw( new XPathException(this, "Only one child term is allowed for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm[] parseChildSearchTerms( Node terms ) throws XPathException
  {
    // Parent allows multiple child search terms
   
    ArrayList<SearchTerm> st = new ArrayList<SearchTerm>();
   
    NodeList children = terms.getChildNodes();
   
    if( children.getLength() > 0 ) {
      for( int i = 0; i < children.getLength(); i++ ) {
        Node child = children.item( i );
       
        st.add( parseSearchTerms( child ) );
      }
    } else {
      throw( new XPathException(this, "At least one child term is required for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( (SearchTerm[])st.toArray( new SearchTerm[] {} ) );
  }
 
 
  private SearchTerm parseFromTerm( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    String pattern  = ((Element)terms).getAttribute( "pattern" );
   
    if( pattern != null && pattern.length() > 0 ) {
      st = new FromStringTerm( pattern );
    } else {
      throw( new XPathException(this, "Pattern attribute must be specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm parseSubjectTerm( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    String pattern  = ((Element)terms).getAttribute( "pattern" );
   
    if( pattern != null && pattern.length() > 0 ) {
      st = new SubjectTerm( pattern );
    } else {
      throw( new XPathException(this, "Pattern attribute must be specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm parseBodyTerm( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    String pattern  = ((Element)terms).getAttribute( "pattern" );
   
    if( pattern != null && pattern.length() > 0 ) {
      st = new BodyTerm( pattern );
    } else {
      throw( new XPathException(this, "Pattern attribute must be specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm parseRecipientTerm( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    String pattern  = ((Element)terms).getAttribute( "pattern" );
    String type     = ((Element)terms).getAttribute( "recipientType" );
   
    if( StringUtils.isEmpty(type) ) {
      throw( new XPathException(this, "recipientType not specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    if( pattern != null && pattern.length() > 0 ) {
      Message.RecipientType rtype = null;
     
      if( type.equalsIgnoreCase( "to" ) ) {
        rtype = Message.RecipientType.TO;
      } else if( type.equalsIgnoreCase( "cc" ) ) {
        rtype = Message.RecipientType.CC;
      } else if( type.equalsIgnoreCase( "bcc" ) ) {
        rtype = Message.RecipientType.BCC;
      } else {
        throw( new XPathException(this, "Invalid recipientType: " + type + ", for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
      }
     
      st = new RecipientStringTerm( rtype, pattern );
    } else {
      throw( new XPathException(this, "Pattern attribute must be specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm parseHeaderTerm( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    String pattern  = ((Element)terms).getAttribute( "pattern" );
    String name     = ((Element)terms).getAttribute( "name" );
   
    if( StringUtils.isEmpty(name) ) {
      throw( new XPathException(this, "name not specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    if( pattern != null && pattern.length() > 0 ) {
      st = new HeaderTerm( name, pattern );
    } else {
      throw( new XPathException(this, "pattern attribute must be specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm parseFlagTerm( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    String flag  = ((Element)terms).getAttribute( "flag" );
    String value = ((Element)terms).getAttribute( "value" );
   
    if( StringUtils.isEmpty(value) ) {
      throw( new XPathException(this, "value not specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    if( flag != null && flag.length() > 0 ) {
      Flags flags = null;
     
      if( flag.equalsIgnoreCase( "answered" ) ) {
        flags = new Flags( Flags.Flag.ANSWERED );
      } else if( flag.equalsIgnoreCase( "deleted" ) ) {
        flags = new Flags( Flags.Flag.DELETED );
      } else if( flag.equalsIgnoreCase( "draft" ) ) {
        flags = new Flags( Flags.Flag.DRAFT );
      } else if( flag.equalsIgnoreCase( "recent" ) ) {
        flags = new Flags( Flags.Flag.RECENT );
      } else if( flag.equalsIgnoreCase( "seen" ) ) {
        flags = new Flags( Flags.Flag.SEEN );
      } else {
        throw( new XPathException(this, "Invalid flag: " + flag + ", for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
      }
       
      st = new FlagTerm( flags, value.equalsIgnoreCase( "true" ) );
    } else {
      throw( new XPathException(this, "flag attribute must be specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm parseSentDateTerm( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    String value = ((Element)terms).getAttribute( "date" );
    String format = ((Element)terms).getAttribute( "format" );
   
    if( StringUtils.isEmpty(value) ) {
      throw( new XPathException(this, "value not specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    if( StringUtils.isEmpty(format) ) {
      throw( new XPathException(this, "format not specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    int  cp = parseComparisonAttribute( terms );
   
    try {
      SimpleDateFormat sdf = new SimpleDateFormat( format );
     
      Date date = sdf.parse( value );
     
      st = new SentDateTerm( cp, date );
    }
    catch( ParseException pe ) {
      throw( new XPathException(this, "Cannot parse date value: " + value + ", using format: " + format + ", for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private SearchTerm parseReceivedDateTerm( Node terms ) throws XPathException
  {
    SearchTerm  st = null;
   
    String value = ((Element)terms).getAttribute( "date" );
    String format = ((Element)terms).getAttribute( "format" );
   
    if( StringUtils.isEmpty(value) ) {
      throw( new XPathException(this, "value not specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    if( StringUtils.isEmpty(format) ) {
      throw( new XPathException(this, "format not specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    int  cp = parseComparisonAttribute( terms );
   
    try {
      SimpleDateFormat sdf = new SimpleDateFormat( format );
     
      Date date = sdf.parse( value );
     
      st = new ReceivedDateTerm( cp, date );
    }
    catch( ParseException pe ) {
      throw( new XPathException(this, "Cannot parse date value: " + value + ", using format: " + format + ", for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( st );
  }
 
 
  private int parseComparisonAttribute( Node terms ) throws XPathException
  {
    int  cp = ComparisonTerm.EQ;
   
    String comp  = ((Element)terms).getAttribute( "comparison" );
   
    if( comp != null && comp.length() > 0 ) {
      if( comp.equalsIgnoreCase( "eq" ) ) {
        cp = ComparisonTerm.EQ;
      } else if( comp.equalsIgnoreCase( "ge" ) ) {
        cp = ComparisonTerm.GE;
      } else if( comp.equalsIgnoreCase( "gt" ) ) {
        cp = ComparisonTerm.GT;
      } else if( comp.equalsIgnoreCase( "le" ) ) {
        cp = ComparisonTerm.LE;
      } else if( comp.equalsIgnoreCase( "lt" ) ) {
        cp = ComparisonTerm.LT;
      } else if( comp.equalsIgnoreCase( "ne" ) ) {
        cp = ComparisonTerm.NE;
      } else {
        throw( new XPathException(this, "Invalid comparison: " + comp + ", for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
      }
    } else {
      throw( new XPathException(this, "comparison attribute must be specified for term with type: " + ((Element)terms).getAttribute( "type" ) ) );
    }
   
    return( cp );
  }
 
}
TOP

Related Classes of org.exist.xquery.modules.mail.MessageListFunctions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.