KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > ldap > LdapGroupProvider


1 /**
2  * $RCSfile: LdapGroupProvider.java,v $
3  * $Revision: 1.4 $
4  * $Date: 2005/08/01 16:54:39 $
5  *
6  * Copyright (C) 2005 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger.ldap;
13
14 import org.jivesoftware.util.*;
15 import org.jivesoftware.messenger.user.*;
16 import org.jivesoftware.messenger.group.*;
17 import org.xmpp.packet.JID;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.TreeMap JavaDoc;
21 import java.util.TreeSet JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.Vector JavaDoc;
26 import java.text.MessageFormat JavaDoc;
27
28 import javax.naming.Name JavaDoc;
29 import javax.naming.NamingEnumeration JavaDoc;
30 import javax.naming.directory.*;
31 import javax.naming.ldap.LdapName JavaDoc;
32
33 /**
34  * LDAP implementation of the GroupProvider interface. All data in the directory is
35  * treated as read-only so any set operations will result in an exception.
36  *
37  * @author Greg Ferguson and Cameron Moore
38  */

39 public class LdapGroupProvider implements GroupProvider
40 {
41
42     private LdapManager manager;
43     private UserManager userManager;
44     private int groupCount;
45     private long expiresStamp;
46     private String JavaDoc[] standardAttributes;
47
48     /**
49      * Constructor of the LdapGroupProvider class.
50      * Gets an LdapManager instance from the LdapManager class.
51      *
52      */

53     public LdapGroupProvider() {
54         manager = LdapManager.getInstance();
55         userManager = UserManager.getInstance();
56         groupCount = -1;
57         expiresStamp = System.currentTimeMillis();
58         standardAttributes = new String JavaDoc[3];
59         standardAttributes[0] = manager.getGroupNameField();
60         standardAttributes[1] = manager.getGroupDescriptionField();
61         standardAttributes[2] = manager.getGroupMemberField();
62     }
63
64     /**
65      * Always throws UnsupportedOperationException because
66      * LDAP operations are treated as read only.
67      *
68      * @param group Name of the group to be created.
69      * @throws UnsupportedOperationException when called.
70      */

71     public Group createGroup (String JavaDoc group)
72         throws UnsupportedOperationException JavaDoc
73     {
74         throw new UnsupportedOperationException JavaDoc();
75     }
76
77     /**
78      * Always throws UnsupportedOperationException because
79      * LDAP operations are treated as read only.
80      *
81      * @param group Group that should be deleted.
82      * @throws UnsupportedOperationException when called.
83      */

84     public void deleteGroup (Group group)
85         throws UnsupportedOperationException JavaDoc
86     {
87         throw new UnsupportedOperationException JavaDoc();
88     }
89
90     /**
91      * Always throws UnsupportedOperationException because
92      * LDAP operations are treated as read only.
93      *
94      * @param group Group that should be deleted.
95      * @throws UnsupportedOperationException when called.
96      */

97     public void deleteGroup (String JavaDoc group)
98         throws UnsupportedOperationException JavaDoc
99     {
100         throw new UnsupportedOperationException JavaDoc();
101     }
102
103     /**
104      * Will populate a group object based on the group name
105      * that is given.
106      *
107      * @param group Name of group that should be retrieved.
108      * @return a populated group based on the name provided.
109      */

110     public Group getGroup (String JavaDoc group)
111     {
112         String JavaDoc filter = MessageFormat.format(manager.getGroupSearchFilter(),"*");
113         String JavaDoc searchFilter = "(&"+filter+"("+
114                               manager.getGroupNameField()+"="+group+"))";
115         Collection JavaDoc<Group> groups = populateGroups(searchForGroups(searchFilter,standardAttributes));
116         if (groups.size() > 1)
117             return null; //if multiple groups found return null
118
for (Group g : groups)
119             return g; //returns the first group found
120
return null;
121     }
122
123     /**
124      * Always throws UnsupportedOperationException because
125      * LDAP operations are treated as read only.
126      *
127      * @param name Current name of group.
128      * @param s Desired name of group.
129      * @throws UnsupportedOperationException when called.
130      */

131     public void setName(String JavaDoc name, String JavaDoc s)
132         throws UnsupportedOperationException JavaDoc
133     {
134         throw new UnsupportedOperationException JavaDoc();
135     }
136
137     /**
138      * Always throws UnsupportedOperationException because
139      * LDAP operations are treated as read only.
140      *
141      * @param description Current description of group.
142      * @param s Desired description of group.
143      * @throws UnsupportedOperationException when called.
144      */

145     public void setDescription(String JavaDoc description,String JavaDoc s)
146         throws UnsupportedOperationException JavaDoc
147     {
148         throw new UnsupportedOperationException JavaDoc();
149     }
150
151     /**
152      * Will return the current number of groups in the
153      * LDAP server.
154      *
155      * @return the number of groups in the LDAP server.
156      */

157     public int getGroupCount()
158     {
159         // Cache group count for 5 minutes.
160
if (groupCount != -1 && System.currentTimeMillis() < expiresStamp) {
161             return groupCount;
162         }
163         int count = 0;
164
165         if (manager.isDebugEnabled()) {
166             Log.debug("Trying to get the number of groups in the system.");
167         }
168
169         String JavaDoc searchFilter = MessageFormat.format(manager.getGroupSearchFilter(),"*");
170         String JavaDoc returningAttributes[]= { manager.getGroupNameField() };
171         NamingEnumeration JavaDoc<SearchResult> answer = searchForGroups(searchFilter,returningAttributes);
172         for (; answer.hasMoreElements(); count++)
173         {
174            try
175            {
176               answer.next();
177            }
178            catch (Exception JavaDoc e) { }
179         }
180
181         this.groupCount = count;
182         this.expiresStamp = System.currentTimeMillis() + JiveConstants.MINUTE *5;
183         return count;
184     }
185
186     /**
187      * Will return a collecion of all groups in the system.
188      *
189      * @return collection of all groups in the system.
190      */

191     public Collection JavaDoc<Group> getGroups()
192     {
193         String JavaDoc filter = MessageFormat.format(manager.getGroupSearchFilter(),"*");
194         return populateGroups(searchForGroups(filter,standardAttributes));
195     }
196
197     /**
198      * Will return a collecion of groups in the system
199      * based on the start index and number of groups desired.
200      * Useful when displaying a certain number of groups
201      * per page on a webpage.
202      *
203      * @param start starting index
204      * @param num number of groups you want
205      * @return collection of groups.
206      */

207     public Collection JavaDoc<Group> getGroups(int start, int num)
208     {
209         ArrayList JavaDoc<Group> returnCollection = new ArrayList JavaDoc<Group>();
210
211         // get an enumeration of all groups in the system
212

213         String JavaDoc searchFilter = MessageFormat.format(manager.getGroupSearchFilter(),"*");
214         NamingEnumeration JavaDoc<SearchResult> answer = searchForGroups(searchFilter,standardAttributes);
215
216         //place all groups that are wanted into an enumeration
217

218         Vector JavaDoc<SearchResult> v = new Vector JavaDoc<SearchResult>();
219         for (int i = 1; answer.hasMoreElements() && i <= (start+num); i++)
220         {
221            try
222            {
223               SearchResult sr = answer.next();
224               if (i >= start)
225                  v.add(sr);
226            }
227            catch (Exception JavaDoc e) { }
228         }
229
230         return populateGroups(v.elements());
231     }
232
233     /**
234      * Will return a collection of groups in the
235      * system that the user provided belongs to.
236      *
237      * @param user a user
238      * @return collection of groups.
239      */

240     public Collection JavaDoc<Group> getGroups(User user)
241     {
242         String JavaDoc username = JID.unescapeNode(user.getUsername());
243         if (!manager.getPosixEnabled())
244         {
245            try
246            {
247               username = manager.findUserDN(username) + "," +
248                          manager.getBaseDN();
249            }
250            catch (Exception JavaDoc e)
251            {
252               return new ArrayList JavaDoc<Group>();
253            }
254         }
255
256         String JavaDoc filter = MessageFormat.format(manager.getGroupSearchFilter(),username);
257         return populateGroups(searchForGroups(filter,standardAttributes));
258     }
259
260     /**
261      * Always throws UnsupportedOperationException because
262      * LDAP operations are treated as read only.
263      *
264      * @param groupName Name of a group.
265      * @param username Name of a user.
266      * @param administrator True if is an administrator.
267      * @throws UnsupportedOperationException when called.
268      */

269     public void addMember(String JavaDoc groupName, String JavaDoc username, boolean administrator)
270         throws UnsupportedOperationException JavaDoc
271     {
272         throw new UnsupportedOperationException JavaDoc();
273     }
274
275     /**
276      * Always throws UnsupportedOperationException because
277      * LDAP operations are treated as read only.
278      *
279      * @param groupName Name of a group.
280      * @param username Name of a user.
281      * @param administrator True if is an administrator.
282      * @throws UnsupportedOperationException when called.
283      */

284     public void updateMember(String JavaDoc groupName, String JavaDoc username, boolean administrator)
285         throws UnsupportedOperationException JavaDoc
286     {
287         throw new UnsupportedOperationException JavaDoc();
288     }
289
290     /**
291      * Always throws UnsupportedOperationException because
292      * LDAP operations are treated as read only.
293      *
294      * @param groupName Name of a group.
295      * @param username Name of a user.
296      * @throws UnsupportedOperationException when called.
297      */

298     public void deleteMember(String JavaDoc groupName, String JavaDoc username)
299         throws UnsupportedOperationException JavaDoc
300     {
301         throw new UnsupportedOperationException JavaDoc();
302     }
303
304     /**
305      * Always returns true because all LDAP operations
306      * are treated as read only.
307      *
308      * @return true always because all LDAP functions are read only.
309      */

310     public boolean isReadOnly()
311     {
312         return true;
313     }
314
315
316     /**
317      * An auxilary method used to perform LDAP queries based on a
318      * provided LDAP search filter.
319      *
320      * @return an enumeration of SearchResult.
321      * @param searchFilter LDAP search filter used to query.
322      */

323     private NamingEnumeration JavaDoc<SearchResult> searchForGroups (String JavaDoc searchFilter,
324                                                              String JavaDoc[] returningAttributes)
325     {
326        if (manager.isDebugEnabled()) {
327            Log.debug("Trying to find all groups in the system.");
328        }
329        DirContext ctx = null;
330        NamingEnumeration JavaDoc<SearchResult> answer = null;
331        try
332        {
333           ctx = manager.getContext();
334           if (manager.isDebugEnabled()) {
335              Log.debug("Starting LDAP search...");
336              Log.debug("Using groupSearchFilter: "+searchFilter);
337           }
338
339           // Search for the dn based on the groupname.
340
SearchControls searchControls = new SearchControls();
341           searchControls.setReturningAttributes(returningAttributes);
342           searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
343           answer = ctx.search("",searchFilter,searchControls);
344
345           if (manager.isDebugEnabled()) {
346              Log.debug("... search finished");
347           }
348        }
349        catch (Exception JavaDoc e)
350        {
351           if (manager.isDebugEnabled())
352              Log.debug("Error while searching for groups.",e);
353        }
354        return answer;
355     }
356
357     /**
358      * An auxilary method used to populate LDAP groups based on a
359      * provided LDAP search result.
360      *
361      * @return a collection of groups.
362      * @param answer LDAP search result.
363      */

364     private Collection JavaDoc<Group> populateGroups (Enumeration JavaDoc<SearchResult> answer)
365     {
366        if (manager.isDebugEnabled()) {
367           Log.debug("Starting to populate groups with users.");
368        }
369
370        TreeMap JavaDoc<String JavaDoc,Group> groups = new TreeMap JavaDoc<String JavaDoc,Group>();
371
372        DirContext ctx = null;
373        try
374        {
375           ctx = manager.getContext();
376        }
377        catch (Exception JavaDoc e)
378        {
379           return new ArrayList JavaDoc<Group>();
380        }
381
382        SearchControls ctrls = new SearchControls();
383        ctrls.setReturningAttributes( new String JavaDoc[]{manager.getUsernameField()} );
384        ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
385
386        String JavaDoc userSearchFilter = MessageFormat.format(manager.getSearchFilter(),"*");
387
388        while (answer.hasMoreElements())
389        {
390           String JavaDoc name = "";
391           try
392           {
393              Attributes a = (((SearchResult)answer.nextElement()).getAttributes());
394              String JavaDoc description;
395              try
396              {
397                 name = ((String JavaDoc)((a.get(manager.getGroupNameField())).get()));
398                 description = ((String JavaDoc)((a.get(manager.getGroupDescriptionField())).get()));
399              }
400              catch (Exception JavaDoc e)
401              {
402                 description = "";
403              }
404              TreeSet JavaDoc<String JavaDoc> members = new TreeSet JavaDoc<String JavaDoc>();
405              Attribute member = a.get(manager.getGroupMemberField());
406              NamingEnumeration JavaDoc ne = member.getAll();
407              while (ne.hasMore())
408              {
409                 String JavaDoc userName = (String JavaDoc)ne.next();
410                 if (!manager.getPosixEnabled())
411                 { //userName is full dn if not posix
412
try
413                     {
414                        // Get the CN using LDAP
415
LdapName JavaDoc ldapname = new LdapName JavaDoc(userName);
416                        String JavaDoc ldapcn = ldapname.get(ldapname.size()-1);
417
418                        // We have to do a new search to find the username field
419

420                        String JavaDoc combinedFilter = "(&("+ldapcn+")"+userSearchFilter+")";
421                        NamingEnumeration JavaDoc usrAnswer = ctx.search("",combinedFilter,ctrls);
422                        if (usrAnswer.hasMoreElements())
423                        {
424                            userName = (String JavaDoc)((SearchResult)usrAnswer.next()).getAttributes().get(
425                                    manager.getUsernameField()).get();
426                        }
427                        else
428                           throw new UserNotFoundException();
429                     }
430                     catch (Exception JavaDoc e)
431                     {
432                        if (manager.isDebugEnabled())
433                           Log.debug("Error populating user with DN: "+userName,e);
434                     }
435                 }
436                 try
437                 {
438                     User user = userManager.getUser(JID.escapeNode(userName));
439                     members.add(user.getUsername());
440                 }
441                 catch (UserNotFoundException e)
442                 {
443                     if (manager.isDebugEnabled())
444                        Log.debug("User not found: "+userName);
445                 }
446              }
447              if (manager.isDebugEnabled())
448                  Log.debug("Adding group \""+name+"\" with "+members.size()+" members.");
449              Group g = new Group(this,name,description,members,new ArrayList JavaDoc<String JavaDoc>());
450              groups.put(name,g);
451           }
452           catch (Exception JavaDoc e)
453           {
454              if (manager.isDebugEnabled())
455                 Log.debug("Error while populating group, "+name+".",e);
456           }
457        }
458        if (manager.isDebugEnabled())
459           Log.debug("Finished populating group(s) with users.");
460
461        try
462        {
463           ctx.close();
464        }
465        catch (Exception JavaDoc e) { }
466
467        return groups.values();
468     }
469 }
Popular Tags