woensdag 26 september 2007

ldap on mac os x

to start openldap:
jdijkmeijer [/usr/libexec]$sudo ./slapd

apache directory studio:
localhost:389 anonymous binding.
to be continued.

Ok the continue: For some reason I could not get the openldap to work correctly slapadd etc all seemed to work but login in with the rootdn and password supplied, gave an error 49 invalid credentials. I do suspect the berkeley db is screwed but i'm not sure.
Anyhow I'm about to reinstall openldap hopefull that will work without installing the prefigured ldap /usr/libexec/slapd Im also woondering what will happen to the slap* cmds. Anyhow just installed the berkeleydb 4.6. It would have been nice if the installation script at http://www.oracle.com/technology/documentation/berkeley-db/db/ref/build_unix/intro.html
would have made a indication that
sudo ln -s /usr/local/BerkeleyDB.4.6/include/db.h /usr/include/db.h would have been useful for tools like openldap. Again to be continued..
configuration of the sources failed with:
checking for db.h... yes
checking for Berkeley DB major version... 1
checking for Berkeley DB minor version... 0
checking for Berkeley DB link (-ldb1)... no
checking for Berkeley DB link (-ldb-1)... no
checking for Berkeley DB link (default)... yes
checking for Berkeley DB version match... yes
checking for Berkeley DB thread support... no

the installed version of berkeleydb must be explicitly indicated by the cppflags:
env CPPFLAGS="-I/usr/local/BerkeleyDB.4.6/include" LDFLAGS="-L/usr/local/BerkeleyDB.4.6/lib" ./configure
openldap is reinstalled and is located in /usr/local/libexec
time to get jboss listen to ldap...

woensdag 19 september 2007

jsf Solutions for many2many: the dataTable

The datatable with rowselector.



Icefaces has extended the datatable with the possibility of a rowselector allowing remote method call of a listener method (Ajax). This feature wonderfully and intuitivily integrates with seam's datamodel and, even more important, seam's datamodelselection. The datamodel for a datamodelselection is a list with objects, which must have a isSelected method. No interface or super class is needed as this method is textual mentioned in the rowselector's value property. Check the roleItem code for a complete implementation.
Having learned a few things from jpa-ql and hibernate ql, and with the help of 2 colleagues I have been able to define an elegant query to populate a list with all the roles, and if present the actor for the subject having focus. In the same query I also construct the roleItem (See the RoleSubjectMgrBean.roleitms() code below), no list manipulation needed afterwards. I'm currently unaware whether the used syntax is allowed jpa-ql? Persisting the selection is a piece of cake (See the RoleSubjectMgrBean.rowSelection..) I only had to change the sessionbeans from session to conversation scope.

<ice:dataTable value="#{subjectRoleList}"
var="roleItem" rendered="${focusSubject.subjectid gt 0}">
<ice:column>
<ice:rowSelector selectionListener="#{roleSubjectMgr.rowSelection}" value="#{roleItem.selected}" multiple="true" selectedClass="selected"/>
<f:facet name="header"><h:outputLabel value="#{msgs['spuyt.subject.edit.role.list']}"/></f:facet>
<h:outputText value="#{roleItem.role.name}"/>
</ice:column>
</ice:dataTable>



Alas some drawbacks of this approach:


  1. The cursor doesn't change when hovering over the items.

  2. The subject in focus must be created before the datamodelselection can save its attached roles. This forces a conditional render of the datamodel

  3. By selecting a row the update is immediately executed on the database. Of course the cancel button gets a complete new meaning(less).

  4. Used query may not be jpa compliant



RoleSubjectMgrBean.java
001 package nl.jeroen.testdb.persist;
002 
003 import java.io.Serializable;
004 import ..;
028 import org.jboss.seam.log.Log;
029 
030 import com.icesoft.faces.component.ext.RowSelectorEvent;
031 
032 @Scope(ScopeType.CONVERSATION)
033 @Stateful
034 @Name("roleSubjectMgr")
035 public class RoleSubjectMgrBean implements Serializable, RoleSubjectMgr {
036     private static final long serialVersionUID = -9145745003284315431L;
037 
038     @Logger
039     Log logger;
040     
041     @In(required=false)
042     private Subject focusSubject;
043     
044     @In(required=true)
045     IApplicationSession sessionstore;
046     
047     @DataModel(value="subjectRoleList")
048     private List<RoleItem> subjectRoleList;
049     
050     @DataModelSelection(value="subjectRoleList")
051     @Out(required=false, value="focusSubjectRoleList")
052     private RoleItem focusSubjectRoleList;
053     
054     @PersistenceContext(type=PersistenceContextType.EXTENDED)
055     private EntityManager em;
056     
057     @Factory("subjectRoleList")
058     public void roleItems() {
059         //http://opensource.atlassian.com/projects/hibernate/browse/HHH-2772
060          subjectRoleList = em.createQuery("select new nl.jeroen.spuyt.util.RoleItem (r, a) 
        from Role r left join r.actors as a with a.subject.subjectid = :subject")
061             .setParameter("subject", focusSubject.getSubjectid()).getResultList();
062     }
063 
064     @Destroy @Remove
065     public void destroy() {
066     }
067     
068     public void rowSelection(RowSelectorEvent e) {
069         final String methodName = "rowSelection: ";
070         if (logger.isDebugEnabled()) {
071             logger.debug(LogUtil.getLogMessage(methodName, LogUtil.VERSION, "'"
072                     + focusSubjectRoleList + "'"));
073         }
074         if (focusSubjectRoleList.isSelected() ) {
075             // it was selected and now we're going to remove it.
076             focusSubject.getActors().remove(focusSubjectRoleList.getActor());
077             em.remove(focusSubjectRoleList.getActor());
078             focusSubjectRoleList.setActor(null);
079         else {
080             // creating a new actor
081             Actor act = new Actor();
082             em.merge(focusSubject);
083             act.setPeriod(sessionstore.getFocusPeriod());
084             act.setRole(focusSubjectRoleList.getRole());
085             act.setSubject(focusSubject);
086             em.persist(act);
087             focusSubjectRoleList.setActor(act);
088         }
089     }
090     
091     public String persist() {
092         final String methodName = "persist: ";
093         if (logger.isTraceEnabled()) {
094             logger.trace(LogUtil.getLogMessage(methodName, LogUtil.VERSION,
095                     "starting '" "'"));
096         }
097         try {
098             if (focusSubject.getSubjectid() == 0) {
099                 em.persist(focusSubject);
100                 return "selectSubject";
101             }
102             em.merge(focusSubject);
103         catch (Exception e) {
104             logger.error("error occured:", e);
105             FacesContext.getCurrentInstance().addMessage("error on saving"new FacesMessage("error on saving"));
106         }
107         return "listSubject";
108     }
109 }


RoleItem.java
01 package nl.jeroen.spuyt.util;
02 
03 import nl.jeroen.testdb.persist.Actor;
04 import nl.jeroen.testdb.persist.Role;
05 
06 public class RoleItem {
07     Role role;
08     Actor actor;
09     
10     public RoleItem(Role r, Actor a) {
11         role = r;
12         actor = a;
13     }
14 
15     @Override
16     public String toString() {
17         return "name: '" + role.getName() "' roleid " + role.getRoleid() " actor " + actor;
18     }
19     
20     public boolean isSelected() {
21         return (actor != null);
22     }
23     
24     public void setSelected(boolean selected) {
25     }
26 
27     public Role getRole() {
28         return role;
29     }
30 
31     public void setRole(Role role) {
32         this.role = role;
33     }
34 
35     public Actor getActor() {
36         return actor;
37     }
38 
39     public void setActor(Actor actor) {
40         this.actor = actor;
41     }
42     
43 }