[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-3285) Seam Email session integration into jBPM
by Boretti Mathieu (JIRA)
Seam Email session integration into jBPM
----------------------------------------
Key: JBSEAM-3285
URL: https://jira.jboss.org/jira/browse/JBSEAM-3285
Project: Seam
Issue Type: Feature Request
Components: BPM
Affects Versions: 2.0.2.GA
Environment: N/A
Reporter: Boretti Mathieu
The goal is to use the MailSession from seam (provided by DataSource or not), when using jBPM task-node.
The idea is to provide a class that extend org.jbpm.mail.Mail and use the MailSession from Seam, instance of the MailSession from jBPM.
It is then possible to reference this class in the jbpm config file (<string name='jbpm.mail.class.name' value='XXXX' />
I wrote a small "example class", by copy-paste from jBPM (see below):
This implementation use the jBPM variable config jbpm.mail.ignoreError to throw, or not, an error in case of error in sending of email.
The MailSession is retrieved with
org.jboss.seam.mail.MailSession.instance();
package org.domain.HardWareStore.actions;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.seam.contexts.Context;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.mail.MailSession;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmException;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.jpdl.el.ELException;
import org.jbpm.jpdl.el.VariableResolver;
import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
import org.jbpm.mail.AddressResolver;
import org.jbpm.mail.Mail;
import org.jbpm.util.XmlUtil;
public class MailHandler extends Mail {
private static final long serialVersionUID = 1L;
String template = null;
String actors = null;
String to = null;
String bcc = null;
String bccActors = null;
String subject = null;
String text = null;
ExecutionContext executionContext = null;
public MailHandler() {
}
public MailHandler(String template, String actors, String to,
String subject, String text) {
this.template = template;
this.actors = actors;
this.to = to;
this.subject = subject;
this.text = text;
}
public MailHandler(String template, String actors, String to,
String bccActors, String bcc, String subject, String text) {
this.template = template;
this.actors = actors;
this.to = to;
this.bccActors = bccActors;
this.bcc = bcc;
this.subject = subject;
this.text = text;
}
public void execute(ExecutionContext executionContext) {
this.executionContext = executionContext;
send();
}
public List getRecipients() {
List recipients = new ArrayList();
if (actors != null) {
String evaluatedActors = evaluate(actors);
List tokenizedActors = tokenize(evaluatedActors);
if (tokenizedActors != null) {
recipients.addAll(resolveAddresses(tokenizedActors));
}
}
if (to != null) {
String resolvedTo = evaluate(to);
recipients.addAll(tokenize(resolvedTo));
}
return recipients;
}
public List getBccRecipients() {
List recipients = new ArrayList();
if (bccActors != null) {
String evaluatedActors = evaluate(bccActors);
List tokenizedActors = tokenize(evaluatedActors);
if (tokenizedActors != null) {
recipients.addAll(resolveAddresses(tokenizedActors));
}
}
if (bcc != null) {
String resolvedTo = evaluate(to);
recipients.addAll(tokenize(resolvedTo));
}
if (JbpmConfiguration.Configs.hasObject("jbpm.mail.bcc.address")) {
recipients.addAll(tokenize(JbpmConfiguration.Configs
.getString("jbpm.mail.bcc.address")));
}
return recipients;
}
public String getSubject() {
if (subject == null)
return null;
return evaluate(subject);
}
public String getText() {
if (text == null)
return null;
return evaluate(text);
}
public String getFromAddress() {
if (JbpmConfiguration.Configs.hasObject("jbpm.mail.from.address")) {
return JbpmConfiguration.Configs
.getString("jbpm.mail.from.address");
}
return "jbpm@noreply";
}
public void send() {
if (template != null) {
Properties properties = getMailTemplateProperties(template);
if (actors == null) {
actors = properties.getProperty("actors");
}
if (to == null) {
to = properties.getProperty("to");
}
if (subject == null) {
subject = properties.getProperty("subject");
}
if (text == null) {
text = properties.getProperty("text");
}
if (bcc == null) {
bcc = properties.getProperty("bcc");
}
if (bccActors == null) {
bccActors = properties.getProperty("bccActors");
}
}
send(getFromAddress(), getRecipients(), getBccRecipients(),
getSubject(), getText());
}
public static void send(String fromAddress, List recipients,
String subject, String text) {
send(fromAddress, recipients, null, subject, text);
}
public static void send(String fromAddress, List recipients,
List bccRecipients, String subject, String text) {
if ((recipients == null) || (recipients.isEmpty())) {
log.info("skipping mail because there are no recipients");
return;
}
log.info("sending email to '" + recipients + "' about '" + subject
+ "'");
log.info("BeginCall");
Context context = Lifecycle.beginMethod();
try {
log.info("GetSession");
Session session = MailSession.instance();
log.info("Create msg for "+session);
MimeMessage message = new MimeMessage(session);
if (fromAddress != null) {
message.setFrom(new InternetAddress(fromAddress));
}
Iterator iter = recipients.iterator();
while (iter.hasNext()) {
InternetAddress recipient = new InternetAddress((String) iter
.next());
message.addRecipient(Message.RecipientType.TO, recipient);
}
if (bccRecipients != null) {
iter = bccRecipients.iterator();
while (iter.hasNext()) {
InternetAddress recipient = new InternetAddress(
(String) iter.next());
message.addRecipient(Message.RecipientType.BCC, recipient);
}
}
if (subject != null) {
message.setSubject(subject);
}
if (text != null) {
message.setText(text);
}
message.setSentDate(new Date());
Transport.send(message);
} catch (Exception e) {
log.error("couldn't send email",e);
boolean ignore=false;
if (JbpmConfiguration.Configs.hasObject("jbpm.mail.ignoreError")) {
ignore=JbpmConfiguration.Configs.getBoolean("jbpm.mail.ignoreError");
}
if (!ignore) throw new JbpmException("couldn't send email", e);
} finally {
Lifecycle.endMethod(context);
}
}
protected List tokenize(String text) {
if (text == null) {
return null;
}
List list = new ArrayList();
StringTokenizer tokenizer = new StringTokenizer(text, ";:");
while (tokenizer.hasMoreTokens()) {
list.add(tokenizer.nextToken());
}
return list;
}
protected Collection resolveAddresses(List actorIds) {
List emailAddresses = new ArrayList();
Iterator iter = actorIds.iterator();
while (iter.hasNext()) {
String actorId = (String) iter.next();
AddressResolver addressResolver = (AddressResolver) JbpmConfiguration.Configs
.getObject("jbpm.mail.address.resolver");
Object resolvedAddresses = addressResolver.resolveAddress(actorId);
if (resolvedAddresses != null) {
if (resolvedAddresses instanceof String) {
emailAddresses.add((String) resolvedAddresses);
} else if (resolvedAddresses instanceof Collection) {
emailAddresses.addAll((Collection) resolvedAddresses);
} else if (resolvedAddresses instanceof String[]) {
emailAddresses.addAll(Arrays
.asList((String[]) resolvedAddresses));
} else {
throw new JbpmException(
"Address resolver '"
+ addressResolver
+ "' returned '"
+ resolvedAddresses.getClass().getName()
+ "' instead of a String, Collection or String-array: "
+ resolvedAddresses);
}
}
}
return emailAddresses;
}
static Map templates = null;
static Map templateVariables = null;
synchronized Properties getMailTemplateProperties(String templateName) {
if (templates == null) {
templates = new HashMap();
String mailTemplatesResource = JbpmConfiguration.Configs
.getString("resource.mail.templates");
org.w3c.dom.Element mailTemplatesElement = XmlUtil
.parseXmlResource(mailTemplatesResource)
.getDocumentElement();
List mailTemplateElements = XmlUtil.elements(mailTemplatesElement,
"mail-template");
Iterator iter = mailTemplateElements.iterator();
while (iter.hasNext()) {
org.w3c.dom.Element mailTemplateElement = (org.w3c.dom.Element) iter
.next();
Properties templateProperties = new Properties();
addTemplateProperty(mailTemplateElement, "actors",
templateProperties);
addTemplateProperty(mailTemplateElement, "to",
templateProperties);
addTemplateProperty(mailTemplateElement, "subject",
templateProperties);
addTemplateProperty(mailTemplateElement, "text",
templateProperties);
addTemplateProperty(mailTemplateElement, "bcc",
templateProperties);
addTemplateProperty(mailTemplateElement, "bccActors",
templateProperties);
templates.put(mailTemplateElement.getAttribute("name"),
templateProperties);
}
templateVariables = new HashMap();
List variableElements = XmlUtil.elements(mailTemplatesElement,
"variable");
iter = variableElements.iterator();
while (iter.hasNext()) {
org.w3c.dom.Element variableElement = (org.w3c.dom.Element) iter
.next();
templateVariables.put(variableElement.getAttribute("name"),
variableElement.getAttribute("value"));
}
}
return (Properties) templates.get(templateName);
}
void addTemplateProperty(org.w3c.dom.Element mailTemplateElement,
String property, Properties templateProperties) {
org.w3c.dom.Element element = XmlUtil.element(mailTemplateElement,
property);
if (element != null) {
templateProperties.put(property, XmlUtil.getContentText(element));
}
}
String evaluate(String expression) {
if (expression == null) {
return null;
}
VariableResolver variableResolver = JbpmExpressionEvaluator
.getUsedVariableResolver();
if (variableResolver != null) {
variableResolver = new MailVariableResolver(templateVariables,
variableResolver);
}
return (String) JbpmExpressionEvaluator.evaluate(expression,
executionContext, variableResolver, null);
}
class MailVariableResolver implements VariableResolver, Serializable {
private static final long serialVersionUID = 1L;
Map templateVariables = null;
VariableResolver variableResolver = null;
public MailVariableResolver(Map templateVariables,
VariableResolver variableResolver) {
this.templateVariables = templateVariables;
this.variableResolver = variableResolver;
}
public Object resolveVariable(String pName) throws ELException {
if ((templateVariables != null)
&& (templateVariables.containsKey(pName))) {
return templateVariables.get(pName);
}
return variableResolver.resolveVariable(pName);
}
}
private static Log log = LogFactory.getLog(Mail.class);
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years
[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-2286) MDB activated too early to use Seam components as a standard EJB
by Siarhei Dudzin (JIRA)
MDB activated too early to use Seam components as a standard EJB
----------------------------------------------------------------
Key: JBSEAM-2286
URL: http://jira.jboss.com/jira/browse/JBSEAM-2286
Project: JBoss Seam
Issue Type: Bug
Affects Versions: 2.0.0.GA
Reporter: Siarhei Dudzin
Priority: Critical
As specified in the forum reference I have an MDB which uses a SLSB (also declared as Seam component) with business logic. If I deploy the application and there are already messages in the queue I get the following exception:
javax.ejb.EJBTransactionRolledbackException: java.lang.IllegalStateException: Attempted to invoke a
Seam component outside the an initialized application
at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:87)
at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.mdb.MessagingContainer.localInvoke(MessagingContainer.java:249)
at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.delivery(MessageInflowLocalProxy.java:268)
at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.invoke(MessageInflowLocalProxy.java:138)
at $Proxy111.onMessage(Unknown Source)
Looks like the MDB processing the message before Seam is initialized?
This forces me to undeclare the SLSB as a Seam component and (potentially) duplicate business logic if I want to re-use the same functionality of the SLSB in Seam.
I could use the solution from http://www.jboss.org/?module=bb&op=viewtopic&t=100946 but then it would force me to use vendor-specific API.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 3 months
[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-2764) Factory method does not create objects properly
by Bogdan Minciu (JIRA)
Factory method does not create objects properly
-----------------------------------------------
Key: JBSEAM-2764
URL: http://jira.jboss.com/jira/browse/JBSEAM-2764
Project: JBoss Seam
Issue Type: Bug
Components: EJB3
Affects Versions: 2.0.1.GA
Reporter: Bogdan Minciu
Hello,
It seems that my @Factory method is recognizing the created objects only in its command block. I have this class:
@Stateful
@Name("xtw")
@Scope(ScopeType.SESSION)
@AutoCreate
public class XTextSessionWrapper implements LocalXTextSessionWrapper {
...
@In(required=false, create=true)
@Out
private XLanguage activeLanguage;
public String getText(String identifier) {
log.info("getText(1): identifier= #0, activeLanguage= #1", identifier, getActiveLanguage());
XTextEntry xte = xTextEntryDAO.findXTextEntry(identifier, getActiveLanguage());
log.info("getText(2): identifier= #0, activeLanguage= #1", identifier, getActiveLanguage());
xte.getXtext();
}
@Factory(value="activeLanguage", autoCreate=true)
public void initActiveLanguage() {
XLanguage xl = xLanguageDAO.findXLanguageByIdentifier("ro");
log.info("initActiveLanguage(1): activeLanguage initialized to #0", xl.getIdentifier());
setActiveLanguage(xl);
log.info("initActiveLanguage(1): activeLanguage initialized to #0", getActiveLanguage().getIdentifier());
}
public XLanguage getActiveLanguage() {
return activeLanguage;
}
public void setActiveLanguage(XLanguage activeLanguage) {
this.activeLanguage = activeLanguage;
}
...
}
And i am calling the getText() method. The method calling is as expected:
1. the injected activeLanguage is detecting that it has a null value,
2. the initActiveLanguage() factory method is called
3. then the getText() method is continuing its execution.
But, the problem is that when the application exists the @Factory method block, the created objects: activeLanguage is lost and reported again as null.
Here is the output:
12:43:48,203 INFO [XTextSessionWrapper] initActiveLanguage(1): activeLanguage initialized to ro
12:43:48,203 INFO [XTextSessionWrapper] initActiveLanguage(1): activeLanguage initialized to ro
12:43:48,703 INFO [XTextSessionWrapper] initActiveLanguage(1): activeLanguage initialized to ro
12:43:48,703 INFO [XTextSessionWrapper] initActiveLanguage(1): activeLanguage initialized to ro
12:43:48,703 INFO [XTextSessionWrapper] getText(1): identifier= com.brit.xcms.cms.Category.12.name, activeLanguage= null
12:43:49,234 INFO [XTextSessionWrapper] getText(2): identifier= com.brit.xcms.cms.Category.12.name, activeLanguage= null
Where did I went wrong? Why is the activeLanguage factoried value lost when i leave the initActiveLanguage() method?
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 4 months
[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-2697) Add attribute to s:link tag to make creation of magic dataModelSelection URL parameter optional
by Wolfgang Schwendt (JIRA)
Add attribute to s:link tag to make creation of magic dataModelSelection URL parameter optional
-----------------------------------------------------------------------------------------------
Key: JBSEAM-2697
URL: http://jira.jboss.com/jira/browse/JBSEAM-2697
Project: JBoss Seam
Issue Type: Feature Request
Components: JSF Controls
Affects Versions: 2.0.1.GA
Reporter: Wolfgang Schwendt
Priority: Minor
When an s:link component (org.jboss.seam.ui.component.UILink) is placed into a h:dataTable backed by a javax.faces.model.DataModel, the s:link automatically generates the magic token for the magic "dataModelSelection" parameter regardless of whether the latter is really needed or not.
This can generate ugly URLs. The following example is particulary ugly:
http://127.0.0.1:8080/seminaris/seminarDetails.seam?seminarId=2&dataModel...
Without the "dataModelSelection" parameter, the URL would look much cleaner:
http://127.0.0.1:8080/seminaris/seminarDetails.seam?semId=2
So my question: Couldn't we make the "dataModelSelection" parameter optional? (For example, by adding an attribute to the s:link tag).
Btw: I'm aware that org.jboss.seam.ui.component.UISeamCommandBase.getUrl() is the culprit that triggers inclusion of the the dataModelSelection parameter, so I know how to remove the dataModelSelection parameter generation, but it would be nice if also the officially released Seam version allowed the deactivation of the magic token generation.
Further, no magic token is generated if a UIDataTable is supplied by a normal List rather than a DataModel (cf. UISeamCommandBase.getSelection() ), but unfortunately there can be cases where it makes sense to supply the table data as DataModel rather than normal List.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 7 months