001/**
002 * Copyright 2011-2013 The Kuali Foundation Licensed under the Educational
003 * Community License, Version 2.0 (the "License"); you may not use this file
004 * except in compliance with the License. You may obtain a copy of the License
005 * at
006 *
007 * http://www.osedu.org/licenses/ECL-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software
010 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
011 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
012 * License for the specific language governing permissions and limitations under
013 * the License.
014 */
015package org.kuali.mobility.academics.controllers;
016
017import java.util.ArrayList;
018import java.util.Arrays;
019import java.util.Iterator;
020import java.util.List;
021import java.util.Map;
022import java.util.Properties;
023
024import javax.servlet.http.HttpServletRequest;
025import javax.servlet.http.HttpSession;
026import org.apache.commons.collections.CollectionUtils;
027
028import org.apache.log4j.Logger;
029import org.kuali.mobility.academics.entity.Career;
030import org.kuali.mobility.academics.entity.CatalogNumber;
031import org.kuali.mobility.academics.entity.SearchResult;
032import org.kuali.mobility.academics.entity.Section;
033import org.kuali.mobility.academics.entity.Subject;
034import org.kuali.mobility.academics.entity.Term;
035import org.kuali.mobility.academics.service.AcademicsService;
036import org.kuali.mobility.academics.util.AcademicsConstants;
037import org.kuali.mobility.academics.util.CareerPredicate;
038import org.kuali.mobility.academics.util.CatalogNumberPredicate;
039import org.kuali.mobility.academics.util.SubjectPredicate;
040import org.springframework.beans.factory.annotation.Autowired;
041import org.springframework.beans.factory.annotation.Qualifier;
042import org.springframework.stereotype.Controller;
043import org.springframework.ui.Model;
044import org.springframework.web.bind.annotation.RequestMapping;
045import org.springframework.web.bind.annotation.RequestMethod;
046import org.springframework.web.bind.annotation.RequestParam;
047
048@Controller
049@RequestMapping("/academics")
050public class AcademicsControllerImpl {
051
052        private static final Logger LOG = Logger.getLogger(AcademicsControllerImpl.class);
053        @Autowired
054        @Qualifier("academicsService")
055        private AcademicsService service;
056
057        @Autowired
058        @Qualifier("academicsProperties")
059        private Properties academicsProperties;
060
061        @RequestMapping(method = RequestMethod.GET)
062        public String index(HttpServletRequest request, Model uiModel) {
063                HttpSession session = request.getSession();
064                session.removeAttribute("currentTerm");
065                session.removeAttribute("currentCareer");
066                session.removeAttribute("currentSection");
067                session.removeAttribute("currentCatalogNumber");
068                session.removeAttribute("sectionsAll");
069                session.removeAttribute(AcademicsConstants.TERM_ID);
070                session.removeAttribute(AcademicsConstants.TERM);
071                session.removeAttribute(AcademicsConstants.CAREER_ID);
072                session.removeAttribute(AcademicsConstants.CAREER);
073                session.removeAttribute(AcademicsConstants.SUBJECT_ID);
074                session.removeAttribute(AcademicsConstants.SUBJECT);
075                session.removeAttribute(AcademicsConstants.CATALOG_NUMBER);
076                session.removeAttribute(AcademicsConstants.CATALOG_DESCRIPTION);
077                session.removeAttribute(AcademicsConstants.CLASS_NUMBER);
078                session.removeAttribute(AcademicsConstants.CLASS_SECTION);
079                session.removeAttribute(AcademicsConstants.COURSE_ID);
080                session.removeAttribute(AcademicsConstants.COURSE_OFFER_NBR);
081                session.removeAttribute(AcademicsConstants.SECTIONS);
082                session.removeAttribute(AcademicsConstants.TERM_DESCRIPTION);
083
084                uiModel.addAttribute( AcademicsConstants.HOME_SCREEN_TOOLS, this.getHomeScreenOrder() );
085
086                return "academics/index";
087        }
088
089        @RequestMapping(value = "/terms")
090        public String getTerms(HttpServletRequest request, Model uiModel) {
091                HttpSession session = request.getSession();
092
093                session.setAttribute(AcademicsConstants.TERM, getService().getTerms());
094
095                //uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/");
096                return "academics/terms";
097        }
098
099        @RequestMapping(value = "/careers")
100        public String getCareers(HttpServletRequest request, Model uiModel,
101                        @RequestParam(required = true) final String termId) {
102                HttpSession session = request.getSession();
103                if (termId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.TERM_ID))) {
104                        // use cached data
105                        uiModel.addAttribute(AcademicsConstants.TITLE, ((Term)session.getAttribute("currentTerm")).getDescription());
106                } else {
107                        Term term = getService().getTerm(termId);
108                        session.setAttribute(AcademicsConstants.TERM_ID, termId);
109                        session.setAttribute("currentTerm", term);
110                        List<? extends Career> lCareers = getService().getCareers(termId);
111                        session.setAttribute(AcademicsConstants.CAREER, lCareers);
112                        session.setAttribute("watermark", "Search " + term.getDescription() + " Classes");
113                        uiModel.addAttribute(AcademicsConstants.TITLE, ((Term)session.getAttribute("currentTerm")).getDescription());
114                }
115
116                //uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/terms");
117                return "academics/careers";
118        }
119
120        @RequestMapping(value = "/subjects")
121        public String getCareers(HttpServletRequest request, Model uiModel,
122                        @RequestParam(required = true) final String termId,
123                        @RequestParam(required = true) final String careerId) {
124                HttpSession session = request.getSession();
125                if (termId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.TERM_ID))
126                                && careerId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CAREER_ID))) {
127                        // Use cached data.
128//                      uiModel.addAttribute(AcademicsConstants.TITLE, ((Career)session.getAttribute("currentCareer")).getShortDescription());
129                        uiModel.addAttribute(AcademicsConstants.TITLE, "Subjects" );
130                } else {
131                        Term term = getService().getTerm(termId);
132                        session.setAttribute(AcademicsConstants.TERM_ID, term.getId());
133                        session.setAttribute("currentTerm", term);
134
135                        session.setAttribute(AcademicsConstants.CAREER_ID, careerId);
136                        Career career = (Career) CollectionUtils.find((List<Career>) session.getAttribute(AcademicsConstants.CAREER), new CareerPredicate(careerId));
137                        session.setAttribute("currentCareer", career);
138
139                        List<? extends Subject> lSubjects = getService().getSubjects(termId, careerId);
140                        session.setAttribute(AcademicsConstants.SUBJECT, lSubjects);
141//                      uiModel.addAttribute(AcademicsConstants.TITLE, ((Career)session.getAttribute("currentCareer")).getShortDescription());
142                        uiModel.addAttribute(AcademicsConstants.TITLE, "Subjects" );
143                }
144                //uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/careers?termId=" + session.getAttribute(AcademicsConstants.TERM_ID));
145                return "academics/subjects";
146        }
147
148        @RequestMapping(value = "/catalogNumbers")
149        public String getCareers(HttpServletRequest request, Model uiModel,
150                        @RequestParam(required = true)
151                        final String termId,
152                        @RequestParam(required = true)
153                        final String careerId,
154                        @RequestParam(required = true)
155                        final String subjectId) {
156                HttpSession session = request.getSession();
157                if (termId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.TERM_ID))
158                                && careerId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CAREER_ID))
159                                && subjectId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.SUBJECT_ID))) {
160                        // Use cached data.
161                        uiModel.addAttribute(AcademicsConstants.TITLE, ((Subject)session.getAttribute("currentSubject")).getDescription());
162                } else {
163                        Term term = getService().getTerm(termId);
164                        session.setAttribute(AcademicsConstants.TERM_ID, term.getId());
165                        session.setAttribute("currentTerm", term);
166                        session.setAttribute(AcademicsConstants.CAREER_ID, careerId);
167                        Career career = (Career) CollectionUtils.find((List<Career>) session.getAttribute(AcademicsConstants.CAREER), new CareerPredicate(careerId));
168                        session.setAttribute("currentCareer", career);
169                        session.setAttribute(AcademicsConstants.SUBJECT_ID, subjectId);
170                        Subject subject = (Subject)CollectionUtils.find((List<Subject>) session.getAttribute(AcademicsConstants.SUBJECT), new SubjectPredicate(subjectId));
171                        session.setAttribute("currentSubject", subject);
172                        List<? extends CatalogNumber> lCatalogNumbers = getService().getCatalogNumbers(termId, subjectId);
173                        session.setAttribute("catalogNumbers", lCatalogNumbers);
174
175                        uiModel.addAttribute(AcademicsConstants.TITLE, ((Subject)session.getAttribute("currentSubject")).getDescription());
176                }
177                //uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/subjects?termId=" + session.getAttribute(AcademicsConstants.TERM_ID) + "&careerId=" + session.getAttribute(AcademicsConstants.CAREER_ID));
178                return "academics/catalogNumbers";
179        }
180
181        @RequestMapping(value = "/browseClasses")
182        public String browseClasses(HttpServletRequest request, Model uiModel,
183                        @RequestParam(required = false) String stage,
184                        @RequestParam(required = false)
185                        final String termId,
186                        @RequestParam(required = false)
187                        final String subjectId,
188                        @RequestParam(required = false)
189                        final String subject,
190                        @RequestParam(required = false)
191                        final String careerId,
192                        @RequestParam(required = false)
193                        final String catalogNumber,
194                        @RequestParam(required = false)
195                        final String catalogDescription) {
196                HttpSession session = request.getSession();
197                if (stage != null) {
198                        session.setAttribute(AcademicsConstants.STAGE, stage);
199                } else {
200                        stage = AcademicsConstants.TERM;
201                }
202                if (termId != null && termId.length() > 0) {
203                        session.setAttribute(AcademicsConstants.TERM_ID, termId);
204                }
205                if (subjectId != null && subjectId.length() > 0) {
206                        session.setAttribute(AcademicsConstants.SUBJECT_ID, subjectId);
207                }
208                if (subject != null && subject.length() > 0) {
209                        session.setAttribute(AcademicsConstants.SUBJECT, subject);
210                }
211                if (careerId != null && careerId.length() > 0) {
212                        session.setAttribute(AcademicsConstants.CAREER_ID, careerId);
213                }
214                if (catalogNumber != null && catalogNumber.length() > 0) {
215                        session.setAttribute(AcademicsConstants.CATALOG_NUMBER, catalogNumber);
216                }
217                uiModel.addAttribute(AcademicsConstants.STAGE, stage);
218                uiModel.addAttribute(AcademicsConstants.TERM_ID, session.getAttribute(AcademicsConstants.TERM_ID));
219                uiModel.addAttribute(AcademicsConstants.SUBJECT_ID, session.getAttribute(AcademicsConstants.SUBJECT_ID));
220                uiModel.addAttribute(AcademicsConstants.CAREER_ID, session.getAttribute(AcademicsConstants.CAREER_ID));
221                uiModel.addAttribute(AcademicsConstants.CATALOG_NUMBER, session.getAttribute(AcademicsConstants.CATALOG_NUMBER));
222                uiModel.addAttribute(AcademicsConstants.SUBJECT, session.getAttribute(AcademicsConstants.SUBJECT));
223                uiModel.addAttribute("toolContext", "academics");
224                if (stage.equalsIgnoreCase(AcademicsConstants.CATALOG_NUMBER)) {
225                        uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, "browseClasses?stage=" + AcademicsConstants.SUBJECT);
226                } else if (stage.equalsIgnoreCase(AcademicsConstants.SUBJECT)) {
227                        uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, "browseClasses?stage=" + AcademicsConstants.CAREER);
228                } else if (stage.equalsIgnoreCase(AcademicsConstants.CAREER)) {
229                        uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, "browseClasses?stage=" + AcademicsConstants.TERM);
230                }
231
232//              Enumeration<String> e = session.getAttributeNames();
233//              while (e.hasMoreElements()) {
234//                      String key = e.nextElement();
235//                      LOG.debug("Session contains: [" + key + "] [" + session.getAttribute(key) + "]");
236//              }
237
238                return "academics/browseClasses";
239        }
240
241        @RequestMapping(value = "/sections")
242        public String getSections(HttpServletRequest request, Model uiModel,
243                        @RequestParam(required = false)
244                        final String termId,
245                        @RequestParam(required = false)
246                        final String subjectId,
247                        @RequestParam(required = false)
248                        final String catalogNumber,
249                        @RequestParam(required = false)
250                        final String careerId) {
251                HttpSession session = request.getSession();
252                if (termId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.TERM_ID))
253                                && careerId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CAREER_ID))
254                                && subjectId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CAREER_ID))
255                                && catalogNumber.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CATALOG_NUMBER))) {
256                        uiModel.addAttribute(AcademicsConstants.TITLE, session.getAttribute(AcademicsConstants.SUBJECT_ID) + " " + session.getAttribute(AcademicsConstants.CATALOG_NUMBER));
257                } else {
258                        List<Section> lSections = (List<Section>) getService().getSections(termId, subjectId, catalogNumber, careerId);
259                        CatalogNumber number = (CatalogNumber) CollectionUtils.find((List<CatalogNumber>) session.getAttribute("catalogNumbers"), new CatalogNumberPredicate(catalogNumber));
260                        for (Section s : lSections) {
261                            if (null==s.getCourseTitle() || s.getCourseTitle().trim().isEmpty()) {
262                                s.setCourseTitle(number.getDescription());
263                            } 
264                        }
265                        
266                        session.setAttribute("sectionsAll", lSections);
267                        session.setAttribute(AcademicsConstants.CATALOG_NUMBER, catalogNumber);
268                        session.setAttribute(AcademicsConstants.SUBJECT_ID, subjectId);
269                        uiModel.addAttribute("sectionsAll", lSections);
270                        uiModel.addAttribute(AcademicsConstants.TITLE, session.getAttribute(AcademicsConstants.SUBJECT_ID) + " " + session.getAttribute(AcademicsConstants.CATALOG_NUMBER));
271                }
272                uiModel.addAttribute("toolContext", "academics");
273                //uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/catalogNumbers?termId=" + termId + "&careerId=" + careerId + "&subjectId=" + subjectId);
274                return "academics/sections";
275        }
276
277        @RequestMapping(value = "/sectionsDetail")
278        public String getSectionsDetail(HttpServletRequest request, Model uiModel,
279                        @RequestParam(required = false)
280                        final String catalogDescription,
281                        @RequestParam(required = true)
282                        final String sectionUID) {
283                HttpSession session = request.getSession();
284                Section sectionDetail = null;
285                LOG.debug("Entering getSectionsDetail looking for sectionUID [" + sectionUID + "]");
286                if (null != session.getAttribute(AcademicsConstants.SECTIONS)) {
287                        LOG.debug("Sections are stored in the session.");
288                        List<Section> allSections = (List<Section>) session.getAttribute(AcademicsConstants.SECTIONS);
289                        for (Section thisSection : allSections) {
290                                LOG.debug("Testing section [" + thisSection.getSectionUID() + "]");
291                                if (sectionUID.equalsIgnoreCase(thisSection.getSectionUID())) {
292                                        LOG.debug("Matching section found, loading remaining details.");
293                                        sectionDetail = getService().getSectionDetail(thisSection);
294                                        break;
295                                }
296                        }
297                }
298//              uiModel.addAttribute(AcademicsConstants.CATALOG_DESCRIPTION, session.getAttribute(AcademicsConstants.CATALOG_DESCRIPTION));
299                uiModel.addAttribute(AcademicsConstants.TITLE, sectionDetail.getSubjectId() + " " + sectionDetail.getCatalogNumber());
300                uiModel.addAttribute("thisSection", sectionDetail);
301                uiModel.addAttribute("toolContext", "academics");
302                //LOG.debug("BACKBUTTON_URL from request for sectionDetail: -" + session.getAttribute("backButtonURL"));
303//        String backurl = (String) session.getAttribute("backButtonURL");
304//        if(backurl.equalsIgnoreCase("search"))
305//        {
306//           uiModel.addAttribute("backButtonURL","academics/classSearch");
307//        }
308//        else
309//        {
310//           uiModel.addAttribute("backButtonURL","academics/sections?termId="+session.getAttribute(AcademicsConstants.TERM_ID)+"&careerId="+session.getAttribute(AcademicsConstants.CAREER_ID)+"&subjectId="+session.getAttribute(AcademicsConstants.SUBJECT_ID)+"&catalogNumber="+session.getAttribute(AcademicsConstants.CATALOG_NUMBER)+"&catalogDescription="+session.getAttribute(AcademicsConstants.CATALOG_DESCRIPTION));
311//        }
312//              uiModel.addAttribute("backButtonURL", request.getHeader("referer"));
313                return "academics/sectionsDetail";
314        }
315
316        @RequestMapping(value = "/search")
317        public String searchForm(Model uiModel) {
318                uiModel.addAttribute(AcademicsConstants.TERM_ID, getService().getTerms());
319                uiModel.addAttribute(AcademicsConstants.CAREER_ID, getService().getCareers("ALL"));
320                uiModel.addAttribute(AcademicsConstants.SUBJECT_ID, getService().getSubjects("ALL", "ALL"));
321                uiModel.addAttribute("toolContext", "academics");
322                
323                return "academics/search";
324        }
325
326        @RequestMapping(value = "/classSearch", method = RequestMethod.POST)
327        public String getSearchResults(HttpServletRequest request, Model uiModel) {
328            Map<String, String[]> inputMap = request.getParameterMap();
329
330            if ( LOG.isDebugEnabled() ) {
331                LOG.debug("Search request parameter map:");
332                Iterator<Map.Entry<String, String[]>> mapIterator = inputMap.entrySet().iterator();
333                while (mapIterator.hasNext()) {
334                    Map.Entry<String, String[]> entry = mapIterator.next();
335                    LOG.debug(entry.getKey() + ": " + Arrays.toString(entry.getValue()));
336                }
337            }
338            
339            SearchResult result = getService().getSearchResults(inputMap);
340            List<Section> lSections = (List<Section>)result.getSections();
341            LOG.debug("Sections classSearch POST  " + lSections.size() + " items long.");
342            HttpSession session = request.getSession();
343            session.setAttribute(AcademicsConstants.SECTIONS, lSections);
344            session.setAttribute(AcademicsConstants.SEARCH_RESULT,result);
345            session.setAttribute("toolContext", "academics");
346
347            uiModel.addAttribute("searchResult", result);
348            uiModel.addAttribute("toolContext", "academics");
349
350            return "academics/searchResult";
351        }
352
353        @RequestMapping(value = "/classSearch", method = RequestMethod.GET)
354        public String searchResults(HttpServletRequest request, Model uiModel) {
355                HttpSession session = request.getSession();
356                //uiModel.addAttribute(AcademicsConstants.TITLE, "Search Results");
357                //uiModel.addAttribute("sectionsAll", session.getAttribute("sectionsAll"));
358                uiModel.addAttribute("searchResult", session.getAttribute(AcademicsConstants.SEARCH_RESULT));
359                uiModel.addAttribute("toolContext", session.getAttribute("toolContext"));
360                //uiModel.addAttribute("backButtonURL", session.getAttribute("backButtonURL"));
361                return "academics/searchResult";
362        }
363
364        private List<String> getHomeScreenOrder() {
365                List<String> toolOrder = new ArrayList<String>();
366                if( null == getAcademicsProperties() ) {
367                        LOG.error( "Failed to load academics properties" );
368                }
369                LOG.debug( "Home screen order is: "+getAcademicsProperties().getProperty("academics.homescreenorder") );
370                for( String s : getAcademicsProperties().getProperty("academics.homescreenorder").split(",") ) {
371                        if( "true".equalsIgnoreCase( getAcademicsProperties().getProperty("academics."+s+".enabled", "false"))) {
372                                toolOrder.add(s);
373                        }
374                }
375                return toolOrder;
376        }
377
378        /**
379         * @return the service
380         */
381        public AcademicsService getService() {
382                return service;
383        }
384
385        /**
386         * @param service the service to set
387         */
388        public void setService(AcademicsService service) {
389                this.service = service;
390        }
391
392        /**
393         * @return the academicsProperties
394         */
395        public Properties getAcademicsProperties() {
396                return academicsProperties;
397        }
398
399        /**
400         * @param academicsProperties the academicsProperties to set
401         */
402        public void setAcademicsProperties(Properties academicsProperties) {
403                this.academicsProperties = academicsProperties;
404        }
405}