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