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.ConfigurableApplicationContext;
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  		ConfigurableApplicationContext 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          ac.close();
70  	}
71  
72  	public SearchManagerImpl(String searchContextFile) {
73  		super();
74  		this.searchContextFile = searchContextFile;
75  		init();
76  	}
77  
78      /**
79       * This Constructor should only be used in tests.
80       * @param searchContextFile
81       * @param em
82       */
83      public SearchManagerImpl(String searchContextFile, EntityManager em) {
84          this(searchContextFile);
85          dao = new SearchableCrudDaoImpl();
86          dao.setEm(em);
87      }
88  
89      @Override
90      public TypeInfo getSearchType(String searchTypeKey,  ContextInfo contextInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
91  		return toTypeInfo(searchInfoTypeMap.get(searchTypeKey));
92  	}
93  
94      @Override
95      public List<TypeInfo> getSearchTypes( ContextInfo contextInfo) throws InvalidParameterException, MissingParameterException, OperationFailedException {
96          List<TypeInfo> typeInfos = new ArrayList<TypeInfo>();
97          for(SearchTypeInfo searchTypeInfo : searchInfoTypeMap.values()){
98              typeInfos.add(toTypeInfo(searchTypeInfo));
99          }
100         return typeInfos;
101 	}
102 
103     private TypeInfo toTypeInfo(SearchTypeInfo searchTypeInfo){
104 
105         if (searchTypeInfo == null){
106             return null;
107         }
108 
109         TypeInfo typeInfo = new TypeInfo();
110         typeInfo.setKey(searchTypeInfo.getKey());
111         typeInfo.setName(searchTypeInfo.getName());
112         RichTextInfo textInfo = new RichTextInfo();
113         textInfo.setPlain(searchTypeInfo.getDesc());
114         textInfo.setFormatted(searchTypeInfo.getDesc());
115         typeInfo.setDescr(textInfo);
116         return typeInfo;
117     }
118 
119 	public String getSearchContextFile() {
120 		return searchContextFile;
121 	}
122 
123 	public void setSearchContext(String searchContextFile) {
124 		this.searchContextFile = searchContextFile;
125 	}
126 
127 	@Override
128     public SearchResultInfo search(SearchRequestInfo searchRequestInfo, @WebParam(name = "contextInfo") ContextInfo contextInfo) throws MissingParameterException, OperationFailedException, PermissionDeniedException, InvalidParameterException {
129     	if(searchRequestInfo == null){
130 			throw new MissingParameterException("Search Request can not be null.");
131 		}
132 
133 		String searchKey = searchRequestInfo.getSearchKey();
134 
135 		SearchTypeInfo searchType = searchInfoTypeMap.get(searchKey);
136 
137 		//If no type was found for the key, try to dispatch the search
138 		if(searchType == null){
139 			if(crossSearchManager!=null && crossSearchManager.getSearchDispatcher()!=null){
140 				logger.info("Search type '"+searchKey+"' is not known to this service's search manager, attempting to dispatch search.");
141 				return crossSearchManager.getSearchDispatcher().search(searchRequestInfo, contextInfo);
142 			}else{
143 				logger.error("Search type '"+searchKey+"' is not known to this service's search manager.");
144 				throw new RuntimeException("Search type '"+searchKey+"' is not known to this service's search manager.");
145 			}
146 		}
147 
148 		//Check if the search is a cross search
149 		if(searchType instanceof CrossSearchTypeInfo){
150 			if(crossSearchManager == null){
151 				//FIXME should we change these to Operation Failed Exceptions? also we need to handle invalid parameters.
152 				throw new RuntimeException("Requested cross service search:"+searchKey+", but no cross service search manager was defined.");
153 			}
154 			return crossSearchManager.doCrossSearch(searchRequestInfo, (CrossSearchTypeInfo) searchType, contextInfo);
155 		}
156 
157 
158 		try{
159 			return dao.search(searchRequestInfo, queryMap, searchType);
160 		}catch (Exception e){
161 			logger.error("Search Failed for searchKey:"+searchKey,e);
162 			throw new RuntimeException("Search Failed for searchKey:"+searchKey, e);
163 		}
164 	}
165 
166 	public void setCrossSearchManager(CrossSearchManager crossSearchManager) {
167 		this.crossSearchManager = crossSearchManager;
168 	}
169 
170     public SearchableCrudDaoImpl getDao() {
171         return dao;
172     }
173 
174     public void setDao(SearchableCrudDaoImpl dao) {
175         this.dao = dao;
176     }
177 }