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                        }
114                } else if(GroupContract.class.isAssignableFrom(businessObjectClass)){
115                        if(fieldValues.containsKey(KimConstants.PrimaryKeyConstants.GROUP_ID)) {
116                Group group = getGroupService().getGroup((String)fieldValues.get(KimConstants.PrimaryKeyConstants.GROUP_ID));
117                                return (T) GroupBo.from(group);
118                        }
119                } else if (EntityEmailTypeEbo.class.isAssignableFrom(businessObjectClass)) {
120            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
121                CodedAttribute codedAttribute = getIdentityService()
122                        .getEmailType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
123                return (T)EntityEmailTypeBo.from(codedAttribute);
124            }
125        } else if (EntityAddressTypeEbo.class.isAssignableFrom(businessObjectClass)) {
126            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
127                CodedAttribute codedAttribute = getIdentityService()
128                        .getAddressType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
129                return (T)EntityAddressTypeBo.from(codedAttribute);
130            }
131        } else if (EntityAffiliationTypeEbo.class.isAssignableFrom(businessObjectClass)) {
132            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
133                EntityAffiliationType codedAttribute = getIdentityService()
134                        .getAffiliationType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
135                return (T)EntityAffiliationTypeBo.from(codedAttribute);
136            }
137        } else if (EntityCitizenshipStatusEbo.class.isAssignableFrom(businessObjectClass)) {
138            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
139                CodedAttribute codedAttribute = getIdentityService()
140                        .getCitizenshipStatus((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
141                return (T)EntityCitizenshipStatusBo.from(codedAttribute);
142            }
143        } else if (EntityEmploymentStatusEbo.class.isAssignableFrom(businessObjectClass)) {
144            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
145                CodedAttribute codedAttribute = getIdentityService()
146                        .getEmploymentStatus((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
147                return (T)EntityEmploymentStatusBo.from(codedAttribute);
148            }
149        }  else if (EntityEmploymentTypeEbo.class.isAssignableFrom(businessObjectClass)) {
150            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
151                CodedAttribute codedAttribute = getIdentityService()
152                        .getEmploymentType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
153                return (T)EntityEmploymentTypeBo.from(codedAttribute);
154            }
155        } else if (EntityNameTypeEbo.class.isAssignableFrom(businessObjectClass)) {
156            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
157                CodedAttribute codedAttribute = getIdentityService()
158                        .getNameType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
159                return (T)EntityNameTypeBo.from(codedAttribute);
160            }
161        } else if (EntityTypeEbo.class.isAssignableFrom(businessObjectClass)) {
162            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
163                CodedAttribute codedAttribute = getIdentityService()
164                        .getEntityType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
165                return (T)EntityTypeBo.from(codedAttribute);
166            }
167        } else if (EntityExternalIdentifierTypeEbo.class.isAssignableFrom(businessObjectClass)) {
168            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
169                EntityExternalIdentifierType codedAttribute = getIdentityService()
170                        .getExternalIdentifierType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
171                return (T)EntityExternalIdentifierTypeBo.from(codedAttribute);
172            }
173        } else if (EntityPhoneTypeEbo.class.isAssignableFrom(businessObjectClass)) {
174            if (fieldValues.containsKey(KimConstants.PrimaryKeyConstants.CODE)) {
175                CodedAttribute codedAttribute = getIdentityService()
176                        .getPhoneType((String) fieldValues.get(KimConstants.PrimaryKeyConstants.CODE));
177                return (T)EntityPhoneTypeBo.from(codedAttribute);
178            }
179        }
180                // otherwise, use the default implementation
181                return super.getExternalizableBusinessObject( businessObjectClass, fieldValues );
182        }
183
184        /**
185         * This overridden method ...
186         *
187         * @see org.kuali.rice.krad.service.impl.ModuleServiceBase#getExternalizableBusinessObjectsList(java.lang.Class, java.util.Map)
188         */
189        @SuppressWarnings("unchecked")
190        @Override
191        public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsList(
192                        Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues) {
193                // for Person objects (which are not real PersistableBOs) pull them through the person service
194
195                if ( Person.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
196                        return (List)getPersonService().findPeople( (Map)fieldValues );
197                }
198        else if ( RoleContract.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
199            List<Role> roles = getKimRoleService().findRoles(toQuery(fieldValues)).getResults();
200            List<RoleEbo> roleEbos = new ArrayList<RoleEbo>(roles.size());
201            for (Role role : roles) {
202                roleEbos.add(RoleBo.from(role));
203            }
204            return (List<T>)roleEbos;
205                } else if ( GroupContract.class.isAssignableFrom(externalizableBusinessObjectClass) ) {
206                        List<Group> groups = getGroupService().findGroups(toQuery(fieldValues)).getResults();
207            List<GroupEbo> groupEbos = new ArrayList<GroupEbo>(groups.size());
208            for (Group group : groups) {
209                groupEbos.add(GroupBo.from(group));
210            }
211            return (List<T>)groupEbos;
212                }
213                // otherwise, use the default implementation
214                return super.getExternalizableBusinessObjectsList( externalizableBusinessObjectClass, fieldValues );
215        }
216
217    private QueryByCriteria toQuery(Map<String,?> fieldValues) {
218        Set<Predicate> preds = new HashSet<Predicate>();
219        for (String key : fieldValues.keySet()) {
220            preds.add(equal(key, fieldValues.get(key)));
221        }
222        Predicate[] predicates = new Predicate[0];
223        predicates = preds.toArray(predicates);
224        return QueryByCriteria.Builder.fromPredicates(predicates);
225    }
226
227        /***
228         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableBusinessObjectsListForLookup(java.lang.Class, java.util.Map, boolean)
229         */
230        @SuppressWarnings("unchecked")
231        @Override
232        public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsListForLookup(
233                        Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues, boolean unbounded) {
234                // for Person objects (which are not real PersistableBOs) pull them through the person service
235                if ( Person.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
236                        return (List)getPersonService().findPeople( (Map)fieldValues, unbounded );
237                } else if ( RoleContract.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
238                        List<Role> roles = getKimRoleService().findRoles(toQuery(fieldValues)).getResults();
239            List<RoleEbo> roleEbos = new ArrayList<RoleEbo>(roles.size());
240            for (Role role : roles) {
241                roleEbos.add(RoleBo.from(role));
242            }
243            return (List<T>)roleEbos;
244                } else if (GroupContract.class.isAssignableFrom( externalizableBusinessObjectClass)) {
245            List<Group> groups = getGroupService().findGroups(toQuery(fieldValues)).getResults();
246            List<GroupEbo> groupEbos = new ArrayList<GroupEbo>(groups.size());
247            for (Group group : groups) {
248                groupEbos.add(GroupBo.from(group));
249            }
250            return (List<T>)groupEbos;
251        }
252                // otherwise, use the default implementation
253                return super.getExternalizableBusinessObjectsListForLookup(externalizableBusinessObjectClass, fieldValues, unbounded);
254        }
255
256        /**
257         * This overridden method ...
258         *
259         * @see org.kuali.rice.krad.service.impl.ModuleServiceBase#listPrimaryKeyFieldNames(java.lang.Class)
260         */
261        @SuppressWarnings("unchecked")
262        @Override
263        public List listPrimaryKeyFieldNames(Class businessObjectInterfaceClass) {
264                // for Person objects (which are not real PersistableBOs) pull them through the person service
265                if ( Person.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
266                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.PRINCIPAL_ID );
267                } else if ( RoleEbo.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
268                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.ROLE_ID );
269                } else if ( GroupEbo.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
270                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.GROUP_ID );
271                } else if ( KimType.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
272                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.KIM_TYPE_ID );
273                } else if ( KimTypeContract.class.isAssignableFrom(businessObjectInterfaceClass)) {
274                        return Collections.singletonList( KimConstants.PrimaryKeyConstants.KIM_TYPE_CODE );
275                }
276
277                // otherwise, use the default implementation
278                return super.listPrimaryKeyFieldNames( businessObjectInterfaceClass );
279        }
280
281        @SuppressWarnings("unchecked")
282        protected PersonService getPersonService() {
283                if ( personService == null ) {
284                        personService = KimApiServiceLocator.getPersonService();
285                }
286                return personService;
287        }
288
289        protected RoleService getKimRoleService() {
290                if ( kimRoleService == null ) {
291                        kimRoleService = KimApiServiceLocator.getRoleService();
292                }
293                return kimRoleService;
294        }
295
296        protected GroupService getGroupService() {
297                if ( groupService == null ) {
298                        groupService = KimApiServiceLocator.getGroupService();
299                }
300                return groupService;
301        }
302
303    protected IdentityService getIdentityService() {
304                if ( identityService == null ) {
305                        identityService = KimApiServiceLocator.getIdentityService();
306                }
307                return identityService;
308        }
309
310        protected KimTypeInfoService getTypeInfoService() {
311                if(kimTypeInfoService == null){
312                        kimTypeInfoService = KimApiServiceLocator.getKimTypeInfoService();
313                }
314                return kimTypeInfoService;
315        }
316
317        protected Properties getUrlParameters(String businessObjectClassAttribute, Map<String, String[]> parameters){
318                Properties urlParameters = new Properties();
319                for (String paramName : parameters.keySet()) {
320                        String[] parameterValues = parameters.get(paramName);
321                        if (parameterValues.length > 0) {
322                                urlParameters.put(paramName, parameterValues[0]);
323                        }
324                }
325                urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObjectClassAttribute);
326                try{
327                        Class inquiryBusinessObjectClass = Class.forName(businessObjectClassAttribute);
328                        if(RoleContract.class.isAssignableFrom(inquiryBusinessObjectClass) ||
329                                        GroupContract.class.isAssignableFrom(inquiryBusinessObjectClass) ||
330                                        Person.class.isAssignableFrom(inquiryBusinessObjectClass)) {
331                        urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.PARAM_MAINTENANCE_VIEW_MODE_INQUIRY);
332                        } else{
333                        urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL);
334                        }
335                } catch(Exception eix){
336                        urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL);
337                }
338        urlParameters.put(KRADConstants.PARAMETER_COMMAND, KewApiConstants.INITIATE_COMMAND);
339                return urlParameters;
340        }
341
342    @Override
343    public boolean isExternalizable(Class boClazz) {
344    if (boClazz == null) {
345        return false;
346    }
347    if(RoleContract.class.isAssignableFrom(boClazz)) {
348        return true;
349    } else if(GroupContract.class.isAssignableFrom(boClazz)) {
350        return true;
351    } else if(Person.class.isAssignableFrom(boClazz)) {
352        return true;
353    }
354    return ExternalizableBusinessObject.class.isAssignableFrom(boClazz);
355    }
356
357        @Override
358        protected String getInquiryUrl(Class inquiryBusinessObjectClass){
359                String inquiryUrl = KimCommonUtilsInternal.getKimBasePath();
360                if (!inquiryUrl.endsWith("/")) {
361                        inquiryUrl = inquiryUrl + "/";
362                }
363                if(RoleContract.class.isAssignableFrom(inquiryBusinessObjectClass)) {
364                        return inquiryUrl + KimConstants.KimUIConstants.KIM_ROLE_INQUIRY_ACTION;
365                } else if(GroupContract.class.isAssignableFrom(inquiryBusinessObjectClass)) {
366                        return inquiryUrl + KimConstants.KimUIConstants.KIM_GROUP_INQUIRY_ACTION;
367                } else if(Person.class.isAssignableFrom(inquiryBusinessObjectClass)) {
368                        return inquiryUrl + KimConstants.KimUIConstants.KIM_PERSON_INQUIRY_ACTION;
369                }
370                return super.getInquiryUrl(inquiryBusinessObjectClass);
371        }
372
373    @Override
374    public List<List<String>> listAlternatePrimaryKeyFieldNames(
375            Class businessObjectInterfaceClass) {
376                if ( Person.class.isAssignableFrom( businessObjectInterfaceClass ) ) {
377            ArrayList<List<String>> retList = new ArrayList<List<String>>();
378            ArrayList<String> keyList = new ArrayList<String>();
379
380            keyList.add("principalName");
381            retList.add(keyList);
382            return retList;
383        }else{
384            return null;
385        }
386
387    }
388    
389    @Override
390    public boolean goToCentralRiceForInquiry() {
391        RunMode runMode = getRunMode(KimApiConstants.Namespaces.MODULE_NAME);
392
393        if (RunMode.EMBEDDED.equals(runMode)) {
394            return true;
395        } else {
396            return false;
397        }
398    }
399}