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.kuali.student.r2.common.dao.impl.SearchableCrudDaoImpl;
19  import org.kuali.student.r2.common.dto.ContextInfo;
20  import org.kuali.student.r2.common.dto.RichTextInfo;
21  import org.kuali.student.r2.common.exceptions.DoesNotExistException;
22  import org.kuali.student.r2.common.exceptions.InvalidParameterException;
23  import org.kuali.student.r2.common.exceptions.MissingParameterException;
24  import org.kuali.student.r2.common.exceptions.OperationFailedException;
25  import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
26  import org.kuali.student.r2.core.class1.type.dto.TypeInfo;
27  import org.kuali.student.r2.core.search.dto.CrossSearchTypeInfo;
28  import org.kuali.student.r2.core.search.dto.SearchCriteriaTypeInfo;
29  import org.kuali.student.r2.core.search.dto.SearchRequestInfo;
30  import org.kuali.student.r2.core.search.dto.SearchResultInfo;
31  import org.kuali.student.r2.core.search.dto.SearchResultTypeInfo;
32  import org.kuali.student.r2.core.search.dto.SearchTypeInfo;
33  import org.kuali.student.r2.core.search.service.SearchManager;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  import org.springframework.context.ConfigurableApplicationContext;
37  import org.springframework.context.support.FileSystemXmlApplicationContext;
38  
39  import javax.jws.WebParam;
40  import javax.persistence.EntityManager;
41  import java.util.ArrayList;
42  import java.util.List;
43  import java.util.Map;
44  
45  /**
46   * Loads all search info for a service into memory
47   *
48   */
49  public class SearchManagerImpl implements SearchManager {
50  
51  	private static final Logger logger = LoggerFactory.getLogger(SearchManagerImpl.class);
52  
53      private SearchableCrudDaoImpl dao;
54  
55  	private String searchContextFile;
56  	private Map<String, SearchTypeInfo> searchInfoTypeMap;
57  	private Map<String, SearchCriteriaTypeInfo> searchCriteriaTypeMap;
58  	private Map<String, SearchResultTypeInfo> searchResultTypeInfoMap;
59  	private Map<String, String> queryMap;
60  
61  	private CrossSearchManager crossSearchManager;
62  
63  	@SuppressWarnings("unchecked")
64  	private void init() {
65  		ConfigurableApplicationContext ac = new FileSystemXmlApplicationContext(searchContextFile);
66  		searchInfoTypeMap = ac.getBeansOfType(SearchTypeInfo.class);
67  		searchCriteriaTypeMap = ac.getBeansOfType(SearchCriteriaTypeInfo.class);
68  		searchResultTypeInfoMap = ac.getBeansOfType(SearchResultTypeInfo.class);
69  		queryMap = (Map<String, String>) ac.getBean("queryMap");
70          ac.close();
71  	}
72  
73  	public SearchManagerImpl(String searchContextFile) {
74  		super();
75  		this.searchContextFile = searchContextFile;
76  		init();
77  	}
78  
79      /**
80       * This Constructor should only be used in tests.
81       * @param searchContextFile
82       * @param em
83       */
84      public SearchManagerImpl(String searchContextFile, EntityManager em) {
85          this(searchContextFile);
86          dao = new SearchableCrudDaoImpl();
87          dao.setEm(em);
88      }
89  
90      @Override
91      public TypeInfo getSearchType(String searchTypeKey,  ContextInfo contextInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
92  		return toTypeInfo(searchInfoTypeMap.get(searchTypeKey));
93  	}
94  
95      @Override
96      public List<TypeInfo> getSearchTypes( ContextInfo contextInfo) throws InvalidParameterException, MissingParameterException, OperationFailedException {
97          List<TypeInfo> typeInfos = new ArrayList<TypeInfo>();
98          for(SearchTypeInfo searchTypeInfo : searchInfoTypeMap.values()){
99              typeInfos.add(toTypeInfo(searchTypeInfo));
100         }
101         return typeInfos;
102 	}
103 
104     private TypeInfo toTypeInfo(SearchTypeInfo searchTypeInfo){
105 
106         if (searchTypeInfo == null){
107             return null;
108         }
109 
110         TypeInfo typeInfo = new TypeInfo();
111         typeInfo.setKey(searchTypeInfo.getKey());
112         typeInfo.setName(searchTypeInfo.getName());
113         RichTextInfo textInfo = new RichTextInfo();
114         textInfo.setPlain(searchTypeInfo.getDesc());
115         textInfo.setFormatted(searchTypeInfo.getDesc());
116         typeInfo.setDescr(textInfo);
117         return typeInfo;
118     }
119 
120 	public String getSearchContextFile() {
121 		return searchContextFile;
122 	}
123 
124 	public void setSearchContext(String searchContextFile) {
125 		this.searchContextFile = searchContextFile;
126 	}
127 
128 	@Override
129     public SearchResultInfo search(SearchRequestInfo searchRequestInfo, @WebParam(name = "contextInfo") ContextInfo contextInfo) throws MissingParameterException, OperationFailedException, PermissionDeniedException, InvalidParameterException {
130     	if(searchRequestInfo == null){
131 			throw new MissingParameterException("Search Request can not be null.");
132 		}
133 
134 		String searchKey = searchRequestInfo.getSearchKey();
135 
136 		SearchTypeInfo searchType = searchInfoTypeMap.get(searchKey);
137 
138 		//If no type was found for the key, try to dispatch the search
139 		if(searchType == null){
140 			if(crossSearchManager!=null && crossSearchManager.getSearchDispatcher()!=null){
141 				logger.info("Search type '{}' is not known to this service's search manager, attempting to dispatch search.", searchKey);
142 				return crossSearchManager.getSearchDispatcher().search(searchRequestInfo, contextInfo);
143 			}else{
144 				logger.error("Search type '{}' is not known to this service's search manager.", searchKey);
145 				throw new RuntimeException("Search type '"+searchKey+"' is not known to this service's search manager.");
146 			}
147 		}
148 
149 		//Check if the search is a cross search
150 		if(searchType instanceof CrossSearchTypeInfo){
151 			if(crossSearchManager == null){
152 				//FIXME should we change these to Operation Failed Exceptions? also we need to handle invalid parameters.
153 				throw new RuntimeException("Requested cross service search:"+searchKey+", but no cross service search manager was defined.");
154 			}
155 			return crossSearchManager.doCrossSearch(searchRequestInfo, (CrossSearchTypeInfo) searchType, contextInfo);
156 		}
157 
158 
159 		try{
160 			return dao.search(searchRequestInfo, queryMap, searchType);
161 		}catch (Exception e){
162             String errorMessage = String.format("Search Failed for searchKey: %s", searchKey);
163             logger.error(errorMessage,e);
164 			throw new RuntimeException(errorMessage, e);
165 		}
166 	}
167 
168 	public void setCrossSearchManager(CrossSearchManager crossSearchManager) {
169 		this.crossSearchManager = crossSearchManager;
170 	}
171 
172     public SearchableCrudDaoImpl getDao() {
173         return dao;
174     }
175 
176     public void setDao(SearchableCrudDaoImpl dao) {
177         this.dao = dao;
178     }
179 }