1 package info.magnolia.cms.mail.templates.impl; 2 3 import freemarker.template.Template; 4 import info.magnolia.cms.core.Path; 5 import info.magnolia.cms.mail.templates.MailAttachment; 6 import info.magnolia.cms.security.User; 7 import info.magnolia.context.MgnlContext; 8 9 import java.io.BufferedInputStream ; 10 import java.io.File ; 11 import java.io.FileOutputStream ; 12 import java.io.IOException ; 13 import java.io.InputStream ; 14 import java.io.StringReader ; 15 import java.io.StringWriter ; 16 import java.net.URL ; 17 import java.util.ArrayList ; 18 import java.util.Iterator ; 19 import java.util.Map ; 20 21 import javax.mail.Session ; 22 23 import org.apache.commons.httpclient.HttpClient; 24 import org.apache.commons.httpclient.NameValuePair; 25 import org.apache.commons.httpclient.cookie.CookiePolicy; 26 import org.apache.commons.httpclient.methods.GetMethod; 27 import org.apache.commons.httpclient.methods.PostMethod; 28 import org.jdom.Attribute; 29 import org.jdom.Document; 30 import org.jdom.Element; 31 import org.jdom.filter.Filter; 32 import org.jdom.input.SAXBuilder; 33 import org.jdom.output.XMLOutputter; 34 35 36 40 public class MagnoliaEmail extends FreemarkerEmail { 41 42 public static final String SUFFIX = "?mgnlIntercept=PREVIEW&mgnlPreview=true&mail=draw"; 43 44 private HttpClient client; 45 46 private int cid = 0; 47 48 private static final String UTF_8 = "UTF-8"; 49 50 private static final String MAGNOLIA = "magnolia"; 51 52 private static final String IMG = "img"; 53 54 private static final String SRC = "src"; 55 56 private static final String CID = "cid:"; 57 58 private static final String LINK = "link"; 59 60 private static final String HREF = "href"; 61 62 private static final String STYLE = "style"; 63 64 private static final String REL = "rel"; 65 66 private static final String ACTION = "action"; 67 68 private static final String LOGIN = "login"; 69 70 private static final String URL = "url"; 71 72 private static final String MGNL_USER_ID = "mgnlUserId"; 73 74 private static final String MGNL_USER_PSWD = "mgnlUserPSWD"; 75 76 private static final String SLASH = "/"; 77 78 public MagnoliaEmail(Session _session) throws Exception { 79 super(_session); 80 } 81 82 public void setBodyFromResourceFile(String resourceFile, Map _map) throws Exception { 83 URL url = new URL (resourceFile); 84 String _content = retrieveContentFromMagnolia(resourceFile); 86 StringReader reader = new StringReader (_content); 87 88 String urlBasePath = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort(); 90 reader = FilterImages(urlBasePath, reader); 91 92 Template template = new Template(MAGNOLIA, reader, FreemarkerEmail.cfg, UTF_8); 94 95 super.setBodyFromTemplate(template, _map); 97 } 98 99 108 private StringReader FilterImages(String urlBasePath, StringReader reader) throws Exception { 109 log.info("Filtering images"); 110 SAXBuilder parser = new SAXBuilder(); 111 Document doc = parser.build(reader); 112 ArrayList toremove = new ArrayList (); 113 ArrayList toadd = new ArrayList (); 114 115 Iterator iter = doc.getDescendants(new ContentFilter()); 117 while (iter.hasNext()) { 118 Element elem = (Element) iter.next(); 119 String name = elem.getName(); 120 if (name.equalsIgnoreCase(IMG)) { 121 Attribute att = elem.getAttribute(SRC); 123 if (log.isDebugEnabled()) { 124 log.debug("Found new img:" + att.toString()); 125 } 126 String value = att.getValue(); 127 this.cid++; 128 att.setValue(CID + (this.cid)); 129 String url = urlBasePath + value; 130 if (log.isDebugEnabled()) { 131 log.debug("Url is:" + url); 132 } 133 this.addAttachment(new MailAttachment(getAttachmentFile(url).toURL(), String.valueOf(this.cid))); 134 } 135 else if (name.equalsIgnoreCase(LINK)) { 136 Attribute att = elem.getAttribute(HREF); 138 Element el = (Element) elem.clone(); 139 if (log.isDebugEnabled()) { 140 log.debug("Found new css:" + att.toString()); 141 } 142 String url = urlBasePath + att.getValue(); 143 el.setName(STYLE); 144 el.removeAttribute(HREF); 145 el.removeAttribute(REL); 146 GetMethod streamCss = new GetMethod(url); 147 getHttpClient(url).executeMethod(streamCss); 148 el.setText(streamCss.getResponseBodyAsString()); 149 150 toremove.add(elem); 151 toadd.add(el); 152 } 153 } 154 155 for (int i = 0; i < toremove.size(); i++) { 158 Element elem = (Element) toremove.get(i); 159 Element parent = elem.getParentElement(); 160 doc.removeContent(elem); 161 parent.addContent((Element) toadd.get(i)); 162 } 163 164 StringWriter writer = new StringWriter (); 166 new XMLOutputter().output(doc, writer); 167 return new StringReader (writer.toString()); 168 } 169 170 176 private File getAttachmentFile(String url) throws Exception { 177 log.info("Streaming content of url:" + url + " to a temporary file"); 178 179 GetMethod redirect = new GetMethod(url); 181 getHttpClient(url).executeMethod(redirect); 182 183 URL _url = new URL (url); 184 String file = _url.getFile(); 185 186 File tempFile = new File (Path.getTempDirectoryPath() 188 + File.separator 189 + file.substring(file.lastIndexOf(SLASH) + 1)); 190 if (tempFile.exists() && redirect.getResponseContentLength() == tempFile.length()) { 192 redirect.releaseConnection(); 193 return tempFile; 194 } 195 196 FileOutputStream out = new FileOutputStream (tempFile); 198 final int BUFFER_SIZE = 1 << 10 << 3; byte[] buffer = new byte[BUFFER_SIZE]; 200 int bytesRead; 201 InputStream in = new BufferedInputStream (redirect.getResponseBodyAsStream()); 202 while (true) { 203 bytesRead = in.read(buffer); 204 if (bytesRead > -1) { 205 out.write(buffer, 0, bytesRead); 206 } 207 else { 208 break; 209 } 210 } 211 212 in.close(); 214 out.close(); 215 redirect.releaseConnection(); 216 217 return tempFile; 218 } 219 220 227 private HttpClient getHttpClient(String baseURL) throws Exception { 228 if (this.client == null) { 229 URL location = new URL (baseURL); 230 User user = MgnlContext.getInstance().getUser(); 231 this.client = getHttpClientForUser(location, user); 232 } 233 return this.client; 234 } 235 236 244 private HttpClient getHttpClientForUser(URL location, User _user) throws IOException { 245 HttpClient _client = new HttpClient(); 246 _client.getHostConfiguration().setHost(location.getHost(), location.getPort(), location.getProtocol()); 247 _client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); 248 String user = _user.getName(); 249 String pass = _user.getPassword(); 250 log.info("Creating http client for user:" + user); 251 PostMethod authpost = new PostMethod(location.getPath()); 253 NameValuePair action = new NameValuePair(ACTION, LOGIN); 254 NameValuePair url = new NameValuePair(URL, location.getPath()); 255 NameValuePair userid = new NameValuePair(MGNL_USER_ID, user); 256 NameValuePair password = new NameValuePair(MGNL_USER_PSWD, pass); 257 authpost.setRequestBody(new NameValuePair[]{action, url, userid, password}); 258 _client.executeMethod(authpost); 259 authpost.releaseConnection(); 260 return _client; 261 } 262 263 270 private String retrieveContentFromMagnolia(String _url) throws Exception { 271 log.info("Retrieving content from magnolia:" + _url); 272 GetMethod redirect = new GetMethod(_url + SUFFIX); 273 getHttpClient(_url).executeMethod(redirect); 274 String response = redirect.getResponseBodyAsString(); 275 redirect.releaseConnection(); 276 return response; 277 } 278 279 282 static class ContentFilter implements Filter { 283 284 287 private static final long serialVersionUID = 1L; 288 289 public boolean matches(Object object) { 290 if (object instanceof Element) { 291 Element e = (Element) object; 292 return e.getName().equalsIgnoreCase(LINK) || e.getName().equalsIgnoreCase(IMG); 293 } 294 295 return false; 296 297 } 298 } 299 } 300 | Popular Tags |