View Javadoc

1   /*
2    * Copyright (C) 2007 Alf Mikula
3    * 
4    * This file is part of PromoteGo.
5    *
6    * PromoteGo is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * PromoteGo is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with PromoteGo.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.promotego.controllers;
20  
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Map;
26  
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.promotego.api.geocoder.util.DistanceUtil;
31  import org.promotego.beans.Address;
32  import org.promotego.beans.Location;
33  import org.promotego.beans.LocationType;
34  import org.promotego.beans.User;
35  import org.promotego.beans.UserHolder;
36  import org.promotego.dao.interfaces.AddressDao;
37  import org.promotego.dao.interfaces.LocationDao;
38  import org.promotego.dao.interfaces.LocationTypeDao;
39  import org.promotego.editors.BeanIdEditor;
40  import org.promotego.formbackingbeans.RadiusSearchBean;
41  import org.promotego.viewbeans.LocationViewBean;
42  import org.springframework.beans.factory.annotation.Required;
43  import org.springframework.transaction.annotation.Transactional;
44  import org.springframework.validation.BindException;
45  import org.springframework.web.bind.ServletRequestDataBinder;
46  import org.springframework.web.servlet.ModelAndView;
47  import org.springframework.web.servlet.mvc.SimpleFormController;
48  
49  public class LocationSearchController extends SimpleFormController
50  {
51      // TODO support search Radii in miles and kilometers
52      private static int [] s_searchRadii = {1,5,10,25,50,100};
53      
54      private LocationDao m_locationDao;
55      private AddressDao m_addressDao;
56      private LocationTypeDao m_locationTypeDao;
57      private UserHolder m_userHolder;
58      
59      @Transactional
60      @Override
61      public ModelAndView onSubmit(Object command)
62      {
63          RadiusSearchBean searchParams = (RadiusSearchBean)command;
64          assert m_userHolder.getUser() != null : "User object may not be null";
65  
66          Address address = searchParams.getAddress();
67          int searchRadius = searchParams.getMiles();
68          
69          List<Location> locations = m_locationDao.findNear(address.getGeolocation(), searchRadius);
70          
71          List<LocationViewBean> viewLocations = new LinkedList<LocationViewBean>();
72          
73          // Calculate distance for all locations
74          for(Location thisLocation : locations)
75          {
76              LocationViewBean viewLocation = new LocationViewBean();
77              viewLocation.setLocation(thisLocation);
78              double distance = DistanceUtil.calculateDistance(thisLocation.getAddress().getGeolocation(), address.getGeolocation());
79              distance = Math.floor(distance*10+0.5)/10.0;
80              viewLocation.setDistance(distance);
81              viewLocations.add(viewLocation);
82          }
83          
84          // Sort locations by distance
85          Collections.sort(viewLocations);
86          
87          Map<String,Object> myModel = new HashMap<String, Object>();
88          
89          myModel.put("locations", viewLocations);
90          myModel.put("address", address);
91          myModel.put("searchRadius", searchRadius);
92          
93          return new ModelAndView(getSuccessView(), myModel);
94      }
95  
96      @SuppressWarnings("unchecked")
97      @Transactional(readOnly=true)
98      @Override
99      protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors, Map controlModel) throws Exception
100     {
101         Map <String,Object>myControlModel;
102         
103         // Create a new Map, leaving the original untouched.
104         if (controlModel == null)
105         {
106             myControlModel = new HashMap<String,Object>();
107         }
108         else
109         {
110             myControlModel = new HashMap<String,Object>(controlModel);
111         }
112         
113         // Populate location types for filtering functionality
114         List<LocationType> locationTypes = m_locationTypeDao.findAll();
115         Collections.sort(locationTypes);
116         myControlModel.put("locationTypes", locationTypes);
117         
118         // Populate user's addresses for searches near an address
119         User theUser = m_userHolder.getUser();
120         assert theUser != null : "User object may not be null";
121         myControlModel.put("addresses", theUser.getAddresses());
122         
123         // Populate allowed search radii
124         myControlModel.put("searchRadii", s_searchRadii);
125         
126         return super.showForm(request, response, errors, myControlModel);
127     }
128     
129     @Override
130     protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception
131     {
132         binder.registerCustomEditor(LocationType.class, new BeanIdEditor<LocationType>(m_locationTypeDao));
133         binder.registerCustomEditor(Address.class, new BeanIdEditor<Address>(m_addressDao));
134         
135         super.initBinder(request, binder);
136     }
137     
138     @Required
139     public void setUserHolder(UserHolder theUserHolder)
140     {
141         m_userHolder = theUserHolder;
142     }
143     
144     @Required
145     public void setLocationDao(LocationDao locationDao)
146     {
147         m_locationDao = locationDao;
148     }
149 
150     @Required
151     public void setLocationTypeDao(LocationTypeDao locationTypeDao)
152     {
153         m_locationTypeDao = locationTypeDao;
154     }
155 
156     @Required
157     public void setAddressDao(AddressDao addressDao)
158     {
159         m_addressDao = addressDao;
160     }
161 }