0
|
1 package nabble.model;
|
|
2
|
|
3 import fschmidt.html.Html;
|
|
4 import nabble.naml.compiler.CompileException;
|
|
5 import nabble.naml.compiler.Template;
|
|
6 import nabble.naml.compiler.TemplatePrintWriter;
|
|
7 import nabble.naml.compiler.Program;
|
|
8 import nabble.naml.namespaces.BasicNamespace;
|
|
9 import nabble.view.web.template.MessageNamespace;
|
|
10 import nabble.modules.ModuleManager;
|
|
11
|
|
12 import java.io.StringWriter;
|
|
13 import java.util.Collections;
|
|
14 import java.util.HashMap;
|
|
15 import java.util.Map;
|
|
16
|
|
17
|
|
18 public class Message {
|
|
19
|
|
20 public static abstract class SourceType extends AbstractType<SourceType> {
|
|
21 private static final Map<Character,SourceType> map = new HashMap<Character,SourceType>();
|
|
22
|
|
23 public static final SourceType TEMP = new SourceType('t',"temp") {
|
|
24 public Source getSource(Site site,long id) {
|
|
25 User user = site.getUser(id);
|
|
26 return new TempSource(user);
|
|
27 }
|
|
28 public String getIdField() {
|
|
29 return "user_id";
|
|
30 }
|
|
31 };
|
|
32 public static final SourceType NODE = new SourceType('n',"node") {
|
|
33 public Source getSource(Site site,long id) {
|
|
34 return site.getNode(id);
|
|
35 }
|
|
36 public String getIdField() {
|
|
37 return "node_id";
|
|
38 }
|
|
39 };
|
|
40 public static final SourceType AVATAR = new SourceType('a',"avatar") {
|
|
41 public Source getSource(Site site,long id) {
|
|
42 User user = site.getUser(id);
|
|
43 return user == null? null : new AvatarSource(user);
|
|
44 }
|
|
45 public String getIdField() {
|
|
46 return "user_id";
|
|
47 }
|
|
48 };
|
|
49 public static final SourceType SITE = new SourceType('s',"site") {
|
|
50 public Source getSource(Site site,long id) {
|
|
51 return site;
|
|
52 }
|
|
53 public String getIdField() {
|
|
54 return null;
|
|
55 }
|
|
56 };
|
|
57
|
|
58 private SourceType(char code,String name) {
|
|
59 super(map,code,name);
|
|
60 }
|
|
61
|
|
62 public abstract Source getSource(Site site,long id);
|
|
63 public abstract String getIdField();
|
|
64
|
|
65 public static SourceType getType(char code) {
|
|
66 return AbstractType.getType(map,code);
|
|
67 }
|
|
68 }
|
|
69
|
|
70 public interface Source {
|
|
71 public Site getSite();
|
|
72 public long getSourceId();
|
|
73 public SourceType getMessageSourceType();
|
|
74 }
|
|
75
|
|
76 public static class TempSource implements Source {
|
|
77 private final User user;
|
|
78
|
|
79 public TempSource(User user) {
|
|
80 this.user = user;
|
|
81 }
|
|
82
|
|
83 public Site getSite() {
|
|
84 return user.getSite();
|
|
85 }
|
|
86
|
|
87 public long getSourceId() {
|
|
88 return user.getId();
|
|
89 }
|
|
90
|
|
91 public SourceType getMessageSourceType() {
|
|
92 return SourceType.TEMP;
|
|
93 }
|
|
94 }
|
|
95
|
|
96 public static class AvatarSource implements Source {
|
|
97 private final User user;
|
|
98
|
|
99 public AvatarSource(User user) {
|
|
100 this.user = user;
|
|
101 }
|
|
102
|
|
103 public Site getSite() {
|
|
104 return user.getSite();
|
|
105 }
|
|
106
|
|
107 public long getSourceId() {
|
|
108 return user.getId();
|
|
109 }
|
|
110
|
|
111 public SourceType getMessageSourceType() {
|
|
112 return SourceType.AVATAR;
|
|
113 }
|
|
114
|
|
115 public User getUser() {
|
|
116 return user;
|
|
117 }
|
|
118 }
|
|
119
|
|
120
|
|
121 public static abstract class Format extends AbstractType<Format> {
|
|
122
|
|
123 private static final Map<Character,Format> map = new HashMap<Character,Format>();
|
|
124
|
|
125 public static Format getMessageFormat(char code) {
|
|
126 return AbstractType.getType(map,code);
|
|
127 }
|
|
128
|
|
129 Format(char code,String name) {
|
|
130 super(map,code,name);
|
|
131 }
|
|
132
|
|
133 protected abstract String getText(String msg, Source source);
|
|
134
|
|
135 protected abstract String getTextWithoutQuotes(String msg, Source source);
|
|
136
|
|
137 protected abstract String getEmail(String msg,int i);
|
|
138
|
|
139 protected abstract Html parse(String msg,Message.Source source);
|
|
140
|
|
141 protected abstract Html parseForMailText(String msg,Message.Source source);
|
|
142
|
|
143 public String toString() {
|
|
144 return getName();
|
|
145 }
|
|
146
|
|
147 public static final Format TEXT = MessageFormatImpls.TEXT;
|
|
148 public static final Format HTML = MessageFormatImpls.HTML;
|
|
149 public static final Format MAILING_LIST = MailingLists.msgFmt;
|
|
150 private static final Format SUBSCRIPTION = PostByEmail.msgFmt;
|
|
151
|
|
152 public boolean isMail() {
|
|
153 return this==MAILING_LIST || this==SUBSCRIPTION;
|
|
154 }
|
|
155 }
|
|
156
|
|
157
|
|
158 // Message
|
|
159
|
|
160 protected String raw;
|
|
161 protected final Format format;
|
|
162
|
|
163 public Message(String raw,Format format) {
|
|
164 this.raw = raw;
|
|
165 this.format = format;
|
|
166 }
|
|
167
|
|
168 public String getRaw() {
|
|
169 return raw;
|
|
170 }
|
|
171
|
|
172 public final Format getFormat() {
|
|
173 return format;
|
|
174 }
|
|
175
|
|
176 public Source getSource() {
|
|
177 return null;
|
|
178 }
|
|
179
|
|
180 public boolean equals(Object obj) {
|
|
181 if( !(obj instanceof Message) )
|
|
182 return false;
|
|
183 Message msg = (Message)obj;
|
|
184 return msg.format.equals(format) && msg.getRaw().equals(getRaw());
|
|
185 }
|
|
186
|
|
187 public final String getText() {
|
|
188 return getFormat().getText(getRaw(),getSource());
|
|
189 }
|
|
190
|
|
191 public final String getTextWithoutQuotes() {
|
|
192 return getFormat().getTextWithoutQuotes(getRaw(),getSource());
|
|
193 }
|
|
194
|
|
195 public final String getEmail(int i) {
|
|
196 return getFormat().getEmail(getRaw(),i);
|
|
197 }
|
|
198
|
|
199 public final Html parse() {
|
|
200 return getFormat().parse(getRaw(),getSource());
|
|
201 }
|
|
202
|
|
203 public final Html parseForMailText() {
|
|
204 return getFormat().parseForMailText(getRaw(),getSource());
|
|
205 }
|
|
206
|
|
207
|
|
208 public static String wrapQuoteText(String text) {
|
|
209 StringBuilder buf = new StringBuilder(text);
|
|
210 wrapQuoteText(buf);
|
|
211 return buf.toString();
|
|
212 }
|
|
213
|
|
214 public static void wrapQuoteText(StringBuilder buf) {
|
|
215 String quot = "";
|
|
216 for (int i=0,n=0,space=-1; i<buf.length(); i++,n++) {
|
|
217 char c = buf.charAt(i);
|
|
218 if (c=='\n' || c=='\r') {
|
|
219 n = 0;
|
|
220 space = -1;
|
|
221 quot = getQuot(buf,i+1);
|
|
222 } else if (Character.isWhitespace(c) && n>quot.length()) {
|
|
223 space = i;
|
|
224 } else if (n>76 && space>=0) {
|
|
225 buf.setCharAt(space,'\n');
|
|
226 buf.insert(space+1,quot);
|
|
227 i+=quot.length();
|
|
228 n = i-space;
|
|
229 space = -1;
|
|
230 }
|
|
231 }
|
|
232 }
|
|
233
|
|
234 private static String getQuot(StringBuilder buf, int start) {
|
|
235 int end = buf.indexOf(" ",start);
|
|
236 if (end<=start) return "";
|
|
237 for (int i=start;i<end;i++) {
|
|
238 if (buf.charAt(i)!='>') return "";
|
|
239 }
|
|
240 return buf.substring(start, end+1);
|
|
241 }
|
|
242
|
|
243 public boolean isDeleted() {
|
|
244 return false;
|
|
245 }
|
|
246
|
|
247 public boolean isDeactivated() {
|
|
248 return false;
|
|
249 }
|
|
250
|
|
251 // for testing
|
|
252 public static String toHtml(String raw,Format format)
|
|
253 throws CompileException
|
|
254 {
|
|
255 Message msg = new Message(raw,format);
|
|
256 Program program = Program.getInstance(ModuleManager.getGenericModules());
|
|
257 Template template = program.getTemplate( "message_as_html",
|
|
258 BasicNamespace.class, MessageNamespace.class
|
|
259 );
|
|
260 StringWriter sw = new StringWriter();
|
|
261 template.run( new TemplatePrintWriter(sw), Collections.<String,Object>emptyMap(),
|
|
262 new BasicNamespace(template), new MessageNamespace(msg)
|
|
263 );
|
|
264 return sw.toString();
|
|
265 }
|
|
266
|
|
267
|
|
268 public static final Map<String,String> htmlSeparators = new HashMap<String,String>();
|
|
269 static {
|
|
270 htmlSeparators.put("a", " ");
|
|
271 htmlSeparators.put("/a", " ");
|
|
272 htmlSeparators.put("blockquote", "\n");
|
|
273 htmlSeparators.put("/blockquote", "\n");
|
|
274 htmlSeparators.put("br", "\n");
|
|
275 htmlSeparators.put("center", "\n");
|
|
276 htmlSeparators.put("/center", "\n");
|
|
277 htmlSeparators.put("div", "\n");
|
|
278 htmlSeparators.put("/div", "\n");
|
|
279 htmlSeparators.put("hr", "\n");
|
|
280 htmlSeparators.put("img", " ");
|
|
281 htmlSeparators.put("ul", "\n");
|
|
282 htmlSeparators.put("/ul", "\n");
|
|
283 htmlSeparators.put("li", "\n");
|
|
284 htmlSeparators.put("nabble_a", " ");
|
|
285 htmlSeparators.put("/nabble_a", " ");
|
|
286 htmlSeparators.put("nabble_img", " ");
|
|
287 htmlSeparators.put("ol", "\n");
|
|
288 htmlSeparators.put("/ol", "\n");
|
|
289 htmlSeparators.put("p", "\n");
|
|
290 htmlSeparators.put("/p", "\n");
|
|
291 htmlSeparators.put("pre", "\n");
|
|
292 htmlSeparators.put("/pre", "\n");
|
|
293 htmlSeparators.put("table", "\n");
|
|
294 htmlSeparators.put("/table", "\n");
|
|
295 htmlSeparators.put("tr", "\n");
|
|
296 htmlSeparators.put("th", "\t");
|
|
297 htmlSeparators.put("td", "\t");
|
|
298 htmlSeparators.put("h1", "\n");
|
|
299 htmlSeparators.put("/h1", "\n");
|
|
300 htmlSeparators.put("h2", "\n");
|
|
301 htmlSeparators.put("/h2", "\n");
|
|
302 htmlSeparators.put("h3", "\n");
|
|
303 htmlSeparators.put("/h3", "\n");
|
|
304 htmlSeparators.put("h4", "\n");
|
|
305 htmlSeparators.put("/h4", "\n");
|
|
306 htmlSeparators.put("h5", "\n");
|
|
307 htmlSeparators.put("/h5", "\n");
|
|
308 htmlSeparators.put("h6", "\n");
|
|
309 htmlSeparators.put("/h6", "\n");
|
|
310 }
|
|
311
|
|
312 }
|