/* DefaultEmailInStorm.java * * Copyright (c) 2002, Marc Schiereck * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * 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 README * file for more details. * */ /* * Written by Marc Schiereck */ package gzz.modules.email; import gzz.media.Enfilade1D; import gzz.mediaserver.*; import gzz.media.impl.*; import java.util.*; /** A representation of an email stored in Storm, as Xanalogical text. * Has methods for getting some headers (From, To, Date, and Subject) * and the body as Enfilade1D objects. */ public class DefaultEmailInStorm implements EmailInStorm { protected Enfilade1D from; protected Enfilade1D to; protected Enfilade1D subject; protected Enfilade1D date; protected Enfilade1D body; public DefaultEmailInStorm(Mediaserver ms, Mediaserver.Id msid) { Enfilade1D.Maker maker = new Enfilade1DImpl.Enfilade1DImplMaker(); PermanentTextScroll pts; pts = new PermanentTextScroll(ms, getBodyId(ms, msid)); from = getEnfilade1DForField("From", ms, msid); to = getEnfilade1DForField("To", ms, msid); subject = getEnfilade1DForField("Subject", ms, msid); date = getEnfilade1DForField("Date", ms, msid); body = maker.makeEnfilade(pts.getCurrent()); } /** Get an Enfilade1D object containing the From header of the email. */ public Enfilade1D getFrom() { return from; } /**Get an Enflilade1D object containing the To header of the email */ public Enfilade1D getTo() { return to; } /**Get an Enfilade1D object containing the Subject header of the email. */ public Enfilade1D getSubject() { return subject; } /**Get an Enfilade1D object containing the Date header of the email. */ public Enfilade1D getDate() { return date; } /**Get an Enfilade1D object containing the body of the email. */ public Enfilade1D getBody() { return body; } protected int nextLine(String str, int curPos) { if (curPos >= (str.length() - 2)) return 0; for(; str.charAt(curPos) != '\r' && str.charAt(curPos + 1) != '\n' && curPos != str.length() - 2; curPos++); return curPos + 2; } protected int nextHeader(String str, int curPos) { if (curPos >= (str.length() - 2)) return 0; while(str.charAt(curPos) != '\r' && str.charAt(curPos + 1) != '\n') { curPos = nextLine(str, curPos); } return curPos + 2; } protected Mediaserver.Id getBodyId(Mediaserver ms, Mediaserver.Id msid) { MediaserverBlock msb; String header = null; String lcHeader = null; int position = 0; int oldPosition = 0; try{ msb = ms.getDatum(msid); if (!msb.getContentType().equals("message/rfc822")) throw new Error(); header = new String(msb.getBytes()); header = header.toLowerCase(); } catch (java.io.IOException ioe) { throw new Error(); } position = nextHeader(header, 0); while(!getFieldBodyString("content-type", header, position).trim().startsWith("text/") && position != 0) { oldPosition = position; position = nextHeader(header, position); } String id = getFieldBodyString("content-id", header, oldPosition).replaceFirst("storm:block:", "").trim(); return (new Mediaserver.Id(id)); } protected String getFieldBodyString(String field, String header, int startPos) { List positions = getFieldBody(field, header, startPos); String fieldBody = ""; Iterator i = positions.iterator(); int[] cur; while(i.hasNext()) { cur = (int [])i.next(); fieldBody += header.substring(cur[0], cur[1]); } return fieldBody; } protected List getFieldBody(String field, String header, int startPos) { List positions = new ArrayList(); boolean unfold = false; //field = field.toLowerCase() + ":"; field += ":"; int fieldLength = field.length(); //header = header.toLowerCase(); int position = startPos; do { if ((position + fieldLength) < header.length()) { if (header.substring(position, position + fieldLength).equals(field)) { int begin = position + fieldLength; int end = nextLine(header, position + fieldLength) - 2; positions.add(new int[] {begin, end}); unfold = true; } else if (header.charAt(position) == ' ' && unfold) { int begin = position; for(;begin < header.length() - 1 && header.charAt(begin) == ' '; begin++); int end = nextLine(header, position) - 2; positions.add(new int[] {begin - 1, end}); } else if (unfold) { unfold = false; return positions; } } position = nextLine(header, position); } while(position != 0); return positions; } protected Enfilade1D getEnfilade1DForField(String field, Mediaserver ms, Mediaserver.Id msid) { Enfilade1D ret = null; MediaserverBlock msb; PermanentTextScroll pts = new PermanentTextScroll(ms, msid); Enfilade1D.Maker maker = new Enfilade1DImpl.Enfilade1DImplMaker(); java.util.List spans = new ArrayList(); String header = null; field = field.toLowerCase(); try{ msb = ms.getDatum(msid); if (!msb.getContentType().equals("message/rfc822")) throw new Error(); header = (new String(msb.getBytes())).toLowerCase(); } catch (java.io.IOException ioe) { throw new Error(); } int position = 0; if(!getFieldBodyString("content-type", header, 0).trim().startsWith("multipart/")) { position = nextHeader(header, 0); } List positions = getFieldBody(field, header, position); Iterator i = positions.iterator(); int[] cur; while(i.hasNext()) { cur = (int [])i.next(); gzz.media.Span tempSpan = pts.getSpan(cur[0], cur[1] - cur[0]); spans.add(tempSpan); } ret = maker.makeEnfilade(spans); return ret; } }