View Javadoc

1   package uk.ac.ebi.intenz.webapp.controller;
2   
3   import java.io.IOException;
4   import java.sql.SQLException;
5   import java.util.Map;
6   import java.util.PropertyResourceBundle;
7   import java.util.StringTokenizer;
8   
9   import javax.servlet.ServletContext;
10  import javax.servlet.ServletException;
11  
12  import org.apache.log4j.Logger;
13  
14  import uk.ac.ebi.intenz.domain.constants.Status;
15  import uk.ac.ebi.intenz.domain.enzyme.EnzymeClass;
16  import uk.ac.ebi.intenz.domain.enzyme.EnzymeCommissionNumber;
17  import uk.ac.ebi.intenz.domain.enzyme.EnzymeEntry;
18  import uk.ac.ebi.intenz.domain.enzyme.EnzymeSubSubclass;
19  import uk.ac.ebi.intenz.domain.enzyme.EnzymeSubclass;
20  import uk.ac.ebi.intenz.domain.exceptions.DomainException;
21  import uk.ac.ebi.intenz.domain.exceptions.EcException;
22  import uk.ac.ebi.intenz.mapper.EnzymeClassMapper;
23  import uk.ac.ebi.intenz.mapper.EnzymeEntryMapper;
24  import uk.ac.ebi.intenz.mapper.EnzymeSubSubclassMapper;
25  import uk.ac.ebi.intenz.mapper.EnzymeSubclassMapper;
26  import uk.ac.ebi.intenz.webapp.utilities.IntEnzMessenger;
27  import uk.ac.ebi.rhea.mapper.MapperException;
28  
29  /**
30   * This command processes all inquiries about EC numbers.
31   * 
32   * @author Michael Darsow
33   * @version 0.9 - 21-July-2003
34   */
35  public class SearchECCommand extends DatabaseCommand {
36  
37  	public static final Logger LOGGER = Logger.getLogger(SearchECCommand.class);
38  
39  	private final EnzymeClassMapper classMapper = new EnzymeClassMapper();
40  	private final EnzymeSubclassMapper subclassMapper = new EnzymeSubclassMapper();
41  	private final EnzymeSubSubclassMapper subSubclassMapper = new EnzymeSubSubclassMapper();
42  
43  	/**
44  	 * @throws ServletException
45  	 * @throws IOException
46  	 * @throws MapperException
47  	 */
48  	public void process() throws ServletException, IOException {
49  		String paramEc = request.getParameter("ec");
50  		String paramStatus = request.getParameter("status");
51  		EnzymeCommissionNumber ec = null;
52  		String forwardPageName = null;
53  
54  		if (paramEc == null) {
55  			request.setAttribute("message",
56  					"The <b>ec</b> parameter has to be set to be able to search for an EC.");
57  			forward("/error.jsp");
58  			return;
59  		}
60  
61  		// First check if the given EC is valid.
62  		try {
63  			ec = EnzymeCommissionNumber.valueOf(paramEc);
64  			if (ec == null) {
65  				request.setAttribute("message", "The EC <b>" + paramEc
66  						+ "</b> you used with this inquiry is not valid.");
67  				forward("/error.jsp");
68  				return;
69  			}
70  		} catch (EcException e) {
71  			request.setAttribute("message", "The EC <b>" + paramEc
72  					+ "</b> you used with this inquiry is not valid.");
73  			forward("/error.jsp");
74  			return;
75  		}
76  
77  		switch (ec.getType()) {
78  		case CLASS:
79  			forwardPageName = setClassData(ec);
80  			break;
81  		case SUBCLASS:
82  			forwardPageName = setSubclassData(ec);
83  			break;
84  		case SUBSUBCLASS:
85  			forwardPageName = setSubSubclassData(ec);
86  			break;
87  		case ENZYME:
88  		case PRELIMINARY:
89  			forwardPageName = setEnzymeData(ec, getStatus(paramStatus, ec));
90  			break;
91  		}
92  		forward(forwardPageName);
93  	}
94  
95  	/**
96  	 * Adjusts the requested status.
97  	 * 
98  	 * @param paramStatus
99  	 *            the requested status, if any.
100 	 * @param ec
101 	 *            the requested EC number.
102 	 * @return
103 	 */
104 	private Status getStatus(String paramStatus, EnzymeCommissionNumber ec) {
105 		switch (ec.getType()) {
106 		case PRELIMINARY:
107 			return Status.PRELIMINARY;
108 		default:
109 			return paramStatus == null ? Status.APPROVED : Status
110 					.fromCode(paramStatus);
111 		}
112 	}
113 
114 	private String setClassData(EnzymeCommissionNumber ec) {
115 		assert ec != null;
116 
117 		EnzymeClass enzymeClass = findEnzymeClass(ec);
118 		if (enzymeClass != null) {
119 			request.setAttribute("result", enzymeClass);
120 			return "/class.jsp";
121 		} else {
122 			if (request.getAttribute("message") != null) {
123 				return "/error.jsp";
124 			} else {
125 				request.setAttribute("message", "No entry found for EC: <b>"
126 						+ ec.toString() + "</b>.");
127 				return "/notFound.jsp"; // No result found.
128 			}
129 		}
130 	}
131 
132 	private String setSubclassData(EnzymeCommissionNumber ec) {
133 		assert ec != null;
134 
135 		EnzymeSubclass enzymeSubclass = findEnzymeSubclass(ec);
136 		if (enzymeSubclass != null) {
137 			request.setAttribute("result", enzymeSubclass);
138 			return "/subclass.jsp";
139 		} else {
140 			if (request.getAttribute("message") != null) {
141 				return "/error.jsp";
142 			} else {
143 				request.setAttribute("message", "No entry found for EC: <b>"
144 						+ ec.toString() + "</b>.");
145 				return "/notFound.jsp"; // No result found.
146 			}
147 		}
148 	}
149 
150 	private String setSubSubclassData(EnzymeCommissionNumber ec) {
151 		assert ec != null;
152 
153 		EnzymeSubSubclass enzymeSubSubclass = findEnzymeSubSubclass(ec);
154 		if (enzymeSubSubclass != null) {
155 			request.setAttribute("result", enzymeSubSubclass);
156 			return "/subsubclass.jsp";
157 		} else {
158 			if (request.getAttribute("message") != null) {
159 				return "/error.jsp";
160 			} else {
161 				request.setAttribute("message", "No entry found for EC: <b>"
162 						+ ec.toString() + "</b>.");
163 				return "/notFound.jsp"; // No result found.
164 			}
165 		}
166 	}
167 
168 	private String setEnzymeData(EnzymeCommissionNumber ec, Status status) {
169 		assert ec != null && status != null;
170 		EnzymeEntry enzymeEntry = findEnzymeEntry(ec, status);
171 		if (enzymeEntry != null) {
172 			request.setAttribute("result", enzymeEntry);
173 			return "/entry.jsp";
174 		} else {
175 			if (request.getAttribute("message") != null) {
176 				return "/error.jsp";
177 			} else {
178 				request.setAttribute("message", "No entry found for EC: <b>"
179 						+ ec.toString() + "</b>.");
180 				return "/notFound.jsp"; // No result found.
181 			}
182 		}
183 	}
184 
185 	/**
186 	 * Calls the according <code>find()</code> method and handles empty results
187 	 * and SQL exceptions.
188 	 * 
189 	 * @param ec
190 	 *            Number of enzyme class to search for.
191 	 * @return An <code>EnzymeClass</code> instance or <code>null</code>.
192 	 */
193 	protected EnzymeClass findEnzymeClass(EnzymeCommissionNumber ec) {
194 		if (ec == null)
195 			throw new NullPointerException();
196 
197 		EnzymeClass enzymeClass = null;
198 		ServletContext application = request.getSession().getServletContext();
199 		@SuppressWarnings("unchecked")
200 		Map<EnzymeCommissionNumber, EnzymeClass> classes = (Map<EnzymeCommissionNumber, EnzymeClass>) application
201 				.getAttribute("classes");
202 
203 		// Check if object already stored in the cache.
204 		if (classes.containsKey(ec)) {
205 			enzymeClass = (EnzymeClass) classes.get(ec);
206 		} else { // If the object is not stored in the cache load it from the
207 					// database.
208 			try {
209 				enzymeClass = classMapper.find(Integer.toString(ec.getEc1()),
210 						con);
211 				if (enzymeClass != null) {
212 					classes.put(ec, enzymeClass);
213 					application.setAttribute("classes", classes);
214 				}
215 			} catch (SQLException e) {
216 				LOGGER.error("Finding enzyme class", e);
217 				IntEnzMessenger.sendError(this.getClass().toString(), e
218 						.getMessage(), (String) request.getSession()
219 						.getAttribute("user"));
220 				request.setAttribute("message", e.getMessage());
221 				return null;
222 			} catch (DomainException e) {
223 				LOGGER.error("Finding enzyme class", e);
224 				PropertyResourceBundle intenzMessages = (PropertyResourceBundle) request
225 						.getSession().getServletContext()
226 						.getAttribute("intenz.messages");
227 				IntEnzMessenger.sendError(this.getClass().toString(),
228 						intenzMessages.getString(e.getMessageKey()),
229 						(String) request.getSession().getAttribute("user"));
230 				request.setAttribute("message", e.getMessage());
231 				return null;
232 			}
233 		}
234 
235 		return enzymeClass;
236 	}
237 
238 	/**
239 	 * Calls the according <code>find()</code> method and handles empty results
240 	 * and SQL exceptions.
241 	 * 
242 	 * @param ec
243 	 *            Number of enzyme class to search for.
244 	 * @return An <code>EnzymeClass</code> instance or <code>null</code>.
245 	 * @throws NullPointerException
246 	 *             if any of the parameters is <code>null</code>.
247 	 */
248 	protected EnzymeSubclass findEnzymeSubclass(EnzymeCommissionNumber ec) {
249 		if (ec == null)
250 			throw new NullPointerException();
251 
252 		EnzymeSubclass enzymeSubclass = null;
253 		ServletContext application = request.getSession().getServletContext();
254 		@SuppressWarnings("unchecked")
255 		Map<EnzymeCommissionNumber, EnzymeSubclass> subclasses = (Map<EnzymeCommissionNumber, EnzymeSubclass>) application
256 				.getAttribute("subclasses");
257 
258 		// Check if object already stored in the cache.
259 		if (subclasses.containsKey(ec)) {
260 			enzymeSubclass = (EnzymeSubclass) subclasses.get(ec);
261 		} else { // If the object is not stored in the cache load it from the
262 			try {
263 				enzymeSubclass = subclassMapper.find(
264 						Integer.toString(ec.getEc1()),
265 						Integer.toString(ec.getEc2()), con);
266 				if (enzymeSubclass != null) {
267 					subclasses.put(ec, enzymeSubclass);
268 					application.setAttribute("subclasses", subclasses);
269 				}
270 			} catch (SQLException e) {
271 				LOGGER.error("Finding enzyme subclass", e);
272 				IntEnzMessenger.sendError(this.getClass().toString(), e
273 						.getMessage(), (String) request.getSession()
274 						.getAttribute("user"));
275 				request.setAttribute("message", e.getMessage());
276 				return null;
277 			} catch (DomainException e) {
278 				LOGGER.error("Finding enzyme subclass", e);
279 				PropertyResourceBundle intenzMessages = (PropertyResourceBundle) request
280 						.getSession().getServletContext()
281 						.getAttribute("intenz.messages");
282 				IntEnzMessenger.sendError(this.getClass().toString(),
283 						intenzMessages.getString(e.getMessageKey()),
284 						(String) request.getSession().getAttribute("user"));
285 				request.setAttribute("message", e.getMessage());
286 				return null;
287 			}
288 		}
289 		return enzymeSubclass;
290 	}
291 
292 	/**
293 	 * Calls the according <code>find()</code> method and handles empty results
294 	 * and SQL exceptions.
295 	 * 
296 	 * @param ec
297 	 *            Number of enzyme class to search for.
298 	 * @return An <code>EnzymeClass</code> instance or <code>null</code>.
299 	 * @throws NullPointerException
300 	 *             if any of the parameters is <code>null</code>.
301 	 */
302 	protected EnzymeSubSubclass findEnzymeSubSubclass(EnzymeCommissionNumber ec) {
303  		if (ec == null)
304 			throw new NullPointerException();
305 
306 		EnzymeSubSubclass enzymeSubSubclass = null;
307 		ServletContext application = request.getSession().getServletContext();
308 		@SuppressWarnings("unchecked")
309 		Map<EnzymeCommissionNumber, EnzymeSubSubclass> subsubclasses = (Map<EnzymeCommissionNumber, EnzymeSubSubclass>) application
310 				.getAttribute("subsubclasses");
311 
312 		// Check if object already stored in the cache.
313 		if (subsubclasses.containsKey(ec)) {
314 			enzymeSubSubclass = (EnzymeSubSubclass) subsubclasses.get(ec);
315 		} else { // If the object is not stored in the cache load it from the
316 					// database.
317 			try {
318 				enzymeSubSubclass = subSubclassMapper.find(ec.getEc1(),
319 						ec.getEc2(), ec.getEc3(), con);
320 				if (enzymeSubSubclass != null) {
321 					subsubclasses.put(ec, enzymeSubSubclass);
322 					application.setAttribute("subsubclasses", subsubclasses);
323 				}
324 			} catch (DomainException e) {
325 				LOGGER.error("Finding enzyme subSubclass", e);
326 				PropertyResourceBundle intenzMessages = (PropertyResourceBundle) request
327 						.getSession().getServletContext()
328 						.getAttribute("intenz.messages");
329 				IntEnzMessenger.sendError(this.getClass().toString(),
330 						intenzMessages.getString(e.getMessageKey()),
331 						(String) request.getSession().getAttribute("user"));
332 				request.setAttribute("message", e.getMessage());
333 				return null;
334 			} catch (Exception e) {
335 				LOGGER.error("Finding enzyme subSubclass", e);
336 				IntEnzMessenger.sendError(this.getClass().toString(),
337 						e.getMessage(),
338 						(String) request.getSession().getAttribute("user"));
339 				request.setAttribute("message", e.getMessage());
340 				return null;
341 			}
342 		}
343 		return enzymeSubSubclass;
344 	}
345 
346 	/**
347 	 * Gets the type of the EC number.
348 	 * <p/>
349 	 * The following types are possible (in [] the value returned by this
350 	 * method):
351 	 * <ul>
352 	 * <li>Class EC (e.g. EC 1) [1]</li>
353 	 * <li>Subclass EC (e.g. EC 1.1) [2]</li>
354 	 * <li>Sub-subclass EC (e.g. EC 1.1.1) [3]</li>
355 	 * <li>Entry EC (e.g. EC 1.1.1.1) [4]</li>
356 	 * </ul>
357 	 * 
358 	 * @param ec
359 	 *            The EC string.
360 	 * @return Integer code for the type.
361 	 */
362 	protected int analyseECType(String ec) {
363 		int count = 0;
364 		for (StringTokenizer stringTokenizer = new StringTokenizer(ec, "."); stringTokenizer
365 				.hasMoreTokens();) {
366 			stringTokenizer.nextToken();
367 			count++;
368 		}
369 
370 		return count;
371 	}
372 
373 	// ------------------- PRIVATE METHODS ------------------------
374 
375 	/**
376 	 * Calls the according <code>find()</code> method and handles empty results
377 	 * and SQL exceptions.
378 	 * 
379 	 * @param ec
380 	 *            EC number of enzyme to search for.
381 	 * @param status
382 	 *            the enzyme status.
383 	 * @return An <code>EnzymeEntry</code> instance or <code>null</code>.
384 	 * @throws NullPointerException
385 	 *             if any of the parameters is <code>null</code>.
386 	 */
387 	protected EnzymeEntry findEnzymeEntry(EnzymeCommissionNumber ec,
388 			Status status) {
389 		if (ec == null || status == null)
390 			throw new NullPointerException();
391 
392 		EnzymeEntry enzymeEntry = null;
393 		ServletContext application = request.getSession().getServletContext();
394 		@SuppressWarnings("unchecked")
395 		Map<EnzymeEntryCacheKey, EnzymeEntry> entries = (Map<EnzymeEntryCacheKey, EnzymeEntry>) application
396 				.getAttribute("entries_ec");
397 
398 		// Check if object already stored in the cache.
399 		EnzymeEntryCacheKey key = new EnzymeEntryCacheKey(ec, status);
400 		if (entries.containsKey(key)) {
401 			enzymeEntry = (EnzymeEntry) entries.get(key);
402 		} else {
403 			try {
404 				Long enzyme_id = enzymeEntryMapper.findIDInMappingTable(
405 						ec.toString(), status, con);
406 				if (enzyme_id.longValue() == -1)
407 					return null;
408 				enzymeEntry = enzymeEntryMapper.findById(enzyme_id, con);
409 				if (enzymeEntry != null)
410 					entries.put(key, enzymeEntry);
411 			} catch (SQLException e) {
412 				IntEnzMessenger.sendError(this.getClass().toString(), e
413 						.getMessage(), (String) request.getSession()
414 						.getAttribute("user"));
415 				request.setAttribute("message", e.getMessage());
416 			} catch (MapperException e) {
417 				IntEnzMessenger.sendError(this.getClass().toString(), e
418 						.getMessage(), (String) request.getSession()
419 						.getAttribute("user"));
420 				request.setAttribute("message", e.getMessage());
421 			} catch (DomainException e) {
422 				LOGGER.error("Finding enzyme entry", e);
423 				PropertyResourceBundle intenzMessages = (PropertyResourceBundle) request
424 						.getSession().getServletContext()
425 						.getAttribute("intenz.messages");
426 				IntEnzMessenger.sendError(this.getClass().toString(),
427 						intenzMessages.getString(e.getMessageKey()),
428 						(String) request.getSession().getAttribute("user"));
429 				request.setAttribute("message", e.getMessage());
430 			} finally {
431 				try {
432 					con.close();
433 				} catch (SQLException e) {
434 					IntEnzMessenger.sendError(this.getClass().toString(), e
435 							.getMessage(), (String) request.getSession()
436 							.getAttribute("user"));
437 					request.setAttribute("message", e.getMessage());
438 					return null;
439 				}
440 			}
441 		}
442 		return enzymeEntry;
443 	}
444 
445 	protected static class EnzymeEntryCacheKey {
446 		private EnzymeCommissionNumber ec;
447 		private Status status;
448 
449 		public EnzymeEntryCacheKey(EnzymeCommissionNumber ec, Status status) {
450 			this.ec = ec;
451 			this.status = status;
452 		}
453 
454 		public boolean equals(Object o) {
455 			if (this == o)
456 				return true;
457 			if (!(o instanceof SearchECCommand.EnzymeEntryCacheKey))
458 				return false;
459 
460 			final SearchECCommand.EnzymeEntryCacheKey enzymeEntryCacheKey = (SearchECCommand.EnzymeEntryCacheKey) o;
461 
462 			if (ec != null ? !ec.equals(enzymeEntryCacheKey.ec)
463 					: enzymeEntryCacheKey.ec != null)
464 				return false;
465 			if (status != null ? !status.equals(enzymeEntryCacheKey.status)
466 					: enzymeEntryCacheKey.status != null)
467 				return false;
468 
469 			return true;
470 		}
471 
472 		public int hashCode() {
473 			int result;
474 			result = (ec != null ? ec.hashCode() : 0);
475 			result = 29 * result + (status != null ? status.hashCode() : 0);
476 			return result;
477 		}
478 
479 		public String toString() {
480 			StringBuffer output = new StringBuffer();
481 			output.append("EC: ");
482 			output.append(ec.toString());
483 			output.append("\n");
484 			output.append("Status: ");
485 			output.append(status.toString());
486 			output.append("\n");
487 			return output.toString();
488 		}
489 	}
490 }