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.kim.service.impl;
017
018import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
019
020import java.util.ArrayList;
021import java.util.Collections;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Map;
025import java.util.Properties;
026import java.util.Set;
027
028import org.kuali.rice.core.api.config.module.RunMode;
029import org.kuali.rice.core.api.criteria.Predicate;
030import org.kuali.rice.core.api.criteria.QueryByCriteria;
031import org.kuali.rice.kew.api.KewApiConstants;
032import org.kuali.rice.kim.api.KimApiConstants;
033import org.kuali.rice.kim.api.KimConstants;
034import org.kuali.rice.kim.api.group.Group;
035import org.kuali.rice.kim.api.group.GroupContract;
036import org.kuali.rice.kim.api.group.GroupService;
037import org.kuali.rice.kim.api.identity.CodedAttribute;
038import org.kuali.rice.kim.api.identity.IdentityService;
039import org.kuali.rice.kim.api.identity.Person;
040import org.kuali.rice.kim.api.identity.PersonService;
041import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliationType;
042import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifierType;
043import org.kuali.rice.kim.api.role.Role;
044import org.kuali.rice.kim.api.role.RoleContract;
045import org.kuali.rice.kim.api.role.RoleService;
046import org.kuali.rice.kim.api.services.KimApiServiceLocator;
047import org.kuali.rice.kim.api.type.KimType;
048import org.kuali.rice.kim.api.type.KimTypeContract;
049import org.kuali.rice.kim.api.type.KimTypeInfoService;
050import org.kuali.rice.kim.framework.group.GroupEbo;
051import org.kuali.rice.kim.framework.identity.EntityTypeEbo;
052import org.kuali.rice.kim.framework.identity.address.EntityAddressTypeEbo;
053import org.kuali.rice.kim.framework.identity.affiliation.EntityAffiliationTypeEbo;
054import org.kuali.rice.kim.framework.identity.citizenship.EntityCitizenshipStatusEbo;
055import org.kuali.rice.kim.framework.identity.email.EntityEmailTypeEbo;
056import org.kuali.rice.kim.framework.identity.employment.EntityEmploymentStatusEbo;
057import org.kuali.rice.kim.framework.identity.employment.EntityEmploymentTypeEbo;
058import org.kuali.rice.kim.framework.identity.external.EntityExternalIdentifierTypeEbo;
059import org.kuali.rice.kim.framework.identity.name.EntityNameTypeEbo;
060import org.kuali.rice.kim.framework.identity.phone.EntityPhoneTypeEbo;
061import org.kuali.rice.kim.framework.role.RoleEbo;
062import org.kuali.rice.kim.impl.KIMPropertyConstants;
063import org.kuali.rice.kim.impl.group.GroupBo;
064import org.kuali.rice.kim.impl.identity.EntityTypeBo;
065import org.kuali.rice.kim.impl.identity.address.EntityAddressTypeBo;
066import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationTypeBo;
067import org.kuali.rice.kim.impl.identity.citizenship.EntityCitizenshipStatusBo;
068import org.kuali.rice.kim.impl.identity.email.EntityEmailTypeBo;
069import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentStatusBo;
070import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentTypeBo;
071import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierTypeBo;
072import org.kuali.rice.kim.impl.identity.name.EntityNameTypeBo;
073import org.kuali.rice.kim.impl.identity.phone.EntityPhoneTypeBo;
074import org.kuali.rice.kim.impl.role.RoleBo;
075import org.kuali.rice.kim.util.KimCommonUtilsInternal;
076import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
077import org.kuali.rice.krad.service.impl.ModuleServiceBase;
078import org.kuali.rice.krad.util.KRADConstants;
079
080/**
081 * This is a description of what this class does - kellerj don't forget to fill this in.
082 *
083 * @author Kuali Rice Team (rice.collab@kuali.org)
084 *
085 */
086public class KimModuleService extends ModuleServiceBase {
087
088        private PersonService personService;
089        private RoleService kimRoleService;
090        private GroupService groupService;
091    private IdentityService identityService;
092        private KimTypeInfoService kimTypeInfoService;
093
094        /**
095         * This overridden method ...
096         *
097         * @see org.kuali.rice.krad.service.impl.ModuleServiceBase#getExternalizableBusinessObject(java.lang.Class, java.util.Map)
098         */
099        @SuppressWarnings("unchecked")
100        @Override
101        public <T extends ExternalizableBusinessObject> T getExternalizableBusinessObject(Class<T> businessObjectClass, Map<String, Object> fieldValues) {
102                if ( Person.class.isAssignableFrom( businessObjectClass ) ) {
103                        if ( fieldValues.containsKey( KIMPropertyConstants.Person.PRINCIPAL_ID ) ) {
104                                return (T) getPersonService().getPerson( (String)fieldValues.get( KIMPropertyConstants.Person.PRINCIPAL_ID ) );
105                        } else if ( fieldValues.containsKey( KIMPropertyConstants.Person.PRINCIPAL_NAME ) ) {
106                                return (T) getPersonService().getPersonByPrincipalName( (String)fieldValues.get( KIMPropertyConstants.Person.PRINCIPAL_NAME ) );
107                        }
108                        // otherwise, fall through since critieria is not known
109                } else if(RoleContract.class.isAssignableFrom(businessObjectClass)){
110                        if(fieldValues.containsKey(KimConstants.PrimaryKeyConstants.ROLE_ID)){
111                                Role role = getKimRoleService().getRole((String)fieldValues.get(KimConstants.PrimaryKeyConstants.ROLE_ID));
112                                return (T) RoleBo.from(role);
113                        } else if ( fieldValues.containsKey(KimConstants.UniqueKeyConstants.ROLE_NAME )
114                     && fieldValues.containsKey(KimConstants.UniqueKeyConstants.NAMESPACE_CODE ) ) {
115                    Role role = getKimRoleService().getRoleByNamespaceCodeAndName(
116                            (String)fieldValues.get(KimConstants.UniqueKeyConstants.NAMESPACE_CODE )
117                           ,(String)fieldValues.get(KimConstants.UniqueKeyConstants.ROLE_NAME ));
118                    return (T) RoleBo.from(role);
119            }
120                } else if(GroupContract.class.isAssignableFrom(businessObjectClass)){
121                        if(fieldValues.containsKey(KimConstants.PrimaryKeyConstants.GROUP_ID)) {
122                Group group = getGroupService().getGroup((String)fieldValues.get(KimConstants.PrimaryKeyConstants.GROUP_ID));
123                                return (T) GroupBo.from(group);
124                        } else if ( fieldValues.containsKey( KimConstants.UniqueKeyConstants.GROUP_NAME )
125                    && fieldValues.containsKey(KimConstants.UniqueKeyConstants.NAMESPACE_CODE ) ) {
126                Group group = getGroupService().getGroupByNamespaceCodeAndName(
127                        (String)fieldValues.get(KimConstants.UniqueKeyConstants.NAMESPACE_CODE )
128                        ,(String)fieldValues.get(KimConstants.UniqueKeyConstants.GROUP_NAME ));
129                return (T) GroupBo.from(group);
130            }
131                } else if (EntityEmailTypeEbo.class.isAssignableFrom(businessObjectClass)) {
132            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
133                CodedAttribute codedAttribute = getIdentityService()
134                        .getEmailType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
135                return (T)EntityEmailTypeBo.from(codedAttribute);
136            }
137        } else if (EntityAddressTypeEbo.class.isAssignableFrom(businessObjectClass)) {
138            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
139                CodedAttribute codedAttribute = getIdentityService()
140                        .getAddressType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
141                return (T)EntityAddressTypeBo.from(codedAttribute);
142            }
143        } else if (EntityAffiliationTypeEbo.class.isAssignableFrom(businessObjectClass)) {
144            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
145                EntityAffiliationType codedAttribute = getIdentityService()
146                        .getAffiliationType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
147                return (T)EntityAffiliationTypeBo.from(codedAttribute);
148            }
149        } else if (EntityCitizenshipStatusEbo.class.isAssignableFrom(businessObjectClass)) {
150            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
151                CodedAttribute codedAttribute = getIdentityService()
152                        .getCitizenshipStatus((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
153                return (T)EntityCitizenshipStatusBo.from(codedAttribute);
154            }
155        } else if (EntityEmploymentStatusEbo.class.isAssignableFrom(businessObjectClass)) {
156            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
157                CodedAttribute codedAttribute = getIdentityService()
158                        .getEmploymentStatus((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
159                return (T)EntityEmploymentStatusBo.from(codedAttribute);
160            }
161        }  else if (EntityEmploymentTypeEbo.class.isAssignableFrom(businessObjectClass)) {
162            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
163                CodedAttribute codedAttribute = getIdentityService()
164                        .getEmploymentType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
165                return (T)EntityEmploymentTypeBo.from(codedAttribute);
166            }
167        } else if (EntityNameTypeEbo.class.isAssignableFrom(businessObjectClass)) {
168            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
169                CodedAttribute codedAttribute = getIdentityService()
170                        .getNameType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
171                return (T)EntityNameTypeBo.from(codedAttribute);
172            }
173        } else if (EntityTypeEbo.class.isAssignableFrom(businessObjectClass)) {
174            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
175                CodedAttribute codedAttribute = getIdentityService()
176                        .getEntityType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
177                return (T)EntityTypeBo.from(codedAttribute);
178            }
179        } else if (EntityExternalIdentifierTypeEbo.class.isAssignableFrom(businessObjectClass)) {
180            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
181                EntityExternalIdentifierType codedAttribute = getIdentityService()
182                        .getExternalIdentifierType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
183                return (T)EntityExternalIdentifierTypeBo.from(codedAttribute);
184            }
185        } else if (EntityPhoneTypeEbo.class.isAssignableFrom(businessObjectClass)) {
186            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
187                CodedAttribute codedAttribute = getIdentityService()
188                        .getPhoneType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
189                return (T)EntityPhoneTypeBo.from(codedAttribute);
190            }
191        }
192                // otherwise, use the default implementation
193                return super.getExternalizableBusinessObject( businessObjectClass, fieldValues );
194        }
195
196        /**
197         * This overridden method ...
198         *
199         * @see org.kuali.rice.krad.service.impl.ModuleServiceBase#getExternalizableBusinessObjectsList(java.lang.Class, java.util.Map)
200         */
201        @SuppressWarnings("unchecked")
202        @Override
203        public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsList(
204                        Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues) {
205                // for Person objects (which are not real PersistableBOs) pull them through the person service
206
207                if ( Person.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
208                        return (List)getPersonService().findPeople( (Map)fieldValues );
209                }
210        else if ( RoleContract.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
211            List<Role> roles = getKimRoleService().findRoles(toQuery(fieldValues)).getResults();
212            List<RoleEbo> roleEbos = new ArrayList<RoleEbo>(roles.size());
213            for (Role role : roles) {
214                roleEbos.add(RoleBo.from(role));
215            }
216            return (List<T>)roleEbos;
217                } else if ( GroupContract.class.isAssignableFrom(externalizableBusinessObjectClass) ) {
218                        List<Group> groups = getGroupService().findGroups(toQuery(fieldValues)).getResults();
219            List<GroupEbo> groupEbos = new ArrayList<GroupEbo>(groups.size());
220            for (Group group : groups) {
221                groupEbos.add(GroupBo.from(group));
222            }
223            return (List<T>)groupEbos;
224                }
225                // otherwise, use the default implementation
226                return super.getExternalizableBusinessObjectsList( externalizableBusinessObjectClass, fieldValues );
227        }
228
229    private QueryByCriteria toQuery(Map<String,?> fieldValues) {
230        Set<Predicate> preds = new HashSet<Predicate>();
231        for (String key : fieldValues.keySet()) {
232            preds.add(equal(key, fieldValues.get(key)));
233        }
234        Predicate[] predicates = new Predicate[0];
235        predicates = preds.toArray(predicates);
236        return QueryByCriteria.Builder.fromPredicates(predicates);
237    }
238
239        /***
240         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableBusinessObjectsListForLookup(java.lang.Class, java.util.Map, boolean)
241         */
242        @SuppressWarnings("unchecked")
243        @Override
244        public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsListForLookup(
245                        Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues, boolean unbounded) {
246                // for Person objects (which are not real PersistableBOs) pull them through the person service
247                if ( Person.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
248                        return (List)getPersonService().findPeople( (Map)fieldValues, unbounded );
249                } else if ( RoleContract.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
250                        List<Role> roles = getKimRoleService().findRoles(toQuery(fieldValues)).getResults();
251            List<RoleEbo> roleEbos = new ArrayList<RoleEbo>(roles.size());
252            for (Role role : roles) {
253                roleEbos.add(RoleBo.from(role));
254            }
255            return (List<T>)roleEbos;
256                } else if (GroupContract.class.isAssignableFrom( externalizableBusinessObjectClass)) {
257            List<Group> groups = getGroupService().findGroups(toQuery(fieldValues)).getResults();
258            List<GroupEbo> groupEbos = new ArrayList<GroupEbo>(groups.size());
259            for (Group group : groups) {
260                groupEbos.add(GroupBo.from(group));
261            }
262            return (List<T>)groupEbos;
263        }
264                // otherwise, use the default implementation
265                return super.getExternalizableBusinessObjectsListForLookup(externalizableBusinessObjectClass, fieldValues, unbounded);
266        }
267
268        /**
269         * This overridden method ...
270         *
271         * @see org.kuali.rice.krad.service.impl.ModuleServiceBase#listPrimaryKeyFieldNames(java.lang.Class)
272         */
273        @SuppressWarnings("unchecked")
274        @Override
275        public List listPrimaryKeyFieldNames(Class businessObjectInterfaceClass) {
276                // for Person objects (which are not real PersistableBOs) pull them through the person service
277                if ( Person.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
278                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.PRINCIPAL_ID );
279                } else if ( RoleEbo.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
280                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.ROLE_ID );
281                } else if ( GroupEbo.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
282                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.GROUP_ID );
283                } else if ( KimType.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
284                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.KIM_TYPE_ID );
285                } else if ( KimTypeContract.class.isAssignableFrom(businessObjectInterfaceClass)) {
286                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.KIM_TYPE_CODE );
287                }
288
289                // otherwise, use the default implementation
290                return super.listPrimaryKeyFieldNames( businessObjectInterfaceClass );
291        }
292
293        @SuppressWarnings("unchecked")
294        protected PersonService getPersonService() {
295                if ( personService == null ) {
296                        personService = KimApiServiceLocator.getPersonService();
297                }
298                return personService;
299        }
300
301        protected RoleService getKimRoleService() {
302                if ( kimRoleService == null ) {
303                        kimRoleService = KimApiServiceLocator.getRoleService();
304                }
305                return kimRoleService;
306        }
307
308        protected GroupService getGroupService() {
309                if ( groupService == null ) {
310                        groupService = KimApiServiceLocator.getGroupService();
311                }
312                return groupService;
313        }
314
315    protected IdentityService getIdentityService() {
316                if ( identityService == null ) {
317                        identityService = KimApiServiceLocator.getIdentityService();
318                }
319                return identityService;
320        }
321
322        protected KimTypeInfoService getTypeInfoService() {
323                if(kimTypeInfoService == null){
324                        kimTypeInfoService = KimApiServiceLocator.getKimTypeInfoService();
325                }
326                return kimTypeInfoService;
327        }
328
329        protected Properties getUrlParameters(String businessObjectClassAttribute, Map<String, String[]> parameters){
330                Properties urlParameters = new Properties();
331                for (String paramName : parameters.keySet()) {
332                        String[] parameterValues = parameters.get(paramName);
333                        if (parameterValues.length > 0) {
334                                urlParameters.put(paramName, parameterValues[0]);
335                        }
336                }
337                urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObjectClassAttribute);
338                try{
339                        Class inquiryBusinessObjectClass = Class.forName(businessObjectClassAttribute);
340                        if(RoleContract.class.isAssignableFrom(inquiryBusinessObjectClass) ||
341                                        GroupContract.class.isAssignableFrom(inquiryBusinessObjectClass) ||
342                                        Person.class.isAssignableFrom(inquiryBusinessObjectClass)) {
343                        urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.PARAM_MAINTENANCE_VIEW_MODE_INQUIRY);
344                        } else{
345                        urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL);
346                        }
347                } catch(Exception eix){
348                        urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL);
349                }
350        urlParameters.put(KRADConstants.PARAMETER_COMMAND, KewApiConstants.INITIATE_COMMAND);
351                return urlParameters;
352        }
353
354    @Override
355    public boolean isExternalizable(Class boClazz) {
356    if (boClazz == null) {
357        return false;
358    }
359    if(RoleContract.class.isAssignableFrom(boClazz)) {
360        return true;
361    } else if(GroupContract.class.isAssignableFrom(boClazz)) {
362        return true;
363    } else if(Person.class.isAssignableFrom(boClazz)) {
364        return true;
365    }
366    return ExternalizableBusinessObject.class.isAssignableFrom(boClazz);
367    }
368
369        @Override
370        protected String getInquiryUrl(Class inquiryBusinessObjectClass){
371                String inquiryUrl = KimCommonUtilsInternal.getKimBasePath();
372                if (!inquiryUrl.endsWith("/")) {
373                        inquiryUrl = inquiryUrl + "/";
374                }
375                if(RoleContract.class.isAssignableFrom(inquiryBusinessObjectClass)) {
376                        return inquiryUrl + KimConstants.KimUIConstants.KIM_ROLE_INQUIRY_ACTION;
377                } else if(GroupContract.class.isAssignableFrom(inquiryBusinessObjectClass)) {
378                        return inquiryUrl + KimConstants.KimUIConstants.KIM_GROUP_INQUIRY_ACTION;
379                } else if(Person.class.isAssignableFrom(inquiryBusinessObjectClass)) {
380                        return inquiryUrl + KimConstants.KimUIConstants.KIM_PERSON_INQUIRY_ACTION;
381                }
382                return super.getInquiryUrl(inquiryBusinessObjectClass);
383        }
384
385    @Override
386    public List<List<String>> listAlternatePrimaryKeyFieldNames(
387            Class businessObjectInterfaceClass) {
388                if ( Person.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
389            ArrayList<List<String>> retList = new ArrayList<List<String>>();
390            ArrayList<String> keyList = new ArrayList<String>();
391
392            keyList.add( KimConstants.UniqueKeyConstants.PRINCIPAL_NAME);
393            retList.add(keyList);
394            return retList;
395        } else if ( RoleBo.class.isAssignableFrom( businessObjectInterfaceClass)) {
396            ArrayList<List<String>> retList = new ArrayList<List<String>>();
397            ArrayList<String> keyList = new ArrayList<String>();
398
399            keyList.add( KimConstants.UniqueKeyConstants.ROLE_NAME);
400            keyList.add( KimConstants.UniqueKeyConstants.NAMESPACE_CODE);
401            retList.add(keyList);
402            return retList;
403        } else if ( GroupBo.class.isAssignableFrom( businessObjectInterfaceClass) ) {
404            ArrayList<List<String>> retList = new ArrayList<List<String>>();
405            ArrayList<String> keyList = new ArrayList<String>();
406
407            keyList.add( KimConstants.UniqueKeyConstants.GROUP_NAME);
408            keyList.add( KimConstants.UniqueKeyConstants.NAMESPACE_CODE);
409            retList.add(keyList);
410            return retList;
411        } else {
412            return null;
413        }
414
415    }
416    
417    @Override
418    public boolean goToCentralRiceForInquiry() {
419        RunMode runMode = getRunMode(KimApiConstants.Namespaces.MODULE_NAME);
420
421        if (RunMode.EMBEDDED.equals(runMode)) {
422            return true;
423        } else {
424            return false;
425        }
426    }
427}