view src/nabble/model/Message.java @ 46:7ac7f55e16cf

subscription message
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 14 Jun 2021 15:35:05 -0600
parents ea757b766baa
children 72765b66e2c3
line wrap: on
line source

package nabble.model;

import fschmidt.html.Html;
import nabble.naml.compiler.CompileException;
import nabble.naml.compiler.Template;
import nabble.naml.compiler.TemplatePrintWriter;
import nabble.naml.compiler.Program;
import nabble.naml.namespaces.BasicNamespace;
import nabble.view.web.template.MessageNamespace;
import nabble.modules.ModuleManager;

import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;


public class Message {

	public static abstract class SourceType extends AbstractType<SourceType> {
		private static final Map<Character,SourceType> map = new HashMap<Character,SourceType>();

		public static final SourceType TEMP = new SourceType('t',"temp") {
			public Source getSource(Site site,long id) {
				User user = site.getUser(id);
				return new TempSource(user);
			}
			public String getIdField() {
				return "user_id";
			}
		};
		public static final SourceType NODE = new SourceType('n',"node") {
			public Source getSource(Site site,long id) {
				return site.getNode(id);
			}
			public String getIdField() {
				return "node_id";
			}
		};
		public static final SourceType AVATAR = new SourceType('a',"avatar") {
			public Source getSource(Site site,long id) {
				User user = site.getUser(id);
				return user == null? null : new AvatarSource(user);
			}
			public String getIdField() {
				return "user_id";
			}
		};
		public static final SourceType SITE = new SourceType('s',"site") {
			public Source getSource(Site site,long id) {
				return site;
			}
			public String getIdField() {
				return null;
			}
		};

		private SourceType(char code,String name) {
			super(map,code,name);
		}

		public abstract Source getSource(Site site,long id);
		public abstract String getIdField();

		public static SourceType getType(char code) {
			return AbstractType.getType(map,code);
		}
	}

	public interface Source {
		public Site getSite();
		public long getSourceId();
		public SourceType getMessageSourceType();
	}

	public static class TempSource implements Source {
		private final User user;

		public TempSource(User user) {
			this.user = user;
		}

		public Site getSite() {
			return user.getSite();
		}

		public long getSourceId() {
			return user.getId();
		}

		public SourceType getMessageSourceType() {
			return SourceType.TEMP;
		}
	}

	public static class AvatarSource implements Source {
		private final User user;

		public AvatarSource(User user) {
			this.user = user;
		}

		public Site getSite() {
			return user.getSite();
		}

		public long getSourceId() {
			return user.getId();
		}

		public SourceType getMessageSourceType() {
			return SourceType.AVATAR;
		}

		public User getUser() {
			return user;
		}
	}


	public static abstract class Format extends AbstractType<Format> {
	
		private static final Map<Character,Format> map = new HashMap<Character,Format>();
	
		public static Format getMessageFormat(char code) {
			return AbstractType.getType(map,code);
		}

		Format(char code,String name) {
			super(map,code,name);
		}
	
		protected abstract String getText(String msg, Source source);
	
		protected abstract String getTextWithoutQuotes(String msg, Source source);
		
		protected abstract String getEmail(String msg,int i);

		protected abstract Html parse(String msg,Message.Source source);

		protected abstract Html parseForMailText(String msg,Message.Source source);

		public String toString() {
			return getName();
		}
	
		public static final Format TEXT = MessageFormatImpls.TEXT;
		public static final Format HTML = MessageFormatImpls.HTML;
		public static final Format MAILING_LIST = MailingLists.msgFmt;
		private static final Format SUBSCRIPTION = new MailMessageFormat('s', "subscription");

		public boolean isMail() {
			return this==MAILING_LIST || this==SUBSCRIPTION;
		}
	}


	// Message

	protected String raw;
	protected final Format format;

	public Message(String raw,Format format) {
		this.raw = raw;
		this.format = format;
	}

	public String getRaw() {
		return raw;
	}

	public final Format getFormat() {
		return format;
	}

	public Source getSource() {
		return null;
	}

	public boolean equals(Object obj) {
		if( !(obj instanceof Message) )
			return false;
		Message msg = (Message)obj;
		return msg.format.equals(format) && msg.getRaw().equals(getRaw());
	}
	
	public final String getText() {
		return getFormat().getText(getRaw(),getSource());
	}

	public final String getTextWithoutQuotes() {
		return getFormat().getTextWithoutQuotes(getRaw(),getSource());
	}

	public final String getEmail(int i) {
		return getFormat().getEmail(getRaw(),i);
	}

	public final Html parse() {
		return getFormat().parse(getRaw(),getSource());
	}

	public final Html parseForMailText() {
		return getFormat().parseForMailText(getRaw(),getSource());
	}


	public static String wrapQuoteText(String text) {
		StringBuilder buf = new StringBuilder(text);
		wrapQuoteText(buf);
		return buf.toString();
	}

	public static void wrapQuoteText(StringBuilder buf) {
		String quot = "";
		for (int i=0,n=0,space=-1; i<buf.length(); i++,n++) {
			char c = buf.charAt(i);
			if (c=='\n' || c=='\r') {
				n = 0;
				space = -1;
				quot = getQuot(buf,i+1);
			} else if (Character.isWhitespace(c) && n>quot.length()) {
				space = i;
			} else if (n>76 && space>=0) {
				buf.setCharAt(space,'\n');
				buf.insert(space+1,quot);
				i+=quot.length();
				n = i-space;
				space = -1;
			}
		}
	}

	private static String getQuot(StringBuilder buf, int start) {
		int end = buf.indexOf(" ",start);
		if (end<=start) return "";
		for (int i=start;i<end;i++) {
			if (buf.charAt(i)!='>') return "";
		}
		return buf.substring(start, end+1);
	}

	public boolean isDeleted() {
		return false;
	}

	public boolean isDeactivated() {
		return false;
	}

	// for testing
	public static String toHtml(String raw,Format format)
		throws CompileException
	{
		Message msg = new Message(raw,format);
		Program program = Program.getInstance(ModuleManager.getGenericModules());
		Template template = program.getTemplate( "message_as_html",
			BasicNamespace.class, MessageNamespace.class
		);
		StringWriter sw = new StringWriter();
		template.run( new TemplatePrintWriter(sw), Collections.<String,Object>emptyMap(),
			new BasicNamespace(template), new MessageNamespace(msg)
		);
		return sw.toString();
	}


	public static final Map<String,String> htmlSeparators = new HashMap<String,String>();
	static {
		htmlSeparators.put("a", " ");
		htmlSeparators.put("/a", " ");
		htmlSeparators.put("blockquote", "\n");
		htmlSeparators.put("/blockquote", "\n");
		htmlSeparators.put("br", "\n");
		htmlSeparators.put("center", "\n");
		htmlSeparators.put("/center", "\n");
		htmlSeparators.put("div", "\n");
		htmlSeparators.put("/div", "\n");
		htmlSeparators.put("hr", "\n");
		htmlSeparators.put("img", " ");
		htmlSeparators.put("ul", "\n");
		htmlSeparators.put("/ul", "\n");
		htmlSeparators.put("li", "\n");
		htmlSeparators.put("nabble_a", " ");
		htmlSeparators.put("/nabble_a", " ");
		htmlSeparators.put("nabble_img", " ");
		htmlSeparators.put("ol", "\n");
		htmlSeparators.put("/ol", "\n");
		htmlSeparators.put("p", "\n");
		htmlSeparators.put("/p", "\n");
		htmlSeparators.put("pre", "\n");
		htmlSeparators.put("/pre", "\n");
		htmlSeparators.put("table", "\n");
		htmlSeparators.put("/table", "\n");
		htmlSeparators.put("tr", "\n");
		htmlSeparators.put("th", "\t");
		htmlSeparators.put("td", "\t");
		htmlSeparators.put("h1", "\n");
		htmlSeparators.put("/h1", "\n");
		htmlSeparators.put("h2", "\n");
		htmlSeparators.put("/h2", "\n");
		htmlSeparators.put("h3", "\n");
		htmlSeparators.put("/h3", "\n");
		htmlSeparators.put("h4", "\n");
		htmlSeparators.put("/h4", "\n");
		htmlSeparators.put("h5", "\n");
		htmlSeparators.put("/h5", "\n");
		htmlSeparators.put("h6", "\n");
		htmlSeparators.put("/h6", "\n");
	}

}