001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.ows;
006:
007: import org.geoserver.ows.util.ResponseUtils;
008: import org.geoserver.platform.Service;
009: import org.geoserver.platform.ServiceException;
010: import java.util.Collections;
011: import java.util.Iterator;
012: import java.util.List;
013: import java.util.logging.Logger;
014: import javax.servlet.http.HttpServletRequest;
015: import javax.servlet.http.HttpServletResponse;
016:
017: /**
018: * Handles an exception thrown by a service.
019: * <p>
020: * A service exception handler must declare the services in which it is capable
021: * of handling exceptions for, see {@link #getServices()}.
022: * </p>
023: * <p>
024: * Instances must be declared in a spring context as follows:
025: * <pre>
026: * <code>
027: * <bean id="myServiceExcepionHandler" class="com.xyz.MyServiceExceptionHandler">
028: * <constructor-arg ref="myService"/>
029: * </bean>
030: * </code>
031: * </pre>
032: *
033: * Where <code>myService</code> is the id of another bean somewhere in the
034: * context.
035: *
036: * </p>
037: *
038: * @author Justin Deoliveira, The Open Planning Project
039: *
040: */
041: public abstract class ServiceExceptionHandler {
042: /**
043: * Logger
044: */
045: protected static Logger LOGGER = org.geotools.util.logging.Logging
046: .getLogger("org.geoserver.ows");
047:
048: /**
049: * The services this handler handles exceptions for.
050: */
051: List /*<Service>*/services;
052:
053: /**
054: * Constructs the handler with the list of {@link Service}'s that it
055: * handles exceptions for.
056: *
057: * @param services A list of {@link Service}.
058: */
059: public ServiceExceptionHandler(List services) {
060: this .services = services;
061: }
062:
063: /**
064: * Constructs the handler for a single {@link Service} that it handles
065: * exceptions for.
066: *
067: * @param service The service to handle exceptions for.
068: */
069: public ServiceExceptionHandler(Service service) {
070: this .services = Collections.singletonList(service);
071: }
072:
073: /**
074: * @return The services this handler handles exceptions for.
075: */
076: public List getServices() {
077: return services;
078: }
079:
080: /**
081: * Handles the service exception.
082: *
083: * @param exception The service exception.
084: * @param service The service that generated the exception
085: * @param request The original request to which the service generated the exception.
086: * @param response The response to report the exception to.
087: */
088: public abstract void handleServiceException(
089: ServiceException exception, Service service,
090: HttpServletRequest request, HttpServletResponse response);
091:
092: /**
093: * Dumps an exception message along all its causes messages (since more often
094: * than not the real cause, such as "unknown property xxx" is a few levels down)
095: * @param e
096: * @param s
097: */
098: protected void dumpExceptionMessages(ServiceException e,
099: StringBuffer s) {
100: Throwable ex = e;
101: do {
102: Throwable cause = ex.getCause();
103: final String message = ex.getMessage();
104: if (!"".equals(message)) {
105: s.append(ResponseUtils.encodeXML(message));
106: if (ex instanceof ServiceException) {
107: for (Iterator t = ((ServiceException) ex)
108: .getExceptionText().iterator(); t.hasNext();) {
109: s.append("\n").append(t.next());
110: }
111: }
112: if (cause != null)
113: s.append("\n");
114: }
115:
116: // avoid infinite loop if someone did the very stupid thing of setting
117: // the cause as the exception itself (I only found this situation once, but...)
118: if (ex == cause || cause == null)
119: break;
120: else
121: ex = cause;
122: } while (true);
123: }
124: }
|