Clover Coverage Report - KS Common 1.2-M2-SNAPSHOT (Aggregated)
Coverage timestamp: Fri Apr 22 2011 04:34:25 EST
../../../../../../../img/srcFileCovDistChart0.png 54% of files have more coverage
41   202   28   2.56
20   122   0.68   5.33
16     1.75  
3    
 
  SearchDispatchRpcGwtServlet       Line # 38 33 0% 21 61 0% 0.0
  SearchDispatchRpcGwtServlet.MaxAgeSoftReference       Line # 150 4 0% 4 9 0% 0.0
  SearchDispatchRpcGwtServlet.MaxSizeMap       Line # 173 4 0% 3 7 0% 0.0
 
No Tests
 
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.common.ui.server.gwt;
17   
18    import java.lang.ref.SoftReference;
19    import java.util.Collections;
20    import java.util.LinkedHashMap;
21    import java.util.List;
22    import java.util.Map;
23    import java.util.Map.Entry;
24   
25    import org.kuali.student.common.assembly.transform.IdTranslatorFilter;
26    import org.kuali.student.common.exceptions.MissingParameterException;
27    import org.kuali.student.common.search.dto.SearchParam;
28    import org.kuali.student.common.search.dto.SearchRequest;
29    import org.kuali.student.common.search.dto.SearchResult;
30    import org.kuali.student.common.search.dto.SearchResultCell;
31    import org.kuali.student.common.search.dto.SearchResultRow;
32    import org.kuali.student.common.search.service.SearchDispatcher;
33    import org.kuali.student.common.ui.client.service.SearchRpcService;
34    import org.springframework.beans.factory.InitializingBean;
35   
36    import com.google.gwt.user.server.rpc.RemoteServiceServlet;
37   
 
38    public class SearchDispatchRpcGwtServlet extends RemoteServiceServlet implements SearchRpcService, InitializingBean {
39   
40    private static final long serialVersionUID = 1L;
41   
42    private IdTranslatorFilter idTranslatorFilter;
43   
44    private SearchDispatcher searchDispatcher;
45   
46    protected boolean cachingEnabled = false;
47    protected int searchCacheMaxSize = 20;
48    protected int searchCacheMaxAgeSeconds = 90;
49    protected Map<String,MaxAgeSoftReference<SearchResult>> searchCache;
50   
51   
 
52  0 toggle public SearchDispatchRpcGwtServlet() {
53  0 super();
54    }
55   
56    /**
57    * Delegates to the service responsible for the given search type key
58    *
59    * @param searchRequest
60    * @return The searchResult from the delegated search or null
61    * @throws MissingParameterException
62    */
 
63  0 toggle @Override
64    public SearchResult search(SearchRequest searchRequest) {
65  0 SearchResult searchResult = searchDispatcher.dispatchSearch(searchRequest);
66  0 List<SearchParam> params = searchRequest.getParams();
67  0 if(params != null && params.size() > 0){
68  0 SearchParam firstParam = params.get(0);
69  0 if(firstParam.getKey().equals("lu.queryParam.cluVersionIndId")){//FIXME can this special case be handled after this call?
70  0 doIdTranslation(searchResult);
71    }
72    }
73  0 return searchResult;
74    }
75   
 
76  0 toggle @Override
77    public SearchResult cachingSearch(SearchRequest searchRequest) {
78  0 String cacheKey = searchRequest.toString();
79  0 if(cachingEnabled){
80   
81    //Get From Cache
82  0 MaxAgeSoftReference<SearchResult> ref = searchCache.get(cacheKey);
83  0 if ( ref != null ) {
84  0 SearchResult cachedSearchResult = ref.get();
85  0 if(cachedSearchResult!=null){
86  0 return cachedSearchResult;
87    }
88    }
89    }
90   
91    //Perform the actual Search
92  0 SearchResult searchResult = search(searchRequest);
93   
94  0 if(cachingEnabled){
95    //Store to cache
96  0 searchCache.put(cacheKey, new MaxAgeSoftReference<SearchResult>( searchCacheMaxAgeSeconds, searchResult) );
97    }
98   
99  0 return searchResult;
100    }
101   
 
102  0 toggle private void doIdTranslation(SearchResult searchResult) {
103  0 for (SearchResultRow searchResultRow : searchResult.getRows()) {
104  0 for (SearchResultCell searchResultCell : searchResultRow.getCells()) {
105  0 String value = searchResultCell.getValue();
106  0 if (value != null && value.startsWith("kuali.atp")) {
107  0 String newValue = idTranslatorFilter.getTranslationForAtp(value);
108  0 if (newValue != null) {
109  0 searchResultCell.setValue(newValue);
110    }
111    }
112    }
113    }
114    }
115   
 
116  0 toggle @Override
117    public void afterPropertiesSet() throws Exception {
118  0 if(cachingEnabled){
119  0 searchCache = Collections.synchronizedMap( new MaxSizeMap<String,MaxAgeSoftReference<SearchResult>>( searchCacheMaxSize ) );
120    }
121    }
122   
 
123  0 toggle public void setSearchDispatcher(SearchDispatcher searchDispatcher) {
124  0 this.searchDispatcher = searchDispatcher;
125    }
126   
 
127  0 toggle public void setIdTranslatorFilter(IdTranslatorFilter idTranslatorFilter) {
128  0 this.idTranslatorFilter = idTranslatorFilter;
129    }
130   
 
131  0 toggle public void setCachingEnabled(boolean cachingEnabled) {
132  0 this.cachingEnabled = cachingEnabled;
133    }
134   
 
135  0 toggle public void setSearchCacheMaxSize(int searchCacheMaxSize) {
136  0 this.searchCacheMaxSize = searchCacheMaxSize;
137    }
138   
 
139  0 toggle public void setSearchCacheMaxAgeSeconds(int searchCacheMaxAgeSeconds) {
140  0 this.searchCacheMaxAgeSeconds = searchCacheMaxAgeSeconds;
141    }
142   
143   
144    //Added as inner classes to avoid huge dependency on rice-impl
145    /**
146    * An extension to SoftReference that stores an expiration time for the
147    * value stored in the SoftReference. If no expiration time is passed in
148    * the value will never be cached.
149    */
 
150    public class MaxAgeSoftReference<T> extends SoftReference<T> {
151   
152    private long expires;
153   
 
154  0 toggle public MaxAgeSoftReference(long expires, T referent) {
155  0 super(referent);
156  0 this.expires = System.currentTimeMillis() + expires * 1000;
157    }
158   
 
159  0 toggle public boolean isValid() {
160  0 return System.currentTimeMillis() < expires;
161    }
162   
 
163  0 toggle public T get() {
164  0 return isValid() ? super.get() : null;
165    }
166   
167    }
168    /**
169    * This class acts like an LRU cache, automatically purging contents when it gets above a certain size.
170    *
171    * @author Kuali Rice Team (rice.collab@kuali.org)
172    */
 
173    public class MaxSizeMap<K,V> extends LinkedHashMap<K,V> {
174    private static final long serialVersionUID = -5354227348838839919L;
175   
176    private int maxSize;
177   
178    /**
179    * @param maxSize
180    */
 
181  0 toggle public MaxSizeMap( int maxSize ) {
182  0 this( maxSize, false );
183    }
184    /**
185    * @param maxSize
186    * @param accessOrder Whether to sort in the order accessed rather than the order inserted.
187    */
 
188  0 toggle public MaxSizeMap( int maxSize, boolean accessOrder ) {
189  0 super( maxSize / 2, 0.75f, accessOrder );
190  0 this.maxSize = maxSize;
191    }
192   
193    /**
194    * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)
195    */
 
196  0 toggle @Override
197    protected boolean removeEldestEntry(Entry<K,V> eldest) {
198  0 return size() > maxSize;
199    }
200   
201    }
202    }