View Javadoc

1   /**
2    * Copyright 2010 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.student.r2.common.class1.search;
17  
18  import org.apache.log4j.Logger;
19  import org.kuali.student.r2.common.dao.impl.SearchableCrudDaoImpl;
20  import org.kuali.student.r2.common.dto.ContextInfo;
21  import org.kuali.student.r2.common.dto.RichTextInfo;
22  import org.kuali.student.r2.common.exceptions.DoesNotExistException;
23  import org.kuali.student.r2.common.exceptions.InvalidParameterException;
24  import org.kuali.student.r2.common.exceptions.MissingParameterException;
25  import org.kuali.student.r2.common.exceptions.OperationFailedException;
26  import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
27  import org.kuali.student.r2.core.class1.type.dto.TypeInfo;
28  import org.kuali.student.r2.core.search.dto.CrossSearchTypeInfo;
29  import org.kuali.student.r2.core.search.dto.SearchCriteriaTypeInfo;
30  import org.kuali.student.r2.core.search.dto.SearchRequestInfo;
31  import org.kuali.student.r2.core.search.dto.SearchResultInfo;
32  import org.kuali.student.r2.core.search.dto.SearchResultTypeInfo;
33  import org.kuali.student.r2.core.search.dto.SearchTypeInfo;
34  import org.kuali.student.r2.core.search.service.SearchManager;
35  import org.springframework.context.ApplicationContext;
36  import org.springframework.context.support.FileSystemXmlApplicationContext;
37  
38  import javax.jws.WebParam;
39  import javax.persistence.EntityManager;
40  import java.util.ArrayList;
41  import java.util.List;
42  import java.util.Map;
43  
44  /**
45   * Loads all search info for a service into memory
46   *
47   */
48  public class SearchManagerImpl implements SearchManager {
49  
50  	final Logger logger = Logger.getLogger(SearchManagerImpl.class);
51  
52      private SearchableCrudDaoImpl dao;
53  
54  	private String searchContextFile;
55  	private Map<String, SearchTypeInfo> searchInfoTypeMap;
56  	private Map<String, SearchCriteriaTypeInfo> searchCriteriaTypeMap;
57  	private Map<String, SearchResultTypeInfo> searchResultTypeInfoMap;
58  	private Map<String, String> queryMap;
59  
60  	private CrossSearchManager crossSearchManager;
61  
62  	@SuppressWarnings("unchecked")
63  	private void init() {
64  		ApplicationContext ac = new FileSystemXmlApplicationContext(searchContextFile);
65  		searchInfoTypeMap = ac.getBeansOfType(SearchTypeInfo.class);
66  		searchCriteriaTypeMap = ac.getBeansOfType(SearchCriteriaTypeInfo.class);
67  		searchResultTypeInfoMap = ac.getBeansOfType(SearchResultTypeInfo.class);
68  		queryMap = (Map<String, String>) ac.getBean("queryMap");
69  	}
70  
71  	public SearchManagerImpl(String searchContextFile) {
72  		super();
73  		this.searchContextFile = searchContextFile;
74  		init();
75  	}
76  
77      /**
78       * This Constructor should only be used in tests.
79       * @param searchContextFile
80       * @param em
81       */
82      public SearchManagerImpl(String searchContextFile, EntityManager em) {
83          this(searchContextFile);
84          dao = new SearchableCrudDaoImpl();
85          dao.setEm(em);
86      }
87  
88      @Override
89      public TypeInfo getSearchType(String searchTypeKey,  ContextInfo contextInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
90  		return toTypeInfo(searchInfoTypeMap.get(searchTypeKey));
91  	}
92  
93      @Override
94      public List<TypeInfo> getSearchTypes( ContextInfo contextInfo) throws InvalidParameterException, MissingParameterException, OperationFailedException {
95          List<TypeInfo> typeInfos = new ArrayList<TypeInfo>();
96          for(SearchTypeInfo searchTypeInfo : searchInfoTypeMap.values()){
97              typeInfos.add(toTypeInfo(searchTypeInfo));
98          }
99          return typeInfos;
100 	}
101 
102     private TypeInfo toTypeInfo(SearchTypeInfo searchTypeInfo){
103 
104         if (searchTypeInfo == null){
105             return null;
106         }
107 
108         TypeInfo typeInfo = new TypeInfo();
109         typeInfo.setKey(searchTypeInfo.getKey());
110         typeInfo.setName(searchTypeInfo.getName());
111         RichTextInfo textInfo = new RichTextInfo();
112         textInfo.setPlain(searchTypeInfo.getDesc());
113         textInfo.setFormatted(searchTypeInfo.getDesc());
114         typeInfo.setDescr(textInfo);
115         return typeInfo;
116     }
117 
118 	public String getSearchContextFile() {
119 		return searchContextFile;
120 	}
121 
122 	public void setSearchContext(String searchContextFile) {
123 		this.searchContextFile = searchContextFile;
124 	}
125 
126 	@Override
127     public SearchResultInfo search(SearchRequestInfo searchRequestInfo, @WebParam(name = "contextInfo") ContextInfo contextInfo) throws MissingParameterException, OperationFailedException, PermissionDeniedException, InvalidParameterException {
128     	if(searchRequestInfo == null){
129 			throw new MissingParameterException("Search Request can not be null.");
130 		}
131 
132 		String searchKey = searchRequestInfo.getSearchKey();
133 
134 		SearchTypeInfo searchType = searchInfoTypeMap.get(searchKey);
135 
136 		//If no type was found for the key, try to dispatch the search
137 		if(searchType == null){
138 			if(crossSearchManager!=null && crossSearchManager.getSearchDispatcher()!=null){
139 				logger.info("Search type '"+searchKey+"' is not known to this service's search manager, attempting to dispatch search.");
140 				return crossSearchManager.getSearchDispatcher().search(searchRequestInfo, contextInfo);
141 			}else{
142 				logger.error("Search type '"+searchKey+"' is not known to this service's search manager.");
143 				throw new RuntimeException("Search type '"+searchKey+"' is not known to this service's search manager.");
144 			}
145 		}
146 
147 		//Check if the search is a cross search
148 		if(searchType instanceof CrossSearchTypeInfo){
149 			if(crossSearchManager == null){
150 				//FIXME should we change these to Operation Failed Exceptions? also we need to handle invalid parameters.
151 				throw new RuntimeException("Requested cross service search:"+searchKey+", but no cross service search manager was defined.");
152 			}
153 			return crossSearchManager.doCrossSearch(searchRequestInfo, (CrossSearchTypeInfo) searchType, contextInfo);
154 		}
155 
156 
157 		try{
158 			return dao.search(searchRequestInfo, queryMap, searchType);
159 		}catch (Exception e){
160 			logger.error("Search Failed for searchKey:"+searchKey,e);
161 			throw new RuntimeException("Search Failed for searchKey:"+searchKey, e);
162 		}
163 	}
164 
165 	public void setCrossSearchManager(CrossSearchManager crossSearchManager) {
166 		this.crossSearchManager = crossSearchManager;
167 	}
168 
169     public SearchableCrudDaoImpl getDao() {
170         return dao;
171     }
172 
173     public void setDao(SearchableCrudDaoImpl dao) {
174         this.dao = dao;
175     }
176 }