1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.MonoRail
.Framework
18 using System
.Collections
;
20 using System
.Text
.RegularExpressions
;
23 using Castle
.Components
.Common
.EmailSender
;
25 using Castle
.Core
.Logging
;
28 /// Default implementation of <see cref="IEmailTemplateService"/>
31 /// Will work only during a MonoRail process as it needs a <see cref="IRailsEngineContext"/>
32 /// and a <see cref="Controller"/> instance to execute.
34 public class EmailTemplateService
: IServiceEnabledComponent
, IEmailTemplateService
37 /// The logger instance
39 private ILogger logger
= NullLogger
.Instance
;
42 /// Initializes a new instance of the <see cref="EmailTemplateService"/> class.
44 public EmailTemplateService()
48 #region IServiceEnabledComponent implementation
51 /// Invoked by the framework in order to give a chance to
52 /// obtain other services
54 /// <param name="provider">The service proviver</param>
55 public void Service(IServiceProvider provider
)
57 ILoggerFactory loggerFactory
= (ILoggerFactory
) provider
.GetService(typeof(ILoggerFactory
));
59 if (loggerFactory
!= null)
61 logger
= loggerFactory
.Create(typeof(EmailTemplateService
));
68 /// Creates an instance of <see cref="Message"/>
69 /// using the specified template for the body
71 /// <param name="templateName">
72 /// Name of the template to load.
73 /// Will look in <c>Views/mail</c> for that template file.
75 /// <param name="parameters">
76 /// Dictionary with parameters
77 /// that you can use on the email template
79 /// <param name="doNotApplyLayout">If <c>true</c>, it will skip the layout</param>
80 /// <returns>An instance of <see cref="Message"/></returns>
81 public Message
RenderMailMessage(String templateName
, IDictionary parameters
, bool doNotApplyLayout
)
83 if (HttpContext
.Current
== null)
85 throw new RailsException("No http context available");
88 if (logger
.IsDebugEnabled
)
90 logger
.DebugFormat("Rendering email message. Template name {0}", templateName
);
93 IRailsEngineContext context
= EngineContextModule
.ObtainRailsEngineContext(HttpContext
.Current
);
95 IController controller
= context
.CurrentController
;
97 if (controller
== null)
99 throw new RailsException("No controller found on the executing activity");
102 if (parameters
!= null && parameters
.Count
!= 0)
104 foreach(DictionaryEntry entry
in parameters
)
106 controller
.PropertyBag
.Add(entry
.Key
, entry
.Value
);
112 return RenderMailMessage(templateName
, context
, controller
, doNotApplyLayout
);
116 if (parameters
!= null && parameters
.Count
!= 0)
118 foreach(DictionaryEntry entry
in parameters
)
120 controller
.PropertyBag
.Remove(entry
.Key
);
127 /// Creates an instance of <see cref="Message"/>
128 /// using the specified template for the body
130 /// <param name="templateName">
131 /// Name of the template to load.
132 /// Will look in Views/mail for that template file.
134 /// <param name="context">Context that represents the current request</param>
135 /// <param name="controller">Controller instance</param>
136 /// <param name="doNotApplyLayout">If <c>true</c>, it will skip the layout</param>
137 /// <returns>An instance of <see cref="Message"/></returns>
138 public Message
RenderMailMessage(String templateName
, IRailsEngineContext context
,
139 IController controller
, bool doNotApplyLayout
)
141 // create a message object
142 Message message
= new Message();
144 // use the template engine to generate the body of the message
145 StringWriter writer
= new StringWriter();
147 String oldLayout
= controller
.LayoutName
;
149 if (doNotApplyLayout
)
151 controller
.LayoutName
= null;
154 if (templateName
.StartsWith("/"))
156 controller
.InPlaceRenderSharedView(writer
, templateName
);
160 controller
.InPlaceRenderSharedView(writer
, Path
.Combine(Constants
.EmailTemplatePath
, templateName
));
163 if (doNotApplyLayout
)
165 controller
.LayoutName
= oldLayout
;
168 String body
= writer
.ToString();
170 // process delivery addresses from template.
171 MatchCollection matches
= Constants
.readdress
.Matches(body
);
173 for(int i
= 0; i
< matches
.Count
; i
++)
175 String header
= matches
[i
].Groups
[Constants
.HeaderKey
].ToString().ToLower();
176 String address
= matches
[i
].Groups
[Constants
.ValueKey
].ToString();
181 message
.To
= address
;
184 message
.Cc
= address
;
187 message
.Bcc
= address
;
192 if (logger
.IsDebugEnabled
)
194 logger
.DebugFormat("Rendering email message to {0} cc {1} bcc {2}", message
.To
, message
.Cc
, message
.Bcc
);
197 body
= Constants
.readdress
.Replace(body
, String
.Empty
);
199 // process from address from template
200 Match match
= Constants
.refrom
.Match(body
);
204 message
.From
= match
.Groups
[Constants
.ValueKey
].ToString();
205 body
= Constants
.refrom
.Replace(body
, String
.Empty
);
208 // process subject and X headers from template
209 matches
= Constants
.reheader
.Matches(body
);
211 for(int i
=0; i
< matches
.Count
; i
++)
213 String header
= matches
[i
].Groups
[Constants
.HeaderKey
].ToString();
214 String strval
= matches
[i
].Groups
[Constants
.ValueKey
].ToString();
216 if (header
.ToLower(System
.Globalization
.CultureInfo
.InvariantCulture
) == Constants
.Subject
)
218 message
.Subject
= strval
;
222 message
.Headers
.Add(header
, strval
);
225 if (logger
.IsDebugEnabled
)
227 logger
.DebugFormat("Adding header {0} value {1}", header
, strval
);
231 body
= Constants
.reheader
.Replace(body
, String
.Empty
);
235 if (logger
.IsDebugEnabled
)
237 logger
.DebugFormat("Email message body {0}", body
);
240 // a little magic to see if the body is html
241 if (message
.Body
.ToLower(System
.Globalization
.CultureInfo
.InvariantCulture
).IndexOf(Constants
.HtmlTag
) != -1)
243 message
.Format
= Format
.Html
;
245 if (logger
.IsDebugEnabled
)
247 logger
.Debug("Content set to Html");