Coverage Report - org.kuali.rice.kew.xml.GroupXmlParser
 
Classes in this File Line Coverage Branch Coverage Complexity
GroupXmlParser
0%
0/165
0%
0/80
9.571
 
 1  
 /*
 2  
  * Copyright 2007-2008 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kew.xml;
 17  
 
 18  
 import org.jdom.Document;
 19  
 import org.jdom.Element;
 20  
 import org.jdom.JDOMException;
 21  
 import org.kuali.rice.core.api.mo.common.Attributes;
 22  
 import org.kuali.rice.core.util.AttributeSet;
 23  
 import org.kuali.rice.core.util.xml.XmlException;
 24  
 import org.kuali.rice.core.util.xml.XmlHelper;
 25  
 import org.kuali.rice.kew.util.KEWConstants;
 26  
 import org.kuali.rice.kew.util.Utilities;
 27  
 import org.kuali.rice.kim.api.common.attribute.KimAttribute;
 28  
 import org.kuali.rice.kim.api.common.attribute.KimAttributeData;
 29  
 import org.kuali.rice.kim.api.entity.principal.Principal;
 30  
 import org.kuali.rice.kim.api.group.Group;
 31  
 import org.kuali.rice.kim.api.services.IdentityManagementService;
 32  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 33  
 import org.kuali.rice.kim.api.type.KimType;
 34  
 import org.kuali.rice.kim.api.type.KimTypeAttribute;
 35  
 
 36  
 import org.kuali.rice.kim.util.KimConstants;
 37  
 import org.xml.sax.SAXException;
 38  
 
 39  
 import javax.xml.parsers.ParserConfigurationException;
 40  
 import java.io.IOException;
 41  
 import java.io.InputStream;
 42  
 import java.util.ArrayList;
 43  
 import java.util.HashMap;
 44  
 import java.util.List;
 45  
 import java.util.Map;
 46  
 
 47  
 import static org.kuali.rice.core.api.impex.xml.XmlConstants.*;
 48  
 
 49  
 
 50  
 /**
 51  
  * Parses groups from XML.
 52  
  *
 53  
  * @see Group
 54  
  *
 55  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 56  
  *
 57  
  */
 58  0
 public class GroupXmlParser {
 59  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(GroupXmlParser.class);
 60  
     private static final boolean DEFAULT_ACTIVE_VALUE = true;
 61  
     private static final String DEFAULT_GROUP_DESCRIPTION = "";
 62  0
     private HashMap<String, List<String>> memberGroupIds = new HashMap<String, List<String>>();
 63  0
     private HashMap<String, List<String>> memberGroupNames = new HashMap<String, List<String>>();
 64  0
     private HashMap<String, List<String>> memberPrincipalIds = new HashMap<String, List<String>>();
 65  0
     private AttributeSet groupAttributes = new AttributeSet();
 66  
 
 67  
     public List<Group> parseGroups(InputStream input) throws IOException, XmlException {
 68  
         try {
 69  0
             Document doc = XmlHelper.trimSAXXml(input);
 70  0
             Element root = doc.getRootElement();
 71  0
             return parseGroups(root);
 72  0
         } catch (JDOMException e) {
 73  0
             throw new XmlException("Parse error.", e);
 74  0
         } catch (SAXException e){
 75  0
             throw new XmlException("Parse error.",e);
 76  0
         } catch(ParserConfigurationException e){
 77  0
             throw new XmlException("Parse error.",e);
 78  
         }
 79  
     }
 80  
 
 81  
 
 82  
     /**
 83  
      * Parses and saves groups
 84  
      * @param element top-level 'data' element which should contain a <groups> child element
 85  
      * @return a list of parsed and saved, current, groups;
 86  
      * @throws XmlException
 87  
      */
 88  
     @SuppressWarnings("unchecked")
 89  
         public List<Group> parseGroups(Element element) throws XmlException {
 90  0
         List<Group> groups = new ArrayList<Group>();
 91  0
         for (Element groupsElement: (List<Element>) element.getChildren(GROUPS, GROUP_NAMESPACE)) {
 92  
 
 93  0
             for (Element groupElement: (List<Element>) groupsElement.getChildren(GROUP, GROUP_NAMESPACE)) {
 94  0
                 groups.add(parseGroup(groupElement));
 95  
             }
 96  
         }
 97  0
         for (Group group : groups) {
 98  0
             IdentityManagementService identityManagementService = KimApiServiceLocator.getIdentityManagementService();
 99  
 
 100  
             // check if group already exists
 101  0
             Group foundGroup = identityManagementService.getGroupByName(group.getNamespaceCode(), group.getName());
 102  
 
 103  0
             if (foundGroup == null) {
 104  0
                 if ( LOG.isInfoEnabled() ) {
 105  0
                         LOG.info("Group named '" + group.getName() + "' not found, creating new group named '" + group.getName() + "'");
 106  
                 }
 107  
                 try {
 108  0
                     Group newGroup =  identityManagementService.createGroup(group);
 109  
 
 110  0
                     String key = newGroup.getNamespaceCode().trim() + KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER + newGroup.getName().trim();
 111  0
                     addGroupMembers(newGroup, key);
 112  0
                 } catch (Exception e) {
 113  0
                     throw new RuntimeException("Error creating group with name '" + group.getName() + "'", e);
 114  0
                 }
 115  
             } else {
 116  0
                     if ( LOG.isInfoEnabled() ) {
 117  0
                             LOG.info("Group named '" + group.getName() + "' found, creating a new version");
 118  
                     }
 119  
                 try {
 120  0
                     Group.Builder builder = Group.Builder.create(foundGroup);
 121  0
                     builder.setActive(group.isActive());
 122  0
                     builder.setDescription(group.getDescription());
 123  0
                     builder.setKimTypeId(group.getKimTypeId());
 124  
 
 125  
                     //builder.setVersionNumber(foundGroup.getVersionNumber());
 126  0
                     group = builder.build();
 127  0
                     identityManagementService.updateGroup(foundGroup.getId(), group);
 128  
 
 129  
                     //delete existing group members and replace with new
 130  0
                     identityManagementService.removeAllMembers(foundGroup.getId());
 131  
 
 132  0
                     String key = group.getNamespaceCode().trim() + KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER + group.getName().trim();
 133  0
                     addGroupMembers(group, key);
 134  
 
 135  0
                 } catch (Exception e) {
 136  0
                     throw new RuntimeException("Error updating group.", e);
 137  0
                 }
 138  
             }
 139  0
         }
 140  0
         return groups;
 141  
     }
 142  
 
 143  
     @SuppressWarnings("unchecked")
 144  
         private Group parseGroup(Element element) throws XmlException {
 145  
 
 146  
 
 147  
         // Type element and children (namespace and name)
 148  
 
 149  0
         String typeId = null;
 150  
         KimType kimTypeInfo;
 151  0
         List<KimTypeAttribute> kimTypeAttributes = new ArrayList<KimTypeAttribute>();
 152  0
         if (element.getChild(TYPE, GROUP_NAMESPACE) != null) {
 153  0
             Element typeElement = element.getChild(TYPE, GROUP_NAMESPACE);
 154  0
             String typeNamespace = typeElement.getChildText(NAMESPACE, GROUP_NAMESPACE);
 155  0
             String typeName = typeElement.getChildText(NAME, GROUP_NAMESPACE);
 156  0
             kimTypeInfo = KimApiServiceLocator.getKimTypeInfoService().findKimTypeByNameAndNamespace(typeNamespace, typeName);
 157  0
             if (kimTypeInfo != null) {
 158  0
                     typeId = kimTypeInfo.getId();
 159  0
                 kimTypeAttributes = kimTypeInfo.getAttributeDefinitions();
 160  
             } else  {
 161  0
                 throw new XmlException("Invalid type name and namespace specified.");
 162  
             }
 163  0
         } else { //set to default type
 164  0
             kimTypeInfo = KimApiServiceLocator.getKimTypeInfoService().findKimTypeByNameAndNamespace(KimConstants.KIM_TYPE_DEFAULT_NAMESPACE, KimConstants.KIM_TYPE_DEFAULT_NAME);
 165  0
             if (kimTypeInfo != null) {
 166  0
                     typeId = kimTypeInfo.getId();
 167  0
                 kimTypeAttributes = kimTypeInfo.getAttributeDefinitions();
 168  
             } else {
 169  0
                     throw new RuntimeException("Failed to locate the 'Default' group type!  Please ensure that it's in your database.");
 170  
             }
 171  
         }
 172  
         //groupInfo.setKimTypeId(typeId);
 173  
 
 174  0
         String groupNamespace = element.getChildText(NAMESPACE, GROUP_NAMESPACE);
 175  0
         if (groupNamespace == null) {
 176  0
             throw new XmlException("Namespace must have a value.");
 177  
         }
 178  
 
 179  0
         String groupName = element.getChildText(NAME, GROUP_NAMESPACE);
 180  0
         if (groupName == null) {
 181  0
             throw new XmlException("Name must have a value.");
 182  
         }
 183  
 
 184  0
         Group.Builder groupInfo = Group.Builder.create(groupNamespace, groupName, typeId);
 185  0
         IdentityManagementService identityManagementService = KimApiServiceLocator.getIdentityManagementService();
 186  
         //groupInfo.setGroupName(element.getChildText(NAME, GROUP_NAMESPACE));
 187  
 
 188  0
         String id = element.getChildText(ID, GROUP_NAMESPACE);
 189  0
         if (id != null) {
 190  0
             groupInfo.setId(id.trim());
 191  
         } else {
 192  
                 
 193  
         }
 194  
 
 195  0
         String description = element.getChildText(DESCRIPTION, GROUP_NAMESPACE);
 196  0
         if (description != null && !description.trim().equals("")) {
 197  0
             groupInfo.setDescription(description);
 198  
         }
 199  
 
 200  
         //Active Indicator
 201  0
         groupInfo.setActive(DEFAULT_ACTIVE_VALUE);
 202  0
         if (element.getChildText(ACTIVE, GROUP_NAMESPACE) != null) {
 203  0
             String active = element.getChildText(ACTIVE, GROUP_NAMESPACE).trim();
 204  0
             if (active.toUpperCase().equals("N") || active.toUpperCase().equals("FALSE")) {
 205  0
                 groupInfo.setActive(false);
 206  
             }
 207  
         }
 208  
 
 209  
         //Get list of attribute keys
 210  0
         List<String> validAttributeKeys = new ArrayList<String>();
 211  0
         for (KimTypeAttribute attribute : kimTypeAttributes) {
 212  0
             validAttributeKeys.add(attribute.getKimAttribute().getAttributeName());
 213  
         }
 214  
         //Group attributes
 215  0
         if (element.getChild(ATTRIBUTES, GROUP_NAMESPACE) != null) {
 216  0
             List<Element> attributes = element.getChild(ATTRIBUTES, GROUP_NAMESPACE).getChildren();
 217  
 
 218  0
             Map<String, String> attrMap = new HashMap<String, String>();
 219  0
             for (Element attr : attributes ) {
 220  0
                 attrMap.put(attr.getAttributeValue(KEY), attr.getAttributeValue(VALUE));
 221  0
                 if (!validAttributeKeys.contains(attr.getAttributeValue(KEY))) {
 222  0
                     throw new XmlException("Invalid attribute specified.");
 223  
                 }
 224  
             }
 225  0
             Attributes groupAttributes = Attributes.fromMap(attrMap);
 226  0
             if (!groupAttributes.isEmpty()) {
 227  0
                 groupInfo.setAttributes(groupAttributes);
 228  
             }
 229  
         }
 230  
 
 231  
         //Group members
 232  
 
 233  0
         List<Element> members = element.getChild(MEMBERS, GROUP_NAMESPACE).getChildren();
 234  0
         for (Element member : members) {
 235  0
             String elementName = member.getName().trim();
 236  0
             if (elementName.equals(PRINCIPAL_NAME)) {
 237  0
                 String principalName = member.getText().trim();
 238  0
                 Principal principal = identityManagementService.getPrincipalByPrincipalName(principalName);
 239  0
                 if (principal != null) {
 240  0
                     addPrincipalToGroup(groupInfo.getNamespaceCode(), groupInfo.getName(), principal.getPrincipalId());
 241  
                 } else {
 242  0
                     throw new XmlException("Principal Name "+principalName+" cannot be found.");
 243  
                 }
 244  0
             } else if (elementName.equals(PRINCIPAL_ID)) {
 245  0
                 String xmlPrincipalId = member.getText().trim();
 246  0
                 Principal principal = identityManagementService.getPrincipal(xmlPrincipalId);
 247  0
                 if (principal != null) {
 248  0
                     addPrincipalToGroup(groupInfo.getNamespaceCode(), groupInfo.getName(), principal.getPrincipalId());
 249  
                 } else {
 250  0
                     throw new XmlException("Principal Id "+xmlPrincipalId+" cannot be found.");
 251  
                 }
 252  
             // Groups are handled differently since the member group may not be saved yet.  Therefore they need to be validated after the groups are saved.
 253  0
             } else if (elementName.equals(GROUP_ID)) {
 254  0
                 String xmlGroupId = member.getText().trim();
 255  0
                 addGroupToGroup(groupInfo.getNamespaceCode(), groupInfo.getName(), xmlGroupId);
 256  0
             } else if (elementName.equals(GROUP_NAME)) {
 257  0
                 String xmlGroupName = member.getChildText(NAME, GROUP_NAMESPACE).trim();
 258  0
                 String xmlGroupNamespace = member.getChildText(NAMESPACE, GROUP_NAMESPACE).trim();
 259  0
                 addGroupNameToGroup(groupInfo.getNamespaceCode(), groupInfo.getName(), xmlGroupNamespace, xmlGroupName);
 260  0
             } else {
 261  0
                 LOG.error("Unknown member element: " + elementName);
 262  
             }
 263  
 
 264  
 
 265  0
         }
 266  
 
 267  0
         return groupInfo.build();
 268  
 
 269  
     }
 270  
 
 271  
     private void addPrincipalToGroup(String groupNamespace, String groupName, String principalId) {
 272  0
         String key = groupNamespace.trim() + KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER + groupName.trim();
 273  0
         List<String> principalIds = memberPrincipalIds.get(key);
 274  0
         if (principalIds == null) {
 275  0
             principalIds = new ArrayList<String>();
 276  
         }
 277  0
         principalIds.add(principalId);
 278  0
         memberPrincipalIds.put(key, principalIds);
 279  0
     }
 280  
 
 281  
     private void addGroupToGroup(String groupNamespace, String groupName, String groupId) {
 282  0
         String key = groupNamespace.trim() + KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER + groupName.trim();
 283  0
         List<String> groupIds = memberGroupIds.get(key);
 284  0
         if (groupIds == null) {
 285  0
             groupIds = new ArrayList<String>();
 286  
         }
 287  0
         groupIds.add(groupId);
 288  0
         memberGroupIds.put(key, groupIds);
 289  0
     }
 290  
 
 291  
     private void addGroupNameToGroup(String groupNamespace, String groupName, String memberGroupNamespace, String memberGroupName) {
 292  0
         String key = groupNamespace.trim() + KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER + groupName.trim();
 293  0
         List<String> groupNames = memberGroupNames.get(key);
 294  0
         if (groupNames == null) {
 295  0
             groupNames = new ArrayList<String>();
 296  
         }
 297  0
         groupNames.add(memberGroupNamespace.trim() + KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER + memberGroupName.trim());
 298  0
         memberGroupNames.put(key, groupNames);
 299  0
     }
 300  
 
 301  
     private void addGroupMembers(Group groupInfo, String key) throws XmlException {
 302  0
         IdentityManagementService identityManagementService = KimApiServiceLocator.getIdentityManagementService();
 303  0
         List<String> groupIds = memberGroupIds.get(key);
 304  0
         if (groupIds != null) {
 305  0
             for (String groupId : groupIds) {
 306  0
                 Group group = identityManagementService.getGroup(groupId);
 307  0
                 if (group != null) {
 308  0
                     identityManagementService.addGroupToGroup(group.getId(), groupInfo.getId());
 309  
                     //TODO HACK!!!!!!! Use IDMService.addPrincipalToGroup
 310  
                     /*GroupMemberBo groupMember = new GroupMemberBo();
 311  
                     groupMember.setGroupId(groupInfo.getId());
 312  
                     groupMember.setTypeCode( KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE );
 313  
                     groupMember.setMemberId(group.getId());*/
 314  
 
 315  
                     /*groupMember = (GroupMemberBo)KNSServiceLocator.getBusinessObjectService().save(groupMember);*/
 316  
                 } else {
 317  0
                     throw new XmlException("Group Id "+groupId+" cannot be found.");
 318  
                 }
 319  0
             }
 320  
         }
 321  0
         List<String> groupNames = memberGroupNames.get(key);
 322  0
         if (groupNames != null) {
 323  0
             for (String groupName : groupNames) {
 324  0
                 Group group = identityManagementService.getGroupByName(Utilities.parseGroupNamespaceCode(groupName), Utilities.parseGroupName(groupName));
 325  0
                 if (group != null) {
 326  
                     //TODO HACK!!!!!!! Use IDMService.addPrincipalToGroup
 327  
                     /*GroupMemberBo groupMember = new GroupMemberBo();
 328  
                     groupMember.setGroupId(groupInfo.getId());
 329  
                     groupMember.setTypeCode( KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE );
 330  
                     groupMember.setMemberId(group.getId());
 331  
 
 332  
                     groupMember = (GroupMemberBo)KNSServiceLocator.getBusinessObjectService().save(groupMember);*/
 333  0
                         identityManagementService.addGroupToGroup(group.getId(), groupInfo.getId());
 334  
                 } else {
 335  0
                     throw new XmlException("Group "+groupName+" cannot be found.");
 336  
                 }
 337  0
             }
 338  
         }
 339  0
         List<String> principalIds = memberPrincipalIds.get(key);
 340  0
         if (principalIds != null) {
 341  0
             for (String principalId : principalIds) {
 342  
                 //TODO HACK!!!!!!! Use IDMService.addPrincipalToGroup
 343  
                 /*GroupMemberBo groupMember = new GroupMemberBo();
 344  
                 groupMember.setGroupId(groupInfo.getId());
 345  
                 groupMember.setTypeCode(KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
 346  
                 groupMember.setMemberId(principalId);
 347  
 
 348  
                 groupMember = (GroupMemberBo)KNSServiceLocator.getBusinessObjectService().save(groupMember);*/
 349  
 
 350  0
                     identityManagementService.addPrincipalToGroup(principalId, groupInfo.getId());
 351  
             }
 352  
         }
 353  
 
 354  0
     }
 355  
 }