View Javadoc

1   /**
2    * 2007, Digitalis Informatica. All rights reserved. Distribuicao e Gestao de Informatica, Lda. Estrada de Paco de Arcos
3    * num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999 http://www.digitalis.pt
4    */
5   
6   package pt.digitalis.dif.controller.security.managers.impl;
7   
8   import java.io.InputStream;
9   import java.util.ArrayList;
10  import java.util.HashMap;
11  import java.util.HashSet;
12  import java.util.List;
13  import java.util.Map;
14  import java.util.Map.Entry;
15  import java.util.Set;
16  
17  import javax.xml.parsers.DocumentBuilder;
18  import javax.xml.parsers.DocumentBuilderFactory;
19  
20  import org.w3c.dom.Document;
21  import org.w3c.dom.Element;
22  import org.w3c.dom.Node;
23  import org.w3c.dom.NodeList;
24  
25  import pt.digitalis.dif.controller.security.managers.IAuthorizationManager;
26  import pt.digitalis.dif.controller.security.objects.DIFGroupImpl;
27  import pt.digitalis.dif.controller.security.objects.DIFUserImpl;
28  import pt.digitalis.dif.controller.security.objects.IDIFClonableUser;
29  import pt.digitalis.dif.controller.security.objects.IDIFGroup;
30  import pt.digitalis.dif.controller.security.objects.IDIFUser;
31  import pt.digitalis.dif.exception.InternalFrameworkException;
32  import pt.digitalis.dif.exception.security.IdentityManagerException;
33  import pt.digitalis.dif.ioc.DIFIoCRegistry;
34  import pt.digitalis.dif.startup.DIFStartupConfiguration;
35  import pt.digitalis.dif.utils.ObjectFormatter;
36  import pt.digitalis.dif.utils.Pagination;
37  import pt.digitalis.dif.utils.logging.DIFLogger;
38  
39  /**
40   * Default implementation for the identity manager.
41   * 
42   * @author Rodrigo Gonçalves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a><br/>
43   * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a>
44   * @author Fábio Souto <a href="mailto:fsouto@digitalis.pt">fsouto@digitalis.pt</a><br/>
45   * @created 2007/12/04
46   */
47  public class IdentityManagerStaticImpl extends AbstractIdentityManager {
48  
49      /** The authorization manager. */
50      static private IAuthorizationManager authorizationManager = DIFIoCRegistry.getRegistry().getImplementation(
51              IAuthorizationManager.class);
52  
53      /** The '' char as a String literal. */
54      final static private String EMPTY = "";
55  
56      /** The ' ' char as a String literal. */
57      final static private String SPACE = " ";
58  
59      /** Users file name to load */
60      private static final String USERS_FILE_NAME = "users.xml";
61  
62      /** Stores the sub-groups that belong to a given group (index for searching). <K = groupID, V = {subGroupIDs}> */
63      Map<String, Set<String>> groupGroups = new HashMap<String, Set<String>>();
64  
65      /** The group list. */
66      Map<String, IDIFGroup> groupList = new HashMap<String, IDIFGroup>();
67  
68      /** Stores the users that belong to a given group (index for searching). <K = groupID, V = {userIDs}> */
69      Map<String, Set<String>> groupUsers = new HashMap<String, Set<String>>();
70  
71      /** Stores the groups that belong to a given user (index for searching). <K = userID, V = {groupIDs}> */
72      Map<String, Set<String>> userGroups = new HashMap<String, Set<String>>();
73  
74      /** The user list. */
75      Map<String, IDIFClonableUser> userList = new HashMap<String, IDIFClonableUser>();
76  
77      /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#addGroup(IDIFGroup) */
78      synchronized public void addGroup(IDIFGroup newGroup) throws IdentityManagerException
79      {
80          if (newGroup != null && newGroup.getID() != null && !EMPTY.equals(newGroup.getID())
81                  && !SPACE.equals(newGroup.getID()) && !N_A.equals(newGroup.getID()))
82          {
83              this.groupList.put(newGroup.getID(), newGroup);
84              this.groupUsers.put(newGroup.getID(), new HashSet<String>());
85          }
86          else
87              throw new IdentityManagerException("Mandatory field ID doesn't exist on group!");
88      }
89  
90      /**
91       * Adds a group to the IdentityManager if it does not exist
92       * 
93       * @param groupID
94       * @param reportAdditions
95       * @throws IdentityManagerException
96       */
97      private void addGroupIfNotExists(String groupID, boolean reportAdditions) throws IdentityManagerException
98      {
99          if (!groupExists(groupID))
100         {
101             IDIFGroup group = new DIFGroupImpl();
102             group.setID(groupID);
103             group.setName(groupID);
104             group.setDescription(groupID);
105 
106             addGroup(group);
107 
108             if (reportAdditions)
109                 DIFLogger.getLogger().warn(
110                         "  => Group \"" + groupID + "\" not found. Was added to the IdentityManager.");
111         }
112     }
113 
114     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#addUser(IDIFUser) */
115     synchronized public void addUser(IDIFUser newUser) throws IdentityManagerException
116     {
117         if (newUser != null && newUser.getID() != null && !EMPTY.equals(newUser.getID())
118                 && !SPACE.equals(newUser.getID()) && !N_A.equals(newUser.getID()))
119         {
120             this.userList.put(newUser.getID(), (IDIFClonableUser) newUser);
121             this.userGroups.put(newUser.getID(), new HashSet<String>());
122         }
123         else
124             throw new IdentityManagerException("Mandatory field ID doesn't exist on user!");
125     }
126 
127     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#addUserToGroup(String, String) */
128     synchronized public void addUserToGroup(String userID, String groupID)
129     {
130         if (this.groupUsers.containsKey(groupID))
131         {
132             this.groupUsers.get(groupID).add(userID);
133             this.userGroups.get(userID).add(groupID);
134         }
135     }
136 
137     /**
138      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#changePassword(java.lang.String,
139      *      java.lang.String)
140      */
141     synchronized public void changePassword(String userID, String newPassword) throws IdentityManagerException
142     {
143         if (this.userList.containsKey(userID))
144         {
145             this.userList.get(userID).setPassword(newPassword);
146         }
147     }
148 
149     /**
150      * Will compare a given value to the current one.<br/>
151      * Supports partial matches by adding "%" or "*" before and/or after the attribute value
152      * 
153      * @param value
154      *            the original value to test
155      * @param compareValue
156      *            the value to compare
157      * @return T if the compare value matches
158      */
159     private boolean compareAttribute(String value, String compareValue)
160     {
161         if (value == null || compareValue == null)
162             return false;
163         else
164         {
165             boolean wildCardAtstart = compareValue.startsWith("%") || compareValue.startsWith("*");
166             boolean wildCardAtEnd = compareValue.endsWith("%") || compareValue.endsWith("*");
167 
168             if (wildCardAtstart && wildCardAtEnd)
169                 return value.contains(compareValue);
170             else if (wildCardAtstart && !wildCardAtEnd)
171                 return value.endsWith(compareValue);
172             else if (!wildCardAtstart && wildCardAtEnd)
173                 return value.startsWith(compareValue);
174             else
175                 return value.equals(compareValue);
176         }
177     }
178 
179     /**
180      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#countAllGroups()
181      */
182     public int countAllGroups() throws IdentityManagerException
183     {
184         return this.groupList.values().size();
185     }
186 
187     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#countAllGroupsOfUser(String) */
188     public int countAllGroupsOfUser(String userId) throws IdentityManagerException
189     {
190         return this.getUserGroups(userId).size();
191     }
192 
193     /**
194      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#countAllUsers()
195      */
196     public int countAllUsers() throws IdentityManagerException
197     {
198         return this.userList.values().size();
199     }
200 
201     /**
202      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#countAllUsers(java.lang.String)
203      */
204     public int countAllUsers(String groupID) throws IdentityManagerException
205     {
206         return getUserIDsInGroup(groupID).size();
207     }
208 
209     /**
210      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#countUsers(java.util.Map)
211      */
212     public int countUsers(Map<String, String> attributes) throws IdentityManagerException
213     {
214         return this.getUsersByAttributes(attributes).size();
215     }
216 
217     /**
218      * @see pt.digitalis.dif.controller.security.managers.impl.AbstractIdentityManager#gatherManagedAttributes()
219      */
220     @Override
221     public List<String> gatherManagedAttributes()
222     {
223         return new ArrayList<String>();
224     }
225 
226     /**
227      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getAllGroups()
228      */
229     public Set<IDIFGroup> getAllGroups()
230     {
231         Set<IDIFGroup> result = new HashSet<IDIFGroup>();
232         for (IDIFGroup g: this.groupList.values())
233             result.add(g.cloneGroup());
234         return result;
235     }
236 
237     /**
238      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getAllUsers()
239      */
240     public Set<IDIFUser> getAllUsers()
241     {
242         Set<IDIFUser> result = new HashSet<IDIFUser>();
243         for (IDIFClonableUser u: this.userList.values())
244             result.add(u.cloneUser());
245         return result;
246     }
247 
248     /**
249      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getExclusionCharaters()
250      */
251     public String getExclusionCharaters()
252     {
253 
254         return null;
255     }
256 
257     /**
258      * Returns null if the group doesn't exist.
259      * 
260      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getGroup(String)
261      */
262     public IDIFGroup getGroup(String groupID)
263     {
264         IDIFGroup group = this.groupList.get(groupID);
265 
266         if (group != null && !group.equals(N_A))
267             group = group.cloneGroup();
268 
269         return group;
270     }
271 
272     /**
273      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getGroupAttributeName()
274      */
275     public String getGroupAttributeName()
276     {
277         return "group";
278     }
279 
280     /**
281      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getGroupGroups(java.lang.String)
282      */
283     public Map<String, IDIFGroup> getGroupGroups(String parentGroupID) throws IdentityManagerException
284     {
285 
286         Map<String, IDIFGroup> groupsMap = new HashMap<String, IDIFGroup>();
287 
288         for (IDIFGroup group: groupList.values())
289         {
290             if (group.getParentGroupID() != null && group.getParentGroupID().equals(parentGroupID))
291             {
292                 groupsMap.put(group.getID(), group);
293                 groupsMap.putAll(getGroupGroups(group.getID()));
294             }
295         }
296 
297         return groupsMap;
298 
299     }
300 
301     /**
302      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getGroups(Pagination)
303      */
304     public Set<IDIFGroup> getGroups(Pagination page) throws IdentityManagerException
305     {
306         ArrayList<IDIFGroup> groups = new ArrayList<IDIFGroup>(this.groupList.values());
307         HashSet<IDIFGroup> result = new HashSet<IDIFGroup>();
308 
309         for (int i = page.getStartRow(); i < page.getStartRow() + page.getRowsPerPage(); i++)
310         {
311             IDIFGroup grp = groups.get(i);
312             result.add(grp);
313         }
314         return result;
315     }
316 
317     /**
318      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getGroupUsers(java.lang.String)
319      */
320     public Map<String, IDIFUser> getGroupUsers(String groupID)
321     {
322         Map<String, IDIFUser> users = new HashMap<String, IDIFUser>();
323 
324         for (String userID: getUserIDsInGroup(groupID))
325             users.put(userID, getUser(userID));
326 
327         return users;
328     }
329 
330     /**
331      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getMailAttributeName()
332      */
333     public String getMailAttributeName()
334     {
335         return "mail";
336     }
337 
338     /**
339      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getNameAttributeName()
340      */
341     public String getNameAttributeName()
342     {
343         return "name";
344     }
345 
346     /**
347      * Returns null if the user doesn't exist.
348      * 
349      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUser(String)
350      */
351     public IDIFUser getUser(String userID)
352     {
353 
354         IDIFClonableUser user = userList.get(userID);
355 
356         if (user != null)
357             return user.cloneUser();
358         else
359             return null;
360     }
361 
362     /**
363      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUserGroups(java.lang.String)
364      */
365     public Map<String, IDIFGroup> getUserGroups(String userID) throws IdentityManagerException
366     {
367         return getUserGroupsPagination(userID, null);
368     }
369 
370     /**
371      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUserGroupsIDs(java.lang.String)
372      */
373     public Set<String> getUserGroupsIDs(String userID)
374     {
375         Set<String> result = new HashSet<String>();
376         result.addAll(getUserGroupsIDsWithOutProfile(userID));
377         try
378         {
379             String profile = this.userList.get(userID).getProfileID();
380 
381             if (profile != null)
382                 result.add(profile);
383         }
384         catch (IdentityManagerException e)
385         {
386             // Do nothing
387         }
388 
389         return result;
390     }
391 
392     /**
393      * Returns the list of group IDs of a given user
394      * 
395      * @param userID
396      *            the user
397      * @return the list of groups
398      */
399     private Set<String> getUserGroupsIDsWithOutProfile(String userID)
400     {
401         Set<String> result = new HashSet<String>();
402         if (this.userGroups.containsKey(userID))
403         {
404             result.addAll(this.userGroups.get(userID));
405         }
406 
407         return result;
408     }
409 
410     /**
411      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUserGroupsPagination(java.lang.String,
412      *      pt.digitalis.dif.utils.Pagination)
413      */
414     public Map<String, IDIFGroup> getUserGroupsPagination(String userID, Pagination page)
415             throws IdentityManagerException
416     {
417         Map<String, IDIFGroup> result = new HashMap<String, IDIFGroup>();
418 
419         Set<String> groups;
420         if (page != null)
421         {
422             groups = getUserGroupsIDsWithOutProfile(userID);
423         }
424         else
425         {
426             groups = getUserGroupsIDs(userID);
427         }
428 
429         if (page != null)
430         {
431             String[] groupIDs = groups.toArray(new String[0]);
432 
433             for (int i = page.getStartRow(); i < page.getStartRow() + page.getRowsPerPage(); i++)
434             {
435                 if (i < groupIDs.length)
436                 {
437                     result.put(groupIDs[i], getGroup(groupIDs[i]));
438                 }
439                 else
440                 {
441                     break;
442                 }
443             }
444         }
445         else
446         {
447             for (String groupID: groups)
448                 result.put(groupID, getGroup(groupID));
449         }
450         return result;
451     }
452 
453     /**
454      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUserIDsInGroup(java.lang.String)
455      */
456     public Set<String> getUserIDsInGroup(String groupID)
457     {
458         if (this.groupUsers.containsKey(groupID))
459             return this.groupUsers.get(groupID);
460         else
461             return new HashSet<String>();
462     }
463 
464     // /**
465     // * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#addGroupToGroup(java.lang.String,
466     // * java.lang.String)
467     // */
468     // synchronized public void addGroupToGroup(String subGroupID, String groupID) {
469     // if (this.groupList.containsKey(groupID)) {
470     // if (!this.groupGroups.containsKey(groupID))
471     // this.groupGroups.put(groupID, new HashSet<String>());
472     //
473     // this.groupGroups.get(groupID).add(subGroupID);
474     // }
475     // }
476     //
477     // /**
478     // * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getGroupIDsOfGroup(java.lang.String)
479     // */
480     // public Set<String> getGroupIDsOfGroup(String groupID) {
481     // if (this.groupGroups.containsKey(groupID))
482     // return this.groupGroups.get(groupID);
483     // else
484     // return new HashSet<String>();
485     // }
486 
487     // /**
488     // * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getGroupsOfGroup(java.lang.String)
489     // */
490     // public Map<String, IDIFGroup> getGroupsOfGroup(String groupID) {
491     // Map<String, IDIFGroup> groups = new HashMap<String, IDIFGroup>();
492     //
493     // for (String subGroupID : getGroupIDsOfGroup(groupID))
494     // groups.put(subGroupID, getGroup(subGroupID));
495     //
496     // return groups;
497     // }
498 
499     // /**
500     // * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#isGroupInGroup(java.lang.String,
501     // * java.lang.String)
502     // */
503     // public boolean isGroupInGroup(String subGroupID, String groupID) {
504     // if (this.groupGroups.containsKey(groupID))
505     // return this.groupGroups.get(groupID).contains(subGroupID);
506     // else
507     // return false;
508     // }
509 
510     // /**
511     // * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#removeGroupFromGroup(java.lang.String,
512     // * java.lang.String)
513     // */
514     // synchronized public void removeGroupFromGroup(String subGroupID, String groupID) {
515     // if (this.groupGroups.containsKey(groupID)) {
516     // this.groupGroups.get(groupID).remove(subGroupID);
517     // }
518     // }
519 
520     /**
521      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUserLoginAttributeName()
522      */
523     public String getUserLoginAttributeName()
524     {
525         return "id";
526     }
527 
528     /**
529      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUserParentGroupAttributeName()
530      */
531     public String getUserParentGroupAttributeName()
532     {
533         return "profile";
534     }
535 
536     /**
537      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUsers(Pagination)
538      */
539     public Set<IDIFUser> getUsers(Pagination page) throws IdentityManagerException
540     {
541         ArrayList<IDIFUser> users = new ArrayList<IDIFUser>(this.userList.values());
542         HashSet<IDIFUser> result = new HashSet<IDIFUser>();
543 
544         for (int i = page.getStartRow(); i < page.getStartRow() + page.getRowsPerPage(); i++)
545         {
546             IDIFUser usr = users.get(i);
547             result.add(usr);
548         }
549         return result;
550     }
551 
552     /**
553      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUsersByAttribute(java.lang.String,
554      *      java.lang.String)
555      */
556     public Set<IDIFUser> getUsersByAttribute(String attribute, String value) throws IdentityManagerException
557     {
558         Map<String, String> attributes = new HashMap<String, String>();
559         attributes.put(attribute, value);
560 
561         return this.getUsersByAttributes(attributes);
562     }
563 
564     /**
565      * @throws IdentityManagerException
566      *             If the operation cannot be completed.
567      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUsersByAttributes(java.util.Map)
568      */
569     public Set<IDIFUser> getUsersByAttributes(Map<String, String> attributes) throws IdentityManagerException
570     {
571         Set<IDIFUser> result = new HashSet<IDIFUser>();
572         for (IDIFClonableUser u: this.userList.values())
573         {
574             boolean allConditions = true;
575             for (Entry<String, String> attr: attributes.entrySet())
576             {
577                 if (attr.getValue() != null && attr.getKey() != null)
578                 {
579                     if (attr.getKey().equals(this.getUserLoginAttributeName()))
580                         allConditions &= this.compareAttribute(u.getID(), attr.getValue());
581                     if (attr.getKey().equals(this.getMailAttributeName()))
582                         allConditions &= this.compareAttribute(u.getEmail(), attr.getValue());
583                     if (attr.getKey().equals(this.getNameAttributeName()))
584                         allConditions &= this.compareAttribute(u.getName(), attr.getValue());
585                     if (attr.getKey().equals(this.getUserParentGroupAttributeName()))
586                         allConditions &= u.getProfile() != null
587                                 && this.compareAttribute(u.getProfile().getID(), attr.getValue());
588 
589                     if (u.getAttribute(attr.getKey()) != null)
590                         allConditions &= this.compareAttribute(attr.getValue(), u.getAttribute(attr.getKey())
591                                 .toString());
592                 }
593             }
594             if (allConditions)
595                 result.add(u.cloneUser());
596         }
597 
598         return result;
599     }
600 
601     /**
602      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUsersByAttributes(java.util.Map,
603      *      pt.digitalis.dif.utils.Pagination)
604      */
605     public Set<IDIFUser> getUsersByAttributes(Map<String, String> attributes, Pagination page)
606             throws IdentityManagerException
607     {
608         ArrayList<IDIFUser> totalUsers = new ArrayList<IDIFUser>(this.getUsersByAttributes(attributes));
609         Set<IDIFUser> result = new HashSet<IDIFUser>();
610 
611         for (int i = page.getStartRow(); i < page.getStartRow() + page.getRowsPerPage(); i++)
612         {
613             IDIFUser usr = totalUsers.get(i);
614             result.add(usr);
615         }
616         return result;
617     }
618 
619     /**
620      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#getUsersByEmail(java.lang.String)
621      */
622     public Set<IDIFUser> getUsersByEmail(String value) throws IdentityManagerException
623     {
624         Set<IDIFUser> difUsers = new HashSet<IDIFUser>();
625         for (IDIFClonableUser user: userList.values())
626         {
627             if (value.equals(user.getEmail()))
628                 difUsers.add(user.cloneUser());
629         }
630         return difUsers;
631     }
632 
633     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#groupExists(String) */
634     public boolean groupExists(String groupID)
635     {
636         return this.groupList.containsKey(groupID);
637     }
638 
639     /**
640      * Initializes users from custom static file "users.xml"
641      */
642     public void initializeStaticCustomUsers()
643     {
644         if (DIFStartupConfiguration.getDeveloperMode() || DIFStartupConfiguration.getTestingMode()
645                 || DIFStartupConfiguration.getDemoMode())
646         {
647             int userCount = 0;
648             int groupCount = 0;
649 
650             try
651             {
652                 DIFLogger.getLogger().info("Loading \"" + USERS_FILE_NAME + "\"...");
653                 InputStream userStream = Thread.currentThread().getContextClassLoader()
654                         .getResourceAsStream(USERS_FILE_NAME);
655 
656                 if (userStream == null)
657                     DIFLogger.getLogger().info("  => No \"" + USERS_FILE_NAME + "\" found.");
658                 else
659                 {
660                     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
661                     DocumentBuilder db = dbf.newDocumentBuilder();
662                     Document doc = db.parse(userStream);
663                     doc.getDocumentElement().normalize();
664 
665                     // Parse groups
666                     NodeList groups = doc.getElementsByTagName("group");
667                     for (int i = 0; i < groups.getLength(); i++)
668                     {
669                         String groupID = ((Element) groups.item(i)).getChildNodes().item(0).getNodeValue();
670                         addGroupIfNotExists(groupID.trim(), false);
671 
672                         groupCount++;
673                     }
674 
675                     if (groupCount > 0)
676                         DIFLogger.getLogger().info("  => " + groupCount + " group(s) parsed");
677 
678                     // Parse users
679                     NodeList users = doc.getElementsByTagName("user");
680 
681                     for (int i = 0; i < users.getLength(); i++)
682                     {
683                         Node userNode = users.item(i);
684 
685                         if (userNode.getNodeType() == Node.ELEMENT_NODE)
686                         {
687                             Element attribute = (Element) userNode;
688 
689                             // User definition
690                             IDIFUser user = new DIFUserImpl();
691                             user.setID(attribute.getElementsByTagName("username").item(0).getChildNodes().item(0)
692                                     .getNodeValue());
693                             user.setName(user.getID());
694                             user.setPassword(attribute.getElementsByTagName("password").item(0).getChildNodes().item(0)
695                                     .getNodeValue());
696 
697                             // Add user
698                             addUser(user);
699 
700                             // User attributes
701                             String attributes = attribute.getElementsByTagName("attributes").item(0).getChildNodes()
702                                     .item(0).getNodeValue();
703 
704                             if (attributes != null && !"".equals(attributes))
705                             {
706                                 String[] attributeArray = attributes.split(",");
707 
708                                 for (int f = 0; f < attributeArray.length; f++)
709                                 {
710                                     String[] attributeDef = attributeArray[f].split("=");
711                                     user.setAttribute(attributeDef[0].trim(), attributeDef[1].trim());
712                                 }
713                             }
714 
715                             String temp = attribute.getElementsByTagName("profile").item(0).getChildNodes().item(0)
716                                     .getNodeValue();
717 
718                             // Set profile
719                             addGroupIfNotExists(temp, true);
720                             user.setProfileID(temp);
721 
722                             // User groups
723                             String groupString = attribute.getElementsByTagName("groups").item(0).getChildNodes()
724                                     .item(0).getNodeValue();
725 
726                             if (groupString != null && !"".equals(groupString))
727                             {
728                                 String[] groupArray = groupString.split(",");
729 
730                                 for (int f = 0; f < groupArray.length; f++)
731                                 {
732                                     addGroupIfNotExists(groupArray[f].trim(), true);
733                                     addUserToGroup(user.getID(), groupArray[f].trim());
734                                 }
735                             }
736 
737                             updateUser(user, user.getID());
738                         }
739 
740                         userCount++;
741                     }
742 
743                     if (userCount > 0)
744                         DIFLogger.getLogger().info("  => " + userCount + " user(s) parsed");
745                 }
746             }
747             catch (Exception e)
748             {
749                 DIFLogger.getLogger().error("  => Load of static users failed!\n\n");
750                 e.printStackTrace();
751             }
752         }
753     }
754 
755     /**
756      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#isIdentityValid(java.lang.String,
757      *      java.lang.String)
758      */
759     public boolean isIdentityValid(String userID, String suppliedPassword)
760     {
761 
762         IDIFClonableUser user = userList.get(userID);
763 
764         if ((user != null) && suppliedPassword.equals(user.getPassword()))
765             return true;
766         else
767             return false;
768     }
769 
770     /**
771      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#isReadOnly()
772      */
773     public boolean isReadOnly()
774     {
775         return false;
776     }
777 
778     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#isUserInGroup(String, String) */
779     public boolean isUserInGroup(String userID, String groupID)
780     {
781         if (this.groupUsers.containsKey(groupID))
782             return this.groupUsers.get(groupID).contains(userID);
783         else
784             return false;
785     }
786 
787     /**
788      * @see pt.digitalis.dif.controller.security.managers.IIdentityManagerPrivate#persistUserAttribute(java.lang.String,
789      *      java.lang.String, java.lang.Object)
790      */
791     synchronized public void persistUserAttribute(String userID, String attributeID, Object attributeValue)
792             throws IdentityManagerException
793     {
794         // No need since the static implementation has no underlying repository
795     }
796 
797     /**
798      * @see pt.digitalis.dif.controller.security.managers.IIdentityManagerPrivate#persistUserAttributes(java.lang.String,
799      *      java.util.Map)
800      */
801     public void persistUserAttributes(String userID, Map<String, Object> attributes) throws IdentityManagerException
802     {
803         // No need since the static implementation has no underlying repository
804     }
805 
806     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#removeGroup(String) */
807     synchronized public void removeGroup(String groupID)
808     {
809         this.groupList.remove(groupID);
810         this.groupUsers.remove(groupID);
811         authorizationManager.revokeAllAccessFromGroup(groupID);
812     }
813 
814     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#removeUser(String) */
815     synchronized public void removeUser(String userID)
816     {
817         this.userList.remove(userID);
818         this.userGroups.remove(userID);
819         authorizationManager.revokeAllAccessFromUser(userID);
820     }
821 
822     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#removeUserFromGroup(String, String) */
823     synchronized public void removeUserFromGroup(String userID, String groupID)
824     {
825         if (this.groupUsers.containsKey(groupID))
826         {
827             this.groupUsers.get(groupID).remove(userID);
828             this.userGroups.get(userID).remove(groupID);
829         }
830     }
831 
832     /**
833      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#resetIdentityManager()
834      */
835     public void resetIdentityManager()
836     {
837         this.groupGroups.clear();
838         this.groupList.clear();
839         this.groupUsers.clear();
840         this.userGroups.clear();
841         this.userList.clear();
842     }
843 
844     /**
845      * @see java.lang.Object#toString()
846      */
847     @Override
848     public String toString()
849     {
850         ObjectFormatter formatter = new ObjectFormatter();
851         formatter.addItem("User List", userList);
852         formatter.addItem("Group List", groupList);
853 
854         return formatter.getFormatedObject();
855     }
856 
857     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#updateGroup(IDIFGroup) */
858     synchronized public void updateGroup(IDIFGroup existingGroup)
859     {
860         if (this.groupList.containsKey(existingGroup.getID()))
861             // Implementation note: java.util.Map#put(K,V) replaces the V of an existing key, so it can be used for
862             // updates.
863             this.groupList.put(existingGroup.getID(), existingGroup);
864     }
865 
866     /**
867      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#updateUser(pt.digitalis.dif.controller.security.objects.IDIFUser,
868      *      java.lang.String)
869      */
870     synchronized public void updateUser(IDIFUser existingUser, String userID)
871     {
872         if (this.userList.containsKey(userID))
873         {
874 
875             existingUser.cleanCache();
876 
877             // Implementation note: java.util.Map#put(K,V) replaces the V of an existing key, so it can be used for
878             // updates.
879             if (existingUser.getID() != null && !existingUser.getID().equals(userID))
880             {
881                 this.userList.remove(userID);
882                 this.userList.put(existingUser.getID(), (IDIFClonableUser) existingUser);
883 
884                 this.userGroups.put(existingUser.getID(), this.userGroups.get(userID));
885                 this.userGroups.remove(userID);
886 
887             }
888             else
889             {
890                 this.userList.put(userID, (IDIFClonableUser) existingUser);
891             }
892         }
893 
894         existingUser.refresh();
895     }
896 
897     /**
898      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#updateUserAttribute(java.lang.String,
899      *      java.lang.String, java.lang.Object)
900      */
901     synchronized public void updateUserAttribute(String userID, String attributeID, Object attributeValue)
902             throws IdentityManagerException
903     {
904         if (!this.userList.containsKey(userID))
905         {
906             throw new IdentityManagerException("User " + userID + " does not exists on the IdentityManager!! ");
907         }
908         else if (!this.userList.get(userID).containsAttribute(attributeID))
909         {
910             throw new IdentityManagerException("User " + userID + " does not contains the attribute: " + attributeID
911                     + "!");
912         }
913 
914         try
915         {
916             this.userList.get(userID).setAttribute(attributeID, attributeValue);
917         }
918         catch (InternalFrameworkException e)
919         {
920             throw new IdentityManagerException(e);
921         }
922     }
923 
924     /**
925      * @see pt.digitalis.dif.controller.security.managers.IIdentityManager#updateUserAttributes(java.lang.String,
926      *      java.util.Map)
927      */
928     synchronized public void updateUserAttributes(String userID, Map<String, Object> attributes)
929             throws IdentityManagerException
930     {
931         if (!this.userList.containsKey(userID))
932         {
933             throw new IdentityManagerException("User " + userID + " does not exists on the IdentityManager!! ");
934         }
935         try
936         {
937             this.userList.get(userID).setAttributes(attributes);
938         }
939         catch (InternalFrameworkException e)
940         {
941             throw new IdentityManagerException(e);
942         }
943     }
944 
945     /** @see pt.digitalis.dif.controller.security.managers.IIdentityManager#userExists(String) */
946     public boolean userExists(String userID)
947     {
948         if (userID == null)
949             return false;
950         else
951             return this.userList.containsKey(userID);
952     }
953 }