Hi All,
Version: SmartGWTEE 4.1
We are using DMI as a thin layer to call EJB where our application logic resides. The EJB returns JPA beans which are converted by SmartGWT Enterprise into data for the client. We wanted to annotate our EJB on the DMI usign CDI @Inject rather than having to use JNDI to lookup our EJBs. This also removes the requirement to add <resource> for every ejb to our web.xml. CDI is new in J2EE6 and quite helpful. http://cdi-spec.org/
This is a modest improvement for us but may be helpful to others. This code has not been thoroughly analyzed so use at your own risk - of course feedback is welcome. The code requires that a DataSource named User has a DMI named UserDMI as a convention.
The following code shows the DataSource using the factory lookup.
The SmartGWT server calls the create(...) method on the factory and passes the DSRequest to the method. The create method looks up the CDI and passes back to SC so it can call fetch or one of the other DMI request methods.
This is the DMI example which is a CDI bean. Notice the @Local EJB is annotated.
So if something like this was added to SmartClient, I think it would be similar to the "spring" lookup.
https://www.smartclient.com/smartgwtee/javadoc/com/smartgwt/client/docs/serverds/ServerObject.html#lookupStyle
<serverObject lookupStyle="dmi" beanName="userDMI" or beanClass="com.ray.dmi.UserDMI" scope="application | session | request />
Note that CDI for the most part uses type for matching so lookups internally use a type but can also be looked up by name
like the factory example shown above. Here scope is probably like for the "attribute" lookup style.
Thanks,
Eric
Version: SmartGWTEE 4.1
We are using DMI as a thin layer to call EJB where our application logic resides. The EJB returns JPA beans which are converted by SmartGWT Enterprise into data for the client. We wanted to annotate our EJB on the DMI usign CDI @Inject rather than having to use JNDI to lookup our EJBs. This also removes the requirement to add <resource> for every ejb to our web.xml. CDI is new in J2EE6 and quite helpful. http://cdi-spec.org/
This is a modest improvement for us but may be helpful to others. This code has not been thoroughly analyzed so use at your own risk - of course feedback is welcome. The code requires that a DataSource named User has a DMI named UserDMI as a convention.
The following code shows the DataSource using the factory lookup.
Code:
<DataSource ID="User" serverType="generic"> <fields> <field name="id" type="integer" title="Id" hidden="true" primaryKey="true" length="20"/> <field name="employeeId" type="text" title="Employee Id" required="true" length="20"/> <field name="firstName" type="text" title="First Name" required="true" length="20"/> <field name="lastName" type="text" title="Last Name" required="true" length="30"/> </fields> <serverObject lookupStyle="factory" className="com.ray.sc.DmiFactory" /> </DataSource>
Code:
package com.ray.sc; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.naming.InitialContext; import javax.naming.NamingException; import com.isomorphic.datasource.DSRequest; import com.isomorphic.datasource.DataSource; /** * Allow SmartGWT server to lookup a DMI which is a CDI bean. * * DMI is named after the DataSource such as User / UserDMI * and the CDI bean annotation {@code @Named} is defaulted which make the * bean name {@code userDMI}. Please follow this convention. * * @author ekr * */ public class DmiFactory { /** * Cached BeanManager */ private static final BeanManager beanManager = lookup(); /** * Required default ctor */ public DmiFactory() { } /** * SmartGWT server calls this method. Looks at the data * source name to look up the DMI which is a CDI Managed * bean. We use the naming convention for the DMI which * the the DataSource name plus DMI. (User -> UserDMI) * * @param dsRequest - used to get datasource * @return - the DMI looked up from the BeanManager * @throws Exception */ public Object create(DSRequest dsRequest) throws Exception { DataSource ds = dsRequest.getDataSource(); String dsName = ds.getName(); String dmiName = dsName.substring(0, 1).toLowerCase() + dsName.substring(1) + "DMI"; return lookupBean(beanManager, dmiName); } private static BeanManager lookup() { BeanManager beanManager = null; try { InitialContext context = new InitialContext(); beanManager = (BeanManager) context.lookup("java:comp/BeanManager"); } catch (NamingException e) { throw new RuntimeException(e); } return beanManager; } private Object lookupBean(BeanManager beanManager, String beanName) { Bean<?> bean = beanManager.getBeans(beanName).iterator().next(); CreationalContext<?> ctx = beanManager.createCreationalContext(bean); Object o = beanManager.getReference(bean, bean.getClass(), ctx); return o; } }
Code:
package com.ray.demo.gwt.server.dmi; import java.util.List; import java.util.logging.Logger; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.inject.Named; import com.isomorphic.datasource.DSRequest; import com.isomorphic.datasource.DSResponse; import com.ray.demo.entity.User; import com.ray.demo.model.UserLocal; import com.ray.sc.dmi.DmiUtils; @Named @RequestScoped public class UserDMI { @Inject private UserLocal userBean; public DSResponse fetch(DSRequest dsRequest) throws Exception { return DmiUtils.prepareResponse(userBean.findAllUsers()); } public DSResponse update(DSRequest dsRequest) throws Exception { User record = DmiUtils.applyRequestToBean(dsRequest, User.class); List<String> roleCodes = getRoleCodesFromRequest(dsRequest); User user = userBean.update(record, roleCodes); return DmiUtils.prepareResponse(user); } public DSResponse add(DSRequest dsRequest) throws Exception { User record = DmiUtils.applyRequestToBean(dsRequest, User.class); List<String> roleCodes = getRoleCodesFromRequest(dsRequest); User user = userBean.add(record, roleCodes); return DmiUtils.prepareResponse(user); } private List<String> getRoleCodesFromRequest(DSRequest dsRequest) { return DmiUtils.getAppliedValue(dsRequest, "roleName"); } }
https://www.smartclient.com/smartgwtee/javadoc/com/smartgwt/client/docs/serverds/ServerObject.html#lookupStyle
<serverObject lookupStyle="dmi" beanName="userDMI" or beanClass="com.ray.dmi.UserDMI" scope="application | session | request />
Note that CDI for the most part uses type for matching so lookups internally use a type but can also be looked up by name
like the factory example shown above. Here scope is probably like for the "attribute" lookup style.
Thanks,
Eric
Comment