001/**
002 * Copyright 2005-2017 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.location.service.impl;
017
018import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
019
020import java.util.ArrayList;
021import java.util.Collection;
022import java.util.HashMap;
023import java.util.HashSet;
024import java.util.List;
025import java.util.Map;
026import java.util.Properties;
027import java.util.Set;
028
029import org.kuali.rice.core.api.CoreApiServiceLocator;
030import org.kuali.rice.core.api.criteria.Predicate;
031import org.kuali.rice.core.api.criteria.QueryByCriteria;
032import org.kuali.rice.kns.service.KNSServiceLocator;
033import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
034import org.kuali.rice.krad.service.BusinessObjectService;
035import org.kuali.rice.krad.service.impl.ModuleServiceBase;
036import org.kuali.rice.krad.util.KRADConstants;
037import org.kuali.rice.krad.util.UrlFactory;
038import org.kuali.rice.location.api.LocationConstants;
039import org.kuali.rice.location.api.campus.Campus;
040import org.kuali.rice.location.api.campus.CampusService;
041import org.kuali.rice.location.api.country.Country;
042import org.kuali.rice.location.api.country.CountryService;
043import org.kuali.rice.location.api.county.County;
044import org.kuali.rice.location.api.county.CountyService;
045import org.kuali.rice.location.api.postalcode.PostalCode;
046import org.kuali.rice.location.api.postalcode.PostalCodeService;
047import org.kuali.rice.location.api.services.LocationApiServiceLocator;
048import org.kuali.rice.location.api.state.State;
049import org.kuali.rice.location.api.state.StateService;
050import org.kuali.rice.location.framework.campus.CampusEbo;
051import org.kuali.rice.location.framework.country.CountryEbo;
052import org.kuali.rice.location.framework.county.CountyEbo;
053import org.kuali.rice.location.framework.postalcode.PostalCodeEbo;
054import org.kuali.rice.location.framework.state.StateEbo;
055import org.kuali.rice.location.impl.campus.CampusBo;
056import org.kuali.rice.location.impl.country.CountryBo;
057import org.kuali.rice.location.impl.county.CountyBo;
058import org.kuali.rice.location.impl.postalcode.PostalCodeBo;
059import org.kuali.rice.location.impl.state.StateBo;
060
061public class LocationModuleService extends ModuleServiceBase {
062
063    private CampusService campusService;
064    private StateService stateService;
065    private CountryService countryService;
066    private CountyService countyService;
067    private PostalCodeService postalCodeService;
068    private BusinessObjectService businessObjectService;
069
070
071    public <T extends ExternalizableBusinessObject> T getExternalizableBusinessObject(Class<T> businessObjectClass, Map<String, Object> fieldValues) {
072        if(CampusEbo.class.isAssignableFrom(businessObjectClass)){
073            if(isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.CODE)){
074                Campus campus = getCampusService().getCampus((String) fieldValues.get(
075                        LocationConstants.PrimaryKeyConstants.CODE));
076                return (T) CampusBo.from(campus);
077            }
078        } else if(StateEbo.class.isAssignableFrom(businessObjectClass)){
079            if(isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.COUNTRY_CODE)
080                    && isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.CODE)) {
081                State state = getStateService().getState((String) fieldValues.get(
082                        LocationConstants.PrimaryKeyConstants.COUNTRY_CODE), (String) fieldValues.get(
083                        LocationConstants.PrimaryKeyConstants.CODE));
084                return (T) StateBo.from(state);
085            }
086        } else if(CountryEbo.class.isAssignableFrom(businessObjectClass)){
087            if(isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.CODE)) {
088                Country country = getCountryService().getCountry((String) fieldValues.get(
089                        LocationConstants.PrimaryKeyConstants.CODE));
090                return (T) CountryBo.from(country);
091            }
092        } else if (CountyEbo.class.isAssignableFrom(businessObjectClass)) {
093            if (isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.CODE)
094                    && isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.COUNTRY_CODE)
095                    && isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.STATE_CODE)) {
096                County county = getCountyService().getCounty((String) fieldValues.get(
097                        LocationConstants.PrimaryKeyConstants.COUNTRY_CODE), (String) fieldValues.get(
098                        LocationConstants.PrimaryKeyConstants.STATE_CODE), (String) fieldValues.get(
099                        LocationConstants.PrimaryKeyConstants.CODE));
100
101                CountyBo countyBo = CountyBo.from(county);
102
103                if(countyBo !=null) {
104                    // get referenced objects too
105                    StateBo stateBo = StateBo.from(getStateService().getState(countyBo.getCountryCode(), countyBo.getStateCode()));
106                    CountryBo countryBo = CountryBo.from(getCountryService().getCountry(countyBo.getCountryCode()));
107
108                    countyBo.setState(stateBo);
109                    countyBo.setCountry(countryBo);
110
111                    return (T) countyBo;
112                }
113            }
114        } else if (PostalCodeEbo.class.isAssignableFrom(businessObjectClass)) {
115            if (isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.CODE)
116                    && isNonBlankValueForKey(fieldValues, LocationConstants.PrimaryKeyConstants.COUNTRY_CODE)) {
117                PostalCode postalCode = getPostalCodeService().getPostalCode((String) fieldValues.get(
118                        LocationConstants.PrimaryKeyConstants.COUNTRY_CODE), (String) fieldValues.get(
119                        LocationConstants.PrimaryKeyConstants.CODE));
120                return (T)PostalCodeBo.from(postalCode);
121            }
122        }
123        // otherwise, use the default implementation
124        return super.getExternalizableBusinessObject( businessObjectClass, fieldValues );
125    }
126
127    /**
128         * This overridden method ...
129         *
130         * @see org.kuali.rice.krad.service.impl.ModuleServiceBase#getExternalizableBusinessObjectsList(java.lang.Class, java.util.Map)
131         */
132        @SuppressWarnings("unchecked")
133        @Override
134        public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsList(
135                        Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues) {
136
137                if ( StateEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
138            Collection<StateBo> states = getBusinessObjectService().findMatching(StateBo.class, fieldValues);
139            List<StateEbo> stateEbos = new ArrayList<StateEbo>(states.size());
140            for (StateBo state : states) {
141                stateEbos.add(StateBo.from(State.Builder.create(state).build()));
142            }
143            return (List<T>)stateEbos;
144                } else if ( CampusEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
145            Collection<CampusBo> campuses = getBusinessObjectService().findMatching(CampusBo.class, fieldValues);
146            List<CampusEbo> campusEbos = new ArrayList<CampusEbo>(campuses.size());
147            for (CampusBo campus : campuses) {
148                campusEbos.add(CampusBo.from(Campus.Builder.create(campus).build()));
149            }
150            return (List<T>)campusEbos;
151                } else if ( CountryEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
152            Collection<CountryBo> countries = getBusinessObjectService().findMatching(CountryBo.class, fieldValues);
153            List<CountryEbo> countryEbos = new ArrayList<CountryEbo>(countries.size());
154            for (CountryBo country : countries) {
155                countryEbos.add(CountryBo.from(Country.Builder.create(country).build()));
156            }
157            return (List<T>)countryEbos;
158                } else if ( CountyEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
159            Collection<CountyBo> counties = getBusinessObjectService().findMatching(CountyBo.class, fieldValues);
160            List<CountyEbo> countyEbos = new ArrayList<CountyEbo>(counties.size());
161            for (CountyBo county : counties) {
162                countyEbos.add(CountyBo.from(County.Builder.create(county).build()));
163            }
164            return (List<T>)countyEbos;
165                } else if ( PostalCodeEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
166            Collection<PostalCodeBo> postalCodes = getBusinessObjectService().findMatching(PostalCodeBo.class, fieldValues);
167            List<PostalCodeEbo> postalCodeEbos = new ArrayList<PostalCodeEbo>(postalCodes.size());
168            for (PostalCodeBo postalCode : postalCodes) {
169                postalCodeEbos.add(PostalCodeBo.from(PostalCode.Builder.create(postalCode).build()));
170            }
171            return (List<T>)postalCodeEbos;
172                }
173                // otherwise, use the default implementation
174                return super.getExternalizableBusinessObjectsList( externalizableBusinessObjectClass, fieldValues );
175        }
176
177        /***
178         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableBusinessObjectsListForLookup(java.lang.Class, java.util.Map, boolean)
179         */
180        @SuppressWarnings("unchecked")
181        @Override
182        public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsListForLookup(
183                        Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues, boolean unbounded) {
184
185        Map<String, String> searchCriteria = new HashMap<String, String>();
186                        for (Map.Entry<String, Object> fieldValue : fieldValues.entrySet()) {
187                                if (fieldValue.getValue() != null) {
188                                        searchCriteria.put(fieldValue.getKey(), fieldValue.getValue().toString());
189                                }
190                                else {
191                                        searchCriteria.put(fieldValue.getKey(), null);
192                                }
193                        }
194                // for Person objects (which are not real PersistableBOs) pull them through the person service
195                if ( StateEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
196            Collection<StateBo> states = getLookupService().findCollectionBySearchHelper(StateBo.class, searchCriteria,
197                    unbounded);
198            List<StateEbo> stateEbos = new ArrayList<StateEbo>(states.size());
199            for (StateBo state : states) {
200                stateEbos.add(StateBo.from(State.Builder.create(state).build()));
201            }
202            return (List<T>)stateEbos;
203                } else if ( CampusEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
204            Collection<CampusBo> campuses = getLookupService().findCollectionBySearchHelper(CampusBo.class,
205                    searchCriteria, unbounded);
206            List<CampusEbo> campusEbos = new ArrayList<CampusEbo>(campuses.size());
207            for (CampusBo campus : campuses) {
208                campusEbos.add(CampusBo.from(Campus.Builder.create(campus).build()));
209            }
210            return (List<T>)campusEbos;
211                } else if ( CountryEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
212            Collection<CountryBo> countries = getLookupService().findCollectionBySearchHelper(CountryBo.class,
213                    searchCriteria, unbounded);
214            List<CountryEbo> countryEbos = new ArrayList<CountryEbo>(countries.size());
215            for (CountryBo country : countries) {
216                countryEbos.add(CountryBo.from(Country.Builder.create(country).build()));
217            }
218            return (List<T>)countryEbos;
219                } else if ( CountyEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
220            Collection<CountyBo> counties = getLookupService().findCollectionBySearchHelper(CountyBo.class,
221                    searchCriteria, unbounded);
222            List<CountyEbo> countyEbos = new ArrayList<CountyEbo>(counties.size());
223            for (CountyBo county : counties) {
224                countyEbos.add(CountyBo.from(County.Builder.create(county).build()));
225            }
226            return (List<T>)countyEbos;
227                } else if ( PostalCodeEbo.class.isAssignableFrom( externalizableBusinessObjectClass ) ) {
228            Collection<PostalCodeBo> postalCodes = getLookupService().findCollectionBySearchHelper(PostalCodeBo.class,
229                    searchCriteria, unbounded);
230            List<PostalCodeEbo> postalCodeEbos = new ArrayList<PostalCodeEbo>(postalCodes.size());
231            for (PostalCodeBo postalCode : postalCodes) {
232                postalCodeEbos.add(PostalCodeBo.from(PostalCode.Builder.create(postalCode).build()));
233            }
234            return (List<T>)postalCodeEbos;
235                }
236                // otherwise, use the default implementation
237                return super.getExternalizableBusinessObjectsListForLookup(externalizableBusinessObjectClass, fieldValues, unbounded);
238        }
239
240    @Override
241    protected String getInquiryUrl(Class inquiryBusinessObjectClass) {
242        String riceBaseUrl = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
243                KRADConstants.KUALI_RICE_URL_KEY);
244        String inquiryUrl = riceBaseUrl;
245        if (!inquiryUrl.endsWith("/")) {
246            inquiryUrl = inquiryUrl + "/";
247        }
248        return inquiryUrl + KRADConstants.INQUIRY_ACTION;
249    }
250
251    /**
252     * This overridden method ...
253     *
254     * @see org.kuali.rice.krad.service.ModuleService#getExternalizableBusinessObjectLookupUrl(java.lang.Class,
255     *      java.util.Map)
256     */
257    @Deprecated
258    @Override
259    public String getExternalizableBusinessObjectLookupUrl(Class inquiryBusinessObjectClass,
260            Map<String, String> parameters) {
261        Properties urlParameters = new Properties();
262
263        String riceBaseUrl = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
264                KRADConstants.KUALI_RICE_URL_KEY);
265        String lookupUrl = riceBaseUrl;
266        if (!lookupUrl.endsWith("/")) {
267            lookupUrl = lookupUrl + "/";
268        }
269        if (parameters.containsKey(KRADConstants.MULTIPLE_VALUE)) {
270            lookupUrl = lookupUrl + KRADConstants.MULTIPLE_VALUE_LOOKUP_ACTION;
271        } else {
272            lookupUrl = lookupUrl + KRADConstants.LOOKUP_ACTION;
273        }
274        for (String paramName : parameters.keySet()) {
275            urlParameters.put(paramName, parameters.get(paramName));
276        }
277
278        Class clazz = getExternalizableBusinessObjectImplementation(inquiryBusinessObjectClass);
279
280        urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, clazz == null ? "" : clazz.getName());
281
282        return UrlFactory.parameterizeUrl(lookupUrl, urlParameters);
283    }
284
285
286    protected CampusService getCampusService() {
287        if (campusService == null) {
288            campusService = LocationApiServiceLocator.getCampusService();
289        }
290        return campusService;
291    }
292
293    protected StateService getStateService() {
294        if (stateService == null) {
295            stateService = LocationApiServiceLocator.getStateService();
296        }
297        return stateService;
298    }
299
300    protected CountryService getCountryService() {
301        if (countryService == null) {
302            countryService = LocationApiServiceLocator.getCountryService();
303        }
304        return countryService;
305    }
306
307    protected CountyService getCountyService() {
308        if (countyService == null) {
309            countyService = LocationApiServiceLocator.getCountyService();
310        }
311        return countyService;
312    }
313
314    protected PostalCodeService getPostalCodeService() {
315        if (postalCodeService == null) {
316            postalCodeService = LocationApiServiceLocator.getPostalCodeService();
317        }
318        return postalCodeService;
319    }
320
321    private QueryByCriteria toQuery(Map<String,?> fieldValues) {
322        Set<Predicate> preds = new HashSet<Predicate>();
323        for (Map.Entry<String, ?> entry : fieldValues.entrySet()) {
324            preds.add(equal(entry.getKey(), entry.getValue()));
325        }
326        Predicate[] predicates = new Predicate[0];
327        predicates = preds.toArray(predicates);
328        return QueryByCriteria.Builder.fromPredicates(predicates);
329    }
330
331
332    public BusinessObjectService getBusinessObjectService() {
333        if(businessObjectService == null){
334            return KNSServiceLocator.getBusinessObjectService();
335        }
336        return businessObjectService;
337    }
338
339    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
340        this.businessObjectService = businessObjectService;
341    }
342
343}