001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kew.xml;
017
018import org.apache.commons.lang.StringUtils;
019import org.jdom.Document;
020import org.jdom.Element;
021import org.jdom.JDOMException;
022import org.jdom.Namespace;
023import org.kuali.rice.core.api.util.xml.XmlException;
024import org.kuali.rice.core.api.util.xml.XmlHelper;
025import org.kuali.rice.kim.api.identity.CodedAttribute;
026import org.kuali.rice.kim.api.identity.email.EntityEmail;
027import org.kuali.rice.kim.impl.identity.email.EntityEmailBo;
028import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentBo;
029import org.kuali.rice.kim.impl.identity.entity.EntityBo;
030import org.kuali.rice.kim.impl.identity.name.EntityNameBo;
031import org.kuali.rice.kim.impl.identity.principal.PrincipalBo;
032import org.kuali.rice.kim.impl.identity.type.EntityTypeContactInfoBo;
033import org.kuali.rice.krad.service.KRADServiceLocator;
034import org.kuali.rice.krad.service.SequenceAccessorService;
035import org.xml.sax.SAXException;
036
037import javax.xml.parsers.ParserConfigurationException;
038import java.io.IOException;
039import java.io.InputStream;
040import java.util.ArrayList;
041import java.util.Collections;
042import java.util.Iterator;
043import java.util.List;
044
045/**
046 * Parses users from XML.
047 * 
048 * This is really meant for use only in the unit tests and was written to help ease
049 * transition over to KIM.  There are numerous unit tests which took advantage of
050 * the ability to import "users" from XML in KEW.  KIM does not provide XML
051 * import capabilities in the initial implementation so this class provides that.
052 *
053 * @author Kuali Rice Team (rice.collab@kuali.org)
054 *
055 */
056public class UserXmlParser {
057    
058    private static final Namespace NAMESPACE = Namespace.getNamespace("", "ns:workflow/User");
059
060    private static final String USERS_ELEMENT = "users";
061    private static final String USER_ELEMENT = "user";
062    private static final String WORKFLOW_ID_ELEMENT = "workflowId";
063    private static final String AUTHENTICATION_ID_ELEMENT = "authenticationId";
064    private static final String PRINCIPAL_ID_ELEMENT = "principalId";
065    private static final String PRINCIPAL_NAME_ELEMENT = "principalName";
066    private static final String EMPL_ID_ELEMENT = "emplId";
067    private static final String EMAIL_ELEMENT = "emailAddress";
068    private static final String GIVEN_NAME_ELEMENT = "givenName";
069    private static final String LAST_NAME_ELEMENT = "lastName";    
070    private static final String TYPE_ELEMENT = "type";
071    
072    public void parseUsers(InputStream input) throws IOException, XmlException {
073        try {
074            Document doc = XmlHelper.trimSAXXml(input);
075            Element root = doc.getRootElement();
076            parseUsers(root);
077        } catch (JDOMException e) {
078            throw new XmlException("Parse error.", e);
079        } catch (SAXException e){
080            throw new XmlException("Parse error.",e);
081        } catch(ParserConfigurationException e){
082            throw new XmlException("Parse error.",e);
083        }
084    }
085
086    public void parseUsers(Element root) throws XmlException {
087        for (Iterator usersElementIt = root.getChildren(USERS_ELEMENT, NAMESPACE).iterator(); usersElementIt.hasNext();) {
088                Element usersElement = (Element) usersElementIt.next();
089                for (Iterator iterator = usersElement.getChildren(USER_ELEMENT, NAMESPACE).iterator(); iterator.hasNext();) {
090                        Element userElement = (Element) iterator.next();
091                        EntityBo entity = constructEntity(userElement);
092                        constructPrincipal(userElement, entity.getId());
093                }
094        }
095    }
096    
097    protected EntityBo constructEntity(Element userElement) {
098        SequenceAccessorService sas = KRADServiceLocator.getSequenceAccessorService();
099        
100        String firstName = userElement.getChildTextTrim(GIVEN_NAME_ELEMENT, NAMESPACE);
101        String lastName = userElement.getChildTextTrim(LAST_NAME_ELEMENT, NAMESPACE);
102        String emplId = userElement.getChildTextTrim(EMPL_ID_ELEMENT, NAMESPACE);
103        String entityTypeCode = userElement.getChildTextTrim(TYPE_ELEMENT, NAMESPACE);
104        if (StringUtils.isBlank(entityTypeCode)) {
105                entityTypeCode = "PERSON";
106        }
107        
108        Long entityId = sas.getNextAvailableSequenceNumber("KRIM_ENTITY_ID_S", 
109                        EntityEmploymentBo.class);
110        
111        // if they define an empl id, let's set that up
112        EntityEmploymentBo emplInfo = null;
113        if (!StringUtils.isBlank(emplId)) {
114                emplInfo = new EntityEmploymentBo();
115                emplInfo.setActive(true);
116                emplInfo.setEmployeeId(emplId);
117                emplInfo.setPrimary(true);
118                emplInfo.setEntityId("" + entityId);
119                emplInfo.setId(emplId);
120                emplInfo.setEntityAffiliationId(null);
121        }
122        
123        
124                EntityBo entity = new EntityBo();
125                entity.setActive(true);
126                entity.setId("" + entityId);
127                List<EntityEmploymentBo> emplInfos = new ArrayList<EntityEmploymentBo>();
128                if (emplInfo != null) {
129                        emplInfos.add(emplInfo);
130                }
131                entity.setEmploymentInformation(emplInfos);
132                
133                EntityTypeContactInfoBo entityType = new EntityTypeContactInfoBo();
134                //identity.getEntityTypes().add(entityType);
135                entityType.setEntityTypeCode(entityTypeCode);
136                entityType.setEntityId(entity.getId());
137                entityType.setActive(true);
138                entityType.setVersionNumber(new Long(1));
139                String emailAddress = userElement.getChildTextTrim(EMAIL_ELEMENT, NAMESPACE);
140                if (!StringUtils.isBlank(emailAddress)) {
141                        Long emailId = sas.getNextAvailableSequenceNumber(
142                                        "KRIM_ENTITY_EMAIL_ID_S", EntityEmailBo.class);
143                        EntityEmail.Builder email = EntityEmail.Builder.create();
144                        email.setActive(true);
145                        email.setId("" + emailId);
146                        email.setEntityTypeCode(entityTypeCode);
147                        // must be in krim_email_typ_t.email_typ_cd:
148                        email.setEmailType(CodedAttribute.Builder.create("WRK"));
149                        email.setVersionNumber(new Long(1));
150                        email.setEmailAddress(emailAddress);
151                        email.setDefaultValue(true);
152                        email.setEntityId(entity.getId());
153                        List<EntityEmailBo> emailAddresses = new ArrayList<EntityEmailBo>(1);
154                        emailAddresses.add(EntityEmailBo.from(email.build()));
155                        entityType.setEmailAddresses(emailAddresses);
156                        //email = (KimEntityEmailImpl)KRADServiceLocatorInternal.getBusinessObjectService().save(email);
157                }
158                List<EntityTypeContactInfoBo> entityTypes = new ArrayList<EntityTypeContactInfoBo>(1);
159                entityTypes.add(entityType);
160                entity.setEntityTypeContactInfos(entityTypes);
161                
162                if (!StringUtils.isBlank(firstName) || !StringUtils.isBlank(lastName)) {
163                        Long entityNameId = sas.getNextAvailableSequenceNumber(
164                                        "KRIM_ENTITY_NM_ID_S", EntityNameBo.class);
165                        EntityNameBo name = new EntityNameBo();
166                        name.setActive(true);
167                        name.setId("" + entityNameId);
168                        name.setEntityId(entity.getId());
169                        // must be in krim_ent_nm_typ_t.ent_nm_typ_cd
170                        name.setNameCode("PRFR");
171                        name.setFirstName(firstName);
172                        name.setMiddleName("");
173                        name.setLastName(lastName);
174                        name.setDefaultValue(true);
175                        
176                        entity.setNames(Collections.singletonList(name));
177                }
178
179                entity =  KRADServiceLocator.getBusinessObjectService().save(entity);
180                
181                return entity;
182    }
183    
184    protected PrincipalBo constructPrincipal(Element userElement, String entityId) {
185        String principalId = userElement.getChildTextTrim(WORKFLOW_ID_ELEMENT, NAMESPACE);
186        if (principalId == null) {
187                principalId = userElement.getChildTextTrim(PRINCIPAL_ID_ELEMENT, NAMESPACE);
188        }
189        String principalName = userElement.getChildTextTrim(AUTHENTICATION_ID_ELEMENT, NAMESPACE);
190        if (principalName == null) {
191                principalName = userElement.getChildTextTrim(PRINCIPAL_NAME_ELEMENT, NAMESPACE);
192        }
193        
194                PrincipalBo principal = new PrincipalBo();
195                principal.setActive(true);
196                principal.setPrincipalId(principalId);
197                principal.setPrincipalName(principalName);
198                principal.setEntityId(entityId);
199                principal = (PrincipalBo) KRADServiceLocator.getBusinessObjectService().save(principal);
200                
201                return principal;
202    }
203
204}