You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by ro...@apache.org on 2010/07/22 15:29:53 UTC
svn commit: r966643 - in /incubator/wink/trunk:
wink-common/src/main/java/org/apache/wink/common/internal/i18n/
wink-common/src/main/java/org/apache/wink/common/internal/registry/
wink-common/src/main/java/org/apache/wink/common/internal/registry/metad...
Author: rott
Date: Thu Jul 22 13:29:52 2010
New Revision: 966643
URL: http://svn.apache.org/viewvc?rev=966643&view=rev
Log:
WINK-304: improve serviceability log message output, add tests
Added:
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ProvidersRegistrySystemTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/IProvider.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider1.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider2.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider3.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider4.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/serviceability/
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/serviceability/ServiceabilityTest.java
Modified:
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/i18n/MessageBundle.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ClassMetadata.java
incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties
incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLogHandler.java
incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLoggerAdapter.java
incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/RequestProcessor.java
incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/application/ApplicationProcessor.java
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/i18n/MessageBundle.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/i18n/MessageBundle.java?rev=966643&r1=966642&r2=966643&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/i18n/MessageBundle.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/i18n/MessageBundle.java Thu Jul 22 13:29:52 2010
@@ -42,16 +42,22 @@ public class MessageBundle {
* Gets a string message from the resource bundle for the given key
*
* @param key The resource key
- * @return The message
+ * @return The message, or key in the case of MissingResourceException
*/
- public String getMessage(String key) throws MissingResourceException {
- String msg = resourceBundle.getString(key);
+ public String getMessage(String key) {
+ try {
+ String msg = resourceBundle.getString(key);
- if (msg == null) {
- throw new MissingResourceException("Cannot find resource key \"" + key //$NON-NLS-1$
- + "\" in base name " //$NON-NLS-1$
- + className, className, key);
+ if (msg == null) {
+ throw new MissingResourceException("Cannot find resource key \"" + key //$NON-NLS-1$
+ + "\" in base name " //$NON-NLS-1$
+ + className, className, key);
+ }
+ return msg;
+ } catch (MissingResourceException e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace(System.err);
}
- return msg;
+ return key;
}
}
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java?rev=966643&r1=966642&r2=966643&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java Thu Jul 22 13:29:52 2010
@@ -745,10 +745,27 @@ public class ProvidersRegistry {
@Override
public String toString() {
- return toString(" "); //$NON-NLS-1$
+ return toString(" ", false, true); //$NON-NLS-1$
}
-
- protected String toString(String indent) {
+
+ /**
+ *
+ * @param userOnly only print user-defined entities
+ * @param trace if calling toString as part of debugging, use trace=false, if as part of trace or any other reason, use trace=true
+ * @return
+ */
+ public String toString(boolean userOnly, boolean trace) {
+ return toString(" ", userOnly, trace);
+ }
+
+ /**
+ *
+ * @param indent how far to indent output
+ * @param userOnly only log user-defined entities
+ * @param trace if calling toString as part of debugging, use trace=false, if as part of trace or any other reason, use trace=true (debug prints slightly less verbose)
+ * @return
+ */
+ protected String toString(String indent, boolean userOnly, boolean trace) {
StringBuffer sb = new StringBuffer();
sb.append("\nRawType: "); //$NON-NLS-1$
@@ -757,25 +774,39 @@ public class ProvidersRegistry {
if (data.isEmpty()) {
sb.append("{empty}"); //$NON-NLS-1$
} else {
- sb.append("\n"); //$NON-NLS-1$
- }
-
- // The data Map can be huge. Separate entries
- // to make it more understandable
- for (MediaType k : data.keySet()) {
- sb.append("MediaType key = "); //$NON-NLS-1$
- sb.append(k);
- sb.append("\n"); //$NON-NLS-1$
- sb.append("ObjectFactory Set value = {\n"); //$NON-NLS-1$
-
- // Separate each ObjectFactory entry in the Set
- // into its own line
- for (ObjectFactory<T> of : data.get(k)) {
- sb.append(indent);
- sb.append(of);
- sb.append("\n"); //$NON-NLS-1$
+ StringBuffer sb_map = new StringBuffer();
+ boolean userItemFound = !userOnly;
+ // The data Map can be huge. Separate entries
+ // to make it more understandable
+ for (MediaType k : data.keySet()) {
+ sb_map.append("MediaType key = "); //$NON-NLS-1$
+ sb_map.append(k);
+ sb_map.append("\n"); //$NON-NLS-1$
+ sb_map.append("ObjectFactory Set value = {\n"); //$NON-NLS-1$
+
+ // Separate each ObjectFactory entry in the Set
+ // into its own line
+ for (ObjectFactory<T> of : data.get(k)) {
+ // assuming everything in the org.apache.wink.* package space with "internal" in package name is system, not user
+ String instanceClassName = of.getInstanceClass().getName();
+ if ((userOnly && !(instanceClassName.startsWith("org.apache.wink.common.internal.") || instanceClassName.startsWith("org.apache.wink.server.internal."))) || !userOnly) { //$NON-NLS-1$ $NON-NLS-2$
+ userItemFound = true;
+ sb_map.append(indent);
+ if (trace) { // trace, print full ObjectFactory.toString()
+ sb_map.append(of);
+ } else { // debug, print slightly less information
+ sb_map.append(of.getInstanceClass());
+ }
+ sb_map.append("\n"); //$NON-NLS-1$
+ }
+ }
+ sb_map.append("}\n"); //$NON-NLS-1$
+ }
+ if ((sb_map.length() > 0) && userItemFound) {
+ sb.append("\n" + sb_map.toString()); //$NON-NLS-1$
+ } else {
+ sb.append("{empty}"); //$NON-NLS-1$
}
- sb.append("}\n"); //$NON-NLS-1$
}
return sb.toString();
}
@@ -932,7 +963,23 @@ public class ProvidersRegistry {
@Override
public String toString() {
- return String.format("Priority: %f, ObjectFactory: %s", priority, of); //$NON-NLS-1$
+ return String.format("Priority: %f, ObjectFactory: %s", priority, of.toString().replace("class ", "")); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ *
+ * @param userOnly true = log user providers only, false = log all providers
+ */
+ public String getLogFormattedProvidersList(boolean userOnly) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(this.contextResolvers.toString(userOnly, false));
+ sb.append(this.messageBodyReaders.toString(userOnly, false));
+ sb.append(this.messageBodyWriters.toString(userOnly, false));
+ if (userOnly) {
+ return Messages.getMessage("followingProvidersUserDefined", sb.toString());
+ } else {
+ return Messages.getMessage("followingProviders", sb.toString());
}
}
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ClassMetadata.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ClassMetadata.java?rev=966643&r1=966642&r2=966643&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ClassMetadata.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ClassMetadata.java Thu Jul 22 13:29:52 2010
@@ -147,7 +147,7 @@ public class ClassMetadata extends Abstr
@Override
public String toString() {
- return String.format("Class: %s", resourceClass); //$NON-NLS-1$
+ return String.format("Class: %s", resourceClass.toString().replace("class ", "")); //$NON-NLS-1$
}
}
Modified: incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties?rev=966643&r1=966642&r2=966643&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties (original)
+++ incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties Thu Jul 22 13:29:52 2010
@@ -94,7 +94,7 @@ jaxbCreateDefaultJAXBElement=The system
# Failure Messages
mediaTypeWrongFormat=The {0} is not a valid MediaType format. You must use the following format: type/subtype.
unhandledExceptionToContainer=An unhandled exception occurred which will be propagated to the container.
-exceptionOccurredDuringInvocation=The following error occurred during the invocation of the handlers chain: {0}
+exceptionOccurredDuringInvocation=The following error occurred during the invocation of the handlers chain: {0} while processing {1} request sent to {2}
# Contexts
uriBadBaseURI=The following base URI is not valid: {0}
@@ -213,6 +213,10 @@ entityRefsNotSupportedSunJDK5=Entity ref
saxParseException=The system cannot parse the XML content into a {0} instance. Verify that the XML content is valid.
saxParserConfigurationException=The system cannot configure the SAX parser with the given configuration parameter.
badXMLReaderInitialStart=The XMLStreamReader instance has already been partially processed.
+processingRequestTo=Processing {0} request to {1}, source content type is {2}, acceptable media types include {3}
+registeredResources=Registered resources: {0}
+followingProviders=The following JAX-RS providers are registered: {0}
+followingProvidersUserDefined=The following user-defined JAX-RS providers are registered: {0}
+applicationProcessed=The following application has been processed: {0}
multipleHttpMethodAnnotations=Multiple http method annotations on method {0} in class {1}
resourceMethodMoreThanOneEntityParam=The {0} method has more than one entity parameter. You must use only one entity parameter.
-processingRequestTo=Processing {0} request to {1}
Modified: incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLogHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLogHandler.java?rev=966643&r1=966642&r2=966643&view=diff
==============================================================================
--- incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLogHandler.java (original)
+++ incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLogHandler.java Thu Jul 22 13:29:52 2010
@@ -22,34 +22,58 @@ package org.apache.wink.logging;
import java.util.ArrayList;
import java.util.logging.Handler;
+import java.util.logging.Level;
import java.util.logging.LogRecord;
public class WinkLogHandler extends Handler {
+
+ public enum LEVEL {
+ INFO, DEBUG, TRACE
+ }
static private ArrayList<LogRecord> logRecords = new ArrayList<LogRecord>();
static boolean storeLogsOn = false;
+ static LEVEL level;
@Override
public void close() throws SecurityException {
- // TODO Auto-generated method stub
}
@Override
public void flush() {
- // TODO Auto-generated method stub
+ }
+
+ public static Level getLogLevel() {
+ if (level != null) {
+ if (level.equals(LEVEL.INFO)) {
+ return Level.INFO;
+ } else if (level.equals(LEVEL.DEBUG)) {
+ return Level.FINE;
+ } else if (level.equals(LEVEL.TRACE)) {
+ return Level.FINEST;
+ }
+ }
+ return Level.OFF;
}
@Override
public void publish(LogRecord record) {
if (storeLogsOn) {
- logRecords.add(record);
+ if (level.equals(LEVEL.INFO) && record.getLevel().equals(Level.INFO)) {
+ logRecords.add(record);
+ } else if (level.equals(LEVEL.DEBUG) && record.getLevel().equals(Level.FINE)) {
+ logRecords.add(record);
+ } else if (level.equals(LEVEL.TRACE) && record.getLevel().equals(Level.FINEST)) {
+ logRecords.add(record);
+ }
}
}
/**
* turns logging capture on
*/
- public static void turnLoggingCaptureOn() {
+ public static void turnLoggingCaptureOn(LEVEL _level) {
+ level = _level;
storeLogsOn = true;
}
@@ -58,6 +82,7 @@ public class WinkLogHandler extends Hand
*/
public static void turnLoggingCaptureOff() {
storeLogsOn = false;
+ level = null;
}
/**
Modified: incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLoggerAdapter.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLoggerAdapter.java?rev=966643&r1=966642&r2=966643&view=diff
==============================================================================
--- incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLoggerAdapter.java (original)
+++ incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/logging/WinkLoggerAdapter.java Thu Jul 22 13:29:52 2010
@@ -31,16 +31,21 @@ import org.slf4j.spi.LocationAwareLogger
public final class WinkLoggerAdapter extends MarkerIgnoringBase implements
LocationAwareLogger {
- final java.util.logging.Logger logger;
-
+ /*
+ * We create a new Logger instance for each call because we want the level controlled by WinkLogHandler.
+ * It's clunky, but the level is controllable by individual unittest methods, and we need to accommodate that.
+ */
+
+ String loggerName;
+ WinkLogHandler winkLogHandler;
+
WinkLoggerAdapter(java.util.logging.Logger logger) {
- this.logger = logger;
- this.logger.setLevel(Level.FINEST);
- this.logger.addHandler(new WinkLogHandler());
+ winkLogHandler = new WinkLogHandler();
+ loggerName = logger.getName();
}
public boolean isTraceEnabled() {
- return logger.isLoggable(Level.FINEST);
+ return WinkLogHandler.getLogLevel().equals(Level.FINEST);
}
public void trace(String message) {
@@ -64,7 +69,7 @@ public final class WinkLoggerAdapter ext
}
public boolean isDebugEnabled() {
- return logger.isLoggable(Level.FINE);
+ return WinkLogHandler.getLogLevel().equals(Level.FINE);
}
public void debug(String msg) {
@@ -88,7 +93,7 @@ public final class WinkLoggerAdapter ext
}
public boolean isInfoEnabled() {
- return logger.isLoggable(Level.INFO);
+ return WinkLogHandler.getLogLevel().equals(Level.INFO);
}
public void info(String msg) {
@@ -112,7 +117,7 @@ public final class WinkLoggerAdapter ext
}
public boolean isWarnEnabled() {
- return logger.isLoggable(Level.WARNING);
+ return WinkLogHandler.getLogLevel().equals(Level.WARNING);
}
public void warn(String msg) {
@@ -136,7 +141,7 @@ public final class WinkLoggerAdapter ext
}
public boolean isErrorEnabled() {
- return logger.isLoggable(Level.SEVERE);
+ return WinkLogHandler.getLogLevel().equals(Level.SEVERE);
}
public void error(String msg) {
@@ -162,8 +167,14 @@ public final class WinkLoggerAdapter ext
private void log(Level level, String msg, Throwable t) {
LogRecord record = new LogRecord(level, msg);
record.setThrown(t);
+ java.util.logging.Logger logger = java.util.logging.Logger.getLogger(loggerName);
+ logger.setLevel(WinkLogHandler.getLogLevel());
+ // all of the WinkLogHander internals are static, so despite having a new instance
+ // of Logger and WinkLogHandler, we'll get the expected log records
+ logger.addHandler(winkLogHandler);
record.setLoggerName(logger.getName());
logger.log(record);
+ logger.removeHandler(winkLogHandler);
}
public void log(Marker marker, String caller, int level, String message,
Modified: incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/RequestProcessor.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/RequestProcessor.java?rev=966643&r1=966642&r2=966643&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/RequestProcessor.java (original)
+++ incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/RequestProcessor.java Thu Jul 22 13:29:52 2010
@@ -42,6 +42,8 @@ import org.apache.wink.server.internal.a
import org.apache.wink.server.internal.handlers.SearchResult;
import org.apache.wink.server.internal.handlers.ServerMessageContext;
import org.apache.wink.server.internal.registry.ResourceInstance;
+import org.apache.wink.server.internal.registry.ResourceRecord;
+import org.apache.wink.server.internal.registry.ResourceRegistry;
import org.apache.wink.server.internal.resources.HtmlServiceDocumentResource;
import org.apache.wink.server.internal.resources.RootResource;
import org.apache.wink.server.utils.RegistrationUtils;
@@ -56,18 +58,21 @@ public class RequestProcessor {
private static final Logger logger =
LoggerFactory
.getLogger(RequestProcessor.class);
- private static final String PROPERTY_ROOT_RESOURCE_NONE = "none"; //$NON-NLS-1$
- private static final String PROPERTY_ROOT_RESOURCE_ATOM = "atom"; //$NON-NLS-1$
- private static final String PROPERTY_ROOT_RESOURCE_ATOM_HTML = "atom+html"; //$NON-NLS-1$
+ private static final String PROPERTY_ROOT_RESOURCE_NONE = "none"; //$NON-NLS-1$
+ private static final String PROPERTY_ROOT_RESOURCE_ATOM = "atom"; //$NON-NLS-1$
+ private static final String PROPERTY_ROOT_RESOURCE_ATOM_HTML = "atom+html"; //$NON-NLS-1$
private static final String PROPERTY_ROOT_RESOURCE_DEFAULT =
PROPERTY_ROOT_RESOURCE_ATOM_HTML;
- private static final String PROPERTY_ROOT_RESOURCE = "wink.rootResource"; //$NON-NLS-1$
+ private static final String PROPERTY_ROOT_RESOURCE = "wink.rootResource"; //$NON-NLS-1$
private static final String PROPERTY_ROOT_RESOURCE_CSS =
- "wink.serviceDocumentCssPath"; //$NON-NLS-1$
+ "wink.serviceDocumentCssPath"; //$NON-NLS-1$
private static final String PROPERTY_LOAD_WINK_APPLICATIONS =
- "wink.loadApplications"; //$NON-NLS-1$
+ "wink.loadApplications"; //$NON-NLS-1$
private final DeploymentConfiguration configuration;
+
+ private String requestString; // save off the request string in case we need to log it
+ private String requestMethod; // save off the request method in case we need to log it
public RequestProcessor(DeploymentConfiguration configuration) {
this.configuration = configuration;
@@ -134,14 +139,11 @@ public class RequestProcessor {
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException {
try {
+ requestMethod = request.getMethod();
+ requestString = request.getRequestURL().toString();
+ requestString += ((request.getQueryString() != null && request.getQueryString().length() > 0) ? ("?" + request.getQueryString()) : ""); //$NON-NLS-1$ $NON-NLS-2$
if (logger.isDebugEnabled()) {
- String requestString = request.getProtocol() + "://"; //$NON-NLS-1$
- requestString += ((request.getLocalName() != null && request.getLocalName().length() > 0) ? request.getLocalName() : request.getLocalAddr());
- requestString += ":"; //$NON-NLS-1$
- requestString += request.getLocalPort();
- requestString += request.getRequestURI();
- requestString += ((request.getQueryString() != null && request.getQueryString().length() > 0) ? ("?" + request.getQueryString()) : ""); //$NON-NLS-1$ $NON-NLS-2$
- logger.debug(Messages.getMessage("processingRequestTo", request.getMethod(), requestString)); //$NON-NLS-1$
+ logger.debug(Messages.getMessage("processingRequestTo", requestMethod, requestString, request.getContentType(), request.getHeader("Accept"))); //$NON-NLS-1$ $NON-NLS-2$
}
handleRequestWithoutFaultBarrier(request, response);
} catch (Throwable t) {
@@ -176,12 +178,12 @@ public class RequestProcessor {
// run the response handler chain
configuration.getResponseHandlersChain().run(msgContext);
- logger.trace("Attempting to release resource instance"); //$NON-NLS-1$
+ logger.trace("Attempting to release resource instance");
isReleaseResourcesCalled = true;
try {
releaseResources(msgContext);
} catch (Exception e) {
- logger.trace("Caught exception when releasing resource object", e); //$NON-NLS-1$
+ logger.trace("Caught exception when releasing resource object", e);
throw e;
}
} catch (Throwable t) {
@@ -202,7 +204,7 @@ public class RequestProcessor {
try {
releaseResources(originalContext);
} catch (Exception e2) {
- logger.trace("Caught exception when releasing resource object", e2); //$NON-NLS-1$
+ logger.trace("Caught exception when releasing resource object", e2);
}
}
} catch (Exception e) {
@@ -212,7 +214,7 @@ public class RequestProcessor {
try {
releaseResources(originalContext);
} catch (Exception e2) {
- logger.trace("Caught exception when releasing resource object", e2); //$NON-NLS-1$
+ logger.trace("Caught exception when releasing resource object", e2);
}
}
throw e;
@@ -228,16 +230,14 @@ public class RequestProcessor {
if (searchResult != null) {
List<ResourceInstance> resourceInstances = searchResult.getData().getMatchedResources();
for (ResourceInstance res : resourceInstances) {
- logger.trace("Releasing resource instance"); //$NON-NLS-1$
+ logger.trace("Releasing resource instance");
res.releaseInstance(msgContext);
}
}
}
private void logException(Throwable t) {
- String exceptionName = t.getClass().getSimpleName();
- String messageFormat =
- Messages.getMessage("exceptionOccurredDuringInvocation", exceptionName); //$NON-NLS-1$
+ String messageFormat;
if (t instanceof WebApplicationException) {
WebApplicationException wae = (WebApplicationException)t;
int statusCode = wae.getResponse().getStatus();
@@ -248,32 +248,28 @@ public class RequestProcessor {
statusSep = " - "; //$NON-NLS-1$
statusMessage = status.toString();
}
- exceptionName =
- String.format("%s (%d%s%s)", exceptionName, statusCode, statusSep, statusMessage); //$NON-NLS-1$
- if (statusCode >= 500) {
- if (logger.isDebugEnabled()) {
- logger.debug(messageFormat, t); //$NON-NLS-1$
- } else {
- logger.info(messageFormat); //$NON-NLS-1$
- }
- } else {
- // don't log the whole call stack for sub-500 return codes unless debugging
- if (logger.isDebugEnabled()) {
- logger.debug(messageFormat, t); //$NON-NLS-1$
- } else {
- logger.info(messageFormat); //$NON-NLS-1$
- }
- }
+ String exceptionName =
+ String.format("%s (%d%s%s)", t.getClass().getSimpleName(), statusCode, statusSep, statusMessage); //$NON-NLS-1$
+ messageFormat = Messages.getMessage("exceptionOccurredDuringInvocation", exceptionName, requestMethod, requestString); //$NON-NLS-1$
} else {
- if (logger.isDebugEnabled()) {
- logger.debug(messageFormat, t); //$NON-NLS-1$
- } else {
- logger.info(messageFormat); //$NON-NLS-1$
+ messageFormat = Messages.getMessage("exceptionOccurredDuringInvocation", t.getClass().getSimpleName(), requestMethod, requestString); //$NON-NLS-1$
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug(messageFormat, t);
+ ResourceRegistry rr = this.configuration.getResourceRegistry();
+ List<ResourceRecord> resourceRecords = rr.getRecords();
+ StringBuffer sb = new StringBuffer();
+ for (ResourceRecord record : resourceRecords) {
+ sb.append("\n " + record.toString()); //$NON-NLS-1$
}
+ logger.debug(Messages.getMessage("registeredResources", (sb.toString().length() > 0) ? sb.toString() : "{}")); //$NON-NLS-1$ $NON-NLS-2$
+ logger.debug(this.configuration.getProvidersRegistry().getLogFormattedProvidersList(true));
+ } else {
+ logger.info(messageFormat);
}
}
- private ServerMessageContext createMessageContext(HttpServletRequest request,
+ private ServerMessageContext createMessageContext(HttpServletRequest request,
HttpServletResponse response) {
ServerMessageContext messageContext =
new ServerMessageContext(request, response, configuration);
Modified: incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/application/ApplicationProcessor.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/application/ApplicationProcessor.java?rev=966643&r1=966642&r2=966643&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/application/ApplicationProcessor.java (original)
+++ incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/application/ApplicationProcessor.java Thu Jul 22 13:29:52 2010
@@ -19,6 +19,7 @@
*******************************************************************************/
package org.apache.wink.server.internal.application;
+import java.util.List;
import java.util.Set;
import javax.ws.rs.core.Application;
@@ -28,6 +29,7 @@ import org.apache.wink.common.internal.i
import org.apache.wink.common.internal.registry.ProvidersRegistry;
import org.apache.wink.common.internal.registry.metadata.ProviderMetadataCollector;
import org.apache.wink.common.internal.registry.metadata.ResourceMetadataCollector;
+import org.apache.wink.server.internal.registry.ResourceRecord;
import org.apache.wink.server.internal.registry.ResourceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -89,6 +91,17 @@ public class ApplicationProcessor {
processWinkApplication((WinkApplication)application);
}
+ // always produce INFO output after completing application processing:
+ logger.info(Messages.getMessage("applicationProcessed", application.getClass().getName())); //$NON-NLS-1$
+ List<ResourceRecord> resourceRecords = resourceRegistry.getRecords();
+ StringBuffer sb = new StringBuffer();
+ for (ResourceRecord record : resourceRecords) {
+ sb.append("\n " + record.toString()); //$NON-NLS-1$
+ }
+ logger.info(Messages.getMessage("registeredResources", (sb.length() > 0) ? sb.toString() : "{}")); //$NON-NLS-1$ $NON-NLS-2$
+ logger.info(providersRegistry.getLogFormattedProvidersList(true));
+ // done with INFO
+
logger.trace("Processing of Application completed."); //$NON-NLS-1$
}
@@ -123,13 +136,17 @@ public class ApplicationProcessor {
}
}
} catch (Exception e) {
- logger.warn(Messages.getMessage("exceptionOccurredDuringInstanceProcessing", obj //$NON-NLS-1$
- .getClass().getCanonicalName()));
- logger.warn(Messages.getMessage("listExceptionDuringInstanceProcessing"), e); //$NON-NLS-1$
+ if (logger.isWarnEnabled()) {
+ logger.warn(Messages.getMessage("exceptionOccurredDuringInstanceProcessing", obj //$NON-NLS-1$
+ .getClass().getCanonicalName()));
+ logger.warn(Messages.getMessage("listExceptionDuringInstanceProcessing"), e); //$NON-NLS-1$
+ }
} catch (NoClassDefFoundError e) {
- logger.warn(Messages.getMessage("exceptionOccurredDuringInstanceProcessing", obj //$NON-NLS-1$
- .getClass().getCanonicalName()));
- logger.warn(Messages.getMessage("listExceptionDuringInstanceProcessing"), e); //$NON-NLS-1$
+ if (logger.isWarnEnabled()) {
+ logger.warn(Messages.getMessage("exceptionOccurredDuringInstanceProcessing", obj //$NON-NLS-1$
+ .getClass().getCanonicalName()));
+ logger.warn(Messages.getMessage("listExceptionDuringInstanceProcessing"), e); //$NON-NLS-1$
+ }
}
}
}
Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ProvidersRegistrySystemTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ProvidersRegistrySystemTest.java?rev=966643&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ProvidersRegistrySystemTest.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ProvidersRegistrySystemTest.java Thu Jul 22 13:29:52 2010
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *******************************************************************************/
+package org.apache.wink.server.internal.registry;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.wink.common.internal.application.ApplicationFileLoader;
+import org.apache.wink.common.internal.providers.entity.StringProvider;
+import org.apache.wink.common.internal.registry.ProvidersRegistry;
+import org.apache.wink.server.internal.DeploymentConfiguration;
+import org.apache.wink.server.internal.RequestProcessor;
+import org.apache.wink.server.internal.registry.providers.Provider1;
+import org.apache.wink.server.internal.registry.providers.Provider2;
+import org.apache.wink.server.internal.registry.providers.Provider3;
+import org.apache.wink.server.internal.registry.providers.Provider4;
+import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
+import org.apache.wink.server.internal.servlet.RestServlet;
+import org.apache.wink.test.mock.MockRequestConstructor;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+public class ProvidersRegistrySystemTest extends MockServletInvocationTest {
+
+ private static File winkprovidersFile = null;
+ private static File winkapplicationFile = null;
+ private static String rootPath = null;
+ private static final String backupExt = "_backup";
+
+ // store this instance so we can check that it was loaded from getSingletons after our Application has loaded
+ private static Provider1 provider1Singleton = new Provider1();
+
+ @Override
+ protected void setUp() throws Exception {
+
+ Field defaultFileField = ApplicationFileLoader.class.getDeclaredField("CORE_APPLICATION");
+ defaultFileField.setAccessible(true);
+ String filePath = (String)defaultFileField.get(null);
+ if (!filePath.startsWith("/")) {
+ filePath = "/" + filePath;
+ }
+
+ // use the path where CORE_APPLICATION is found as the root for the WINK_APPLICATION file
+ String classPath = System.getProperty("java.class.path");
+ StringTokenizer tokenizer = new StringTokenizer(classPath, System.getProperty("path.separator"));
+ while (tokenizer.hasMoreElements()) {
+ String temp = tokenizer.nextToken();
+ if (temp.contains("test-classes")) {
+ rootPath = temp;
+ break;
+ }
+ }
+
+ // save a backup of winkprovidersFile if it exists:
+ copyfile(rootPath + filePath, rootPath + filePath + backupExt);
+
+ // create a custom wink-providers file with known entries for this test
+ ArrayList<String> lines = new ArrayList<String>();
+ lines.add(Provider1.class.getName()); // should be ignored due to it already being listed in getSingletons
+ lines.add(Provider2.class.getName()); // should be ignored due to it already being listed in getClasses
+ lines.add(Provider3.class.getName()); // accepted
+ lines.add(StringProvider.class.getName()); // accepted, need it to complete end to end test
+ winkprovidersFile = createFile(rootPath + filePath, lines.toArray(new String[0]));
+
+ defaultFileField = ApplicationFileLoader.class.getDeclaredField("WINK_APPLICATION");
+ defaultFileField.setAccessible(true);
+ filePath = (String)defaultFileField.get(null);
+ if (!filePath.startsWith("/")) {
+ filePath = "/" + filePath;
+ }
+
+ // create a custom wink-application file with known entries for this test
+ lines = new ArrayList<String>();
+ lines.add(Provider1.class.getName()); // should be ignored due to it already being listed in getSingletons
+ lines.add(Provider2.class.getName()); // should be ignored due to it already being listed in getClasses
+ lines.add(Provider3.class.getName()); // should be ignored due to it already being listed in wink-providers
+ lines.add(Provider4.class.getName()); // accepted
+ winkapplicationFile = createFile(rootPath + filePath, lines.toArray(new String[0]));
+
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (!winkapplicationFile.delete()) {
+ fail("failed to delete file " + winkapplicationFile.getPath());
+ }
+ if (!winkprovidersFile.delete()) {
+ fail("failed to delete file " + winkprovidersFile.getPath());
+ }
+ // restore the backup:
+ copyfile(winkprovidersFile.getPath() + backupExt, winkprovidersFile.getPath());
+ super.tearDown();
+ }
+
+ @Override
+ protected String getApplicationClassName() {
+ return MyApplication.class.getName();
+ }
+
+ public static class MyApplication extends Application {
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ HashSet<Class<?>> set = new LinkedHashSet<Class<?>>();
+ set.add(Provider1.class); // Provider1 should be ignored due to it already being listed in getSingletons
+ set.add(Provider2.class); // accepted
+ return set;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ HashSet<Object> set = new LinkedHashSet<Object>();
+ set.add(provider1Singleton);
+ set.add(new Provider1()); // should be ignored due to provider1Singleton already being listed
+ set.add(new ECHOResource());
+ return set;
+ }
+
+ }
+
+ @Path("/test")
+ public static class ECHOResource {
+
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Produces(MediaType.TEXT_PLAIN)
+ @Path("priority")
+ public String echoString(String string) {
+ return string;
+ }
+ }
+
+ /**
+ * Test the order of loading and the prioritization of Providers based on that loading order.
+ *
+ * NOTE: this test depends on the MockServletInvocationTest continuing to use LinkedHashSet in its
+ * getClasses and getSingletons methods
+ *
+ */
+ public void testProviderPrioritization() throws Exception {
+
+ // make sure all the lists were read and processed by tracking the number of hits to the ctors
+
+ Provider1 p1 = new Provider1();
+ assertEquals(5, p1.getNumCtorHits());
+
+ Provider2 p2 = new Provider2();
+ assertEquals(3, p2.getNumCtorHits());
+
+ Provider3 p3 = new Provider3();
+ assertEquals(2, p3.getNumCtorHits());
+
+ Provider4 p4 = new Provider4();
+ assertEquals(2, p4.getNumCtorHits());
+
+ // to actually inspect the list in the 'data' object in the MessageBodyReaders in the ProvidersRegistry would take a lot of
+ // reflection and hacking. We'll at least confirm that only 5 (due to AssetProvider) are in the ProvidersRegistry.
+
+ RestServlet servlet = (RestServlet)this.getServlet();
+ ServletContext context = servlet.getServletContext();
+ RequestProcessor processor = (RequestProcessor) context.getAttribute(RequestProcessor.class.getName());
+ DeploymentConfiguration config = processor.getConfiguration();
+ ProvidersRegistry providersRegistry = config.getProvidersRegistry();
+ // to confirm that the ignores are indeed happening, I need to get the private field
+ // "messageBodyReaders" object, then it's superclass "data" object and inspect it:
+ Field field = providersRegistry.getClass().getDeclaredField("messageBodyReaders");
+ field.setAccessible(true);
+ Object messageBodyReaders = field.get(providersRegistry);
+ Field field2 = messageBodyReaders.getClass().getSuperclass().getDeclaredField("data");
+ field2.setAccessible(true);
+ HashMap data = (HashMap)field2.get(messageBodyReaders);
+ HashSet readers = (HashSet)data.get(MediaType.WILDCARD_TYPE);
+
+ assertEquals(6, readers.size());
+
+ // under the covers, the "list" is a treeset, so the iterator does not really tell us any info about the sort
+ Set<String> expectedSet = new HashSet<String>(6);
+ expectedSet.add("Priority: 0.500000, ObjectFactory: SingletonOF: " + org.apache.wink.server.internal.registry.providers.Provider1.class.getName());
+ expectedSet.add("Priority: 0.100000, ObjectFactory: ClassMetadataPrototypeOF Class: " + org.apache.wink.common.internal.providers.entity.AssetProvider.class.getName());
+ expectedSet.add("Priority: 0.100000, ObjectFactory: SingletonOF: " + org.apache.wink.server.internal.registry.providers.Provider3.class.getName());
+ expectedSet.add("Priority: 0.500000, ObjectFactory: SingletonOF: " + org.apache.wink.server.internal.registry.providers.Provider2.class.getName());
+ expectedSet.add("Priority: 0.100000, ObjectFactory: SingletonOF: " + org.apache.wink.server.internal.registry.providers.Provider4.class.getName());
+ expectedSet.add("Priority: 0.100000, ObjectFactory: SingletonOF: " + StringProvider.class.getName());
+
+ // this is obviously not the best way to check this. If toString() output is changed, or the TreeSet implementation is modified,
+ // this test code will also have to be modified. Also, can't check order of the readers HashSet. But we're compatible with other
+ // locales now.
+ int count = 0;
+ for (Iterator it = readers.iterator(); it.hasNext();) {
+ Object obj = it.next();
+ assertTrue(obj.toString(), expectedSet.contains(obj.toString()));
+ count++;
+ }
+
+ // do a real transaction too to confirm that the listing in getClasses took the top spot
+
+ MockHttpServletRequest request =
+ MockRequestConstructor.constructMockRequest("POST",
+ "/test/priority",
+ MediaType.TEXT_PLAIN,
+ MediaType.TEXT_PLAIN,
+ "".getBytes());
+ MockHttpServletResponse response = invoke(request);
+ assertEquals(200, response.getStatus());
+ // make sure the first instance processed has top priority, and that it is indeed the first instance of Provider2 (because it was given
+ // higher priority due to getClasses being processed after getSingletons)
+ assertEquals(Provider2.class.getName() + "_" + p2.getFirstInstanceHashCode(), response.getContentAsString());
+
+ }
+
+ // utility method
+ private File createFile(String filePath, String[] lines) throws Exception {
+
+ File propFile = new File(filePath);
+ if (!propFile.exists()) {
+ File dir = new File(filePath.substring(0, filePath.lastIndexOf("/")));
+ dir.mkdirs();
+ propFile.createNewFile();
+ }
+ FileWriter fileWriter = new FileWriter(propFile);
+ for (int i = 0; i < lines.length; i++) {
+ fileWriter.write(lines[i]);
+ fileWriter.write(System.getProperty("line.separator"));
+ }
+ fileWriter.flush();
+ fileWriter.close();
+ return propFile;
+ }
+
+ private static void copyfile(String sourceFile, String destinationFile) throws Exception {
+ try {
+ File f1 = new File(sourceFile);
+ File f2 = new File(destinationFile);
+ InputStream in = new FileInputStream(f1);
+
+ OutputStream out = new FileOutputStream(f2);
+
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0){
+ out.write(buf, 0, len);
+ }
+ in.close();
+ out.close();
+ } catch (Exception e) {
+ // ignore
+ }
+
+ }
+
+}
\ No newline at end of file
Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/IProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/IProvider.java?rev=966643&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/IProvider.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/IProvider.java Thu Jul 22 13:29:52 2010
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *******************************************************************************/
+
+package org.apache.wink.server.internal.registry.providers;
+
+import javax.ws.rs.ext.MessageBodyReader;
+
+public interface IProvider extends MessageBodyReader<String> {
+
+ /**
+ * implementors must count the number of hits to their constructor(s)
+ * @return number of hits to the constructor
+ */
+ public int getNumCtorHits();
+
+ /**
+ * implementors should track the hashcode of the first instance created
+ * @return first created instance's hashcode
+ */
+ public int getFirstInstanceHashCode();
+
+}
Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider1.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider1.java?rev=966643&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider1.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider1.java Thu Jul 22 13:29:52 2010
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *******************************************************************************/
+
+package org.apache.wink.server.internal.registry.providers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+@Consumes
+@Produces
+public class Provider1 implements IProvider {
+
+ static private int ctorHits = 0;
+ static private int firstInstanceHashcode = 0;
+
+ public Provider1() {
+ ctorHits++;
+ if (firstInstanceHashcode == 0) {
+ firstInstanceHashcode = hashCode();
+ }
+ }
+
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return true;
+ }
+
+ public String readFrom(Class<String> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException {
+ return this.getClass().getName() + "_" + hashCode();
+ }
+
+ public int getNumCtorHits() {
+ return ctorHits;
+ }
+
+ public int getFirstInstanceHashCode() {
+ return firstInstanceHashcode;
+ }
+
+}
\ No newline at end of file
Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider2.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider2.java?rev=966643&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider2.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider2.java Thu Jul 22 13:29:52 2010
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *******************************************************************************/
+
+package org.apache.wink.server.internal.registry.providers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+@Consumes
+@Produces
+public class Provider2 implements IProvider {
+
+ private static int ctorHits = 0;
+ private static int firstInstanceHashcode = 0;
+
+ public Provider2() {
+ ctorHits++;
+ if (firstInstanceHashcode == 0) {
+ firstInstanceHashcode = hashCode();
+ }
+ }
+
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return true;
+ }
+
+ public String readFrom(Class<String> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException {
+ return this.getClass().getName() + "_" + hashCode();
+ }
+
+ public int getNumCtorHits() {
+ return ctorHits;
+ }
+
+ public int getFirstInstanceHashCode() {
+ return firstInstanceHashcode;
+ }
+
+}
\ No newline at end of file
Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider3.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider3.java?rev=966643&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider3.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider3.java Thu Jul 22 13:29:52 2010
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *******************************************************************************/
+
+package org.apache.wink.server.internal.registry.providers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+@Consumes
+@Produces
+public class Provider3 implements IProvider {
+
+ private static int ctorHits = 0;
+ private static int firstInstanceHashcode = 0;
+
+ public Provider3() {
+ ctorHits++;
+ if (firstInstanceHashcode == 0) {
+ firstInstanceHashcode = hashCode();
+ }
+ }
+
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return true;
+ }
+
+ public String readFrom(Class<String> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException {
+ return this.getClass().getName() + "_" + hashCode();
+ }
+
+ public int getNumCtorHits() {
+ return ctorHits;
+ }
+
+ public int getFirstInstanceHashCode() {
+ return firstInstanceHashcode;
+ }
+
+}
\ No newline at end of file
Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider4.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider4.java?rev=966643&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider4.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/providers/Provider4.java Thu Jul 22 13:29:52 2010
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *******************************************************************************/
+
+package org.apache.wink.server.internal.registry.providers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+@Consumes
+@Produces
+public class Provider4 implements IProvider {
+
+ private static int ctorHits = 0;
+ private static int firstInstanceHashcode = 0;
+
+ public Provider4() {
+ ctorHits++;
+ if (firstInstanceHashcode == 0) {
+ firstInstanceHashcode = hashCode();
+ }
+ }
+
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return true;
+ }
+
+ public String readFrom(Class<String> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException {
+ return this.getClass().getName() + "_" + hashCode();
+ }
+
+ public int getNumCtorHits() {
+ return ctorHits;
+ }
+
+ public int getFirstInstanceHashCode() {
+ return firstInstanceHashcode;
+ }
+
+}
\ No newline at end of file
Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/serviceability/ServiceabilityTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/serviceability/ServiceabilityTest.java?rev=966643&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/serviceability/ServiceabilityTest.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/serviceability/ServiceabilityTest.java Thu Jul 22 13:29:52 2010
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wink.server.serviceability;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.LogRecord;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.wink.common.internal.application.ApplicationValidator;
+import org.apache.wink.common.internal.lifecycle.LifecycleManagersRegistry;
+import org.apache.wink.common.internal.registry.ProvidersRegistry;
+import org.apache.wink.logging.WinkLogHandler;
+import org.apache.wink.server.internal.application.ApplicationProcessor;
+import org.apache.wink.server.internal.registry.ResourceRegistry;
+import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
+import org.apache.wink.test.mock.MockRequestConstructor;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+/**
+ *
+ * When running this test in Eclipse or another IDE, make sure project wink-component-test-support is first in the classpath
+ * so that SLF4J picks up the SLF4J bridge provided from it. Otherwise, you'll get no log output to assert against.
+ *
+ */
+public class ServiceabilityTest extends MockServletInvocationTest {
+
+ @Override
+ protected Class<?>[] getClasses() {
+ return new Class<?>[]{MyResource.class, MyContextResolver.class, MyContextResolver1.class};
+ }
+
+ @Path("/root")
+ public static class MyResource {
+
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String getTEXT() {
+ return "some text";
+ }
+
+ @GET
+ @Produces(MediaType.TEXT_HTML)
+ public String getHTML() {
+ return "some html";
+ }
+
+ @GET
+ @Path("2")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String getTEXT2() {
+ return "some text 2";
+ }
+
+ }
+
+ // intentionally forgetting @Provider annotation as part of test
+ public static class MyContextResolver implements ContextResolver {
+ public Object getContext(Class type) {
+ return null;
+ }
+ }
+
+ @Provider
+ public static class MyContextResolver1 implements ContextResolver {
+ public Object getContext(Class type) {
+ return null;
+ }
+ }
+
+ public static class MyApp extends Application {
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> classes = new HashSet<Class<?>>();
+ classes.add(MyAppResource.class);
+ return classes;
+ }
+
+ @Path("/myapp")
+ public static class MyAppResource {
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ @Path("gettext")
+ public String getTEXT() {
+ return "some private text";
+ }
+ }
+
+ }
+
+ public static class MockAppValidator extends ApplicationValidator {
+
+ @Override
+ public boolean isValidProvider(Class<?> cls) {
+ return true;
+ }
+
+ @Override
+ public boolean isValidResource(Class<?> cls) {
+ return true;
+ }
+
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ WinkLogHandler.clearRecords();
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ WinkLogHandler.clearRecords();
+ super.tearDown();
+ }
+
+ public void testGoodAppStartupInfoLogOutput() throws Exception {
+ WinkLogHandler.turnLoggingCaptureOn(WinkLogHandler.LEVEL.INFO);
+ MockAppValidator mockAppValidator = new MockAppValidator();
+ ResourceRegistry mockResourceRegistry = new ResourceRegistry(new LifecycleManagersRegistry(), mockAppValidator);
+ ProvidersRegistry mockProvidersRegistry = new ProvidersRegistry(new LifecycleManagersRegistry(), mockAppValidator);
+ ApplicationProcessor appProcessor = new ApplicationProcessor(new MyApp(), mockResourceRegistry, mockProvidersRegistry, false);
+ appProcessor.process();
+ WinkLogHandler.turnLoggingCaptureOff();
+ ArrayList<LogRecord> records = WinkLogHandler.getRecords();
+
+ assertEquals(3, records.size());
+ assertEquals("The following application has been processed: org.apache.wink.server.serviceability.ServiceabilityTest$MyApp", records.get(0).getMessage());
+ assertEquals("Registered resources: \n" +
+ " Path: myapp; ClassMetadata: Class: org.apache.wink.server.serviceability.ServiceabilityTest$MyApp$MyAppResource", records.get(1).getMessage());
+ assertEquals("The following user-defined JAX-RS providers are registered: \n" +
+ "RawType: interface javax.ws.rs.ext.ContextResolver\n" +
+ "Data Map: {empty}\n" +
+ "RawType: interface javax.ws.rs.ext.MessageBodyReader\n" +
+ "Data Map: {empty}\n" +
+ "RawType: interface javax.ws.rs.ext.MessageBodyWriter\n" +
+ "Data Map: {empty}", records.get(2).getMessage());
+ }
+
+ public void testGoodURLLogOutput1() throws Exception {
+ WinkLogHandler.turnLoggingCaptureOn(WinkLogHandler.LEVEL.DEBUG);
+
+ MockHttpServletRequest mockRequest =
+ MockRequestConstructor.constructMockRequest("GET", "/root", MediaType.TEXT_PLAIN);
+ MockHttpServletResponse mockResponse = invoke(mockRequest);
+ assertEquals(200, mockResponse.getStatus());
+ assertEquals("some text", mockResponse.getContentAsString());
+
+ WinkLogHandler.turnLoggingCaptureOff();
+ ArrayList<LogRecord> records = WinkLogHandler.getRecords();
+
+ assertEquals(1, records.size());
+ assertEquals("Processing GET request to http://localhost:80/root, source content type is null, acceptable media types include text/plain", records.get(0).getMessage());
+ }
+
+ public void testGoodURLLogOutput2() throws Exception {
+ WinkLogHandler.turnLoggingCaptureOn(WinkLogHandler.LEVEL.DEBUG);
+
+ MockHttpServletRequest mockRequest =
+ MockRequestConstructor.constructMockRequest("GET", "/root", MediaType.TEXT_HTML);
+ MockHttpServletResponse mockResponse = invoke(mockRequest);
+ assertEquals(200, mockResponse.getStatus());
+ assertEquals("some html", mockResponse.getContentAsString());
+
+ WinkLogHandler.turnLoggingCaptureOff();
+ ArrayList<LogRecord> records = WinkLogHandler.getRecords();
+
+ assertEquals(1, records.size());
+ assertEquals("Processing GET request to http://localhost:80/root, source content type is null, acceptable media types include text/html", records.get(0).getMessage());
+ }
+
+ public void testGoodURLLogOutput3() throws Exception {
+ WinkLogHandler.turnLoggingCaptureOn(WinkLogHandler.LEVEL.DEBUG);
+
+ MockHttpServletRequest mockRequest =
+ MockRequestConstructor.constructMockRequest("GET", "/root", MediaType.TEXT_PLAIN);
+ mockRequest.setQueryString("param1=value1");
+ MockHttpServletResponse mockResponse = invoke(mockRequest);
+ assertEquals(200, mockResponse.getStatus());
+ assertEquals("some text", mockResponse.getContentAsString());
+
+ WinkLogHandler.turnLoggingCaptureOff();
+ ArrayList<LogRecord> records = WinkLogHandler.getRecords();
+
+ assertEquals(1, records.size());
+ assertEquals("Processing GET request to http://localhost:80/root?param1=value1, source content type is null, acceptable media types include text/plain", records.get(0).getMessage());
+ }
+
+ public void testGoodURLLogOutput4() throws Exception {
+ WinkLogHandler.turnLoggingCaptureOn(WinkLogHandler.LEVEL.DEBUG);
+
+ MockHttpServletRequest mockRequest =
+ MockRequestConstructor.constructMockRequest("GET", "/root/2", MediaType.TEXT_PLAIN);
+ MockHttpServletResponse mockResponse = invoke(mockRequest);
+ assertEquals(200, mockResponse.getStatus());
+ assertEquals("some text 2", mockResponse.getContentAsString());
+
+ WinkLogHandler.turnLoggingCaptureOff();
+ ArrayList<LogRecord> records = WinkLogHandler.getRecords();
+
+ assertEquals(1, records.size());
+ assertEquals("Processing GET request to http://localhost:80/root/2, source content type is null, acceptable media types include text/plain", records.get(0).getMessage());
+ }
+
+ public void testBadURLLogOutput1() throws Exception {
+ WinkLogHandler.turnLoggingCaptureOn(WinkLogHandler.LEVEL.INFO);
+
+ MockHttpServletRequest mockRequest =
+ MockRequestConstructor.constructMockRequest("GET", "/root/BAD", MediaType.TEXT_PLAIN);
+ MockHttpServletResponse mockResponse = invoke(mockRequest);
+ assertEquals(404, mockResponse.getStatus());
+
+ WinkLogHandler.turnLoggingCaptureOff();
+ ArrayList<LogRecord> records = WinkLogHandler.getRecords();
+
+ assertEquals(1, records.size());
+ assertEquals("The following error occurred during the invocation of the handlers chain: WebApplicationException (404 - Not Found) while processing GET request sent to http://localhost:80/root/BAD", records.get(0).getMessage());
+ assertNull(records.get(0).getThrown()); // when NOT in debug mode, exception should NOT show up in the debug trace
+ }
+
+ public void testBadURLLogOutput2() throws Exception {
+ WinkLogHandler.turnLoggingCaptureOn(WinkLogHandler.LEVEL.DEBUG);
+
+ MockHttpServletRequest mockRequest =
+ MockRequestConstructor.constructMockRequest("GET", "/root/BAD", MediaType.TEXT_PLAIN);
+ MockHttpServletResponse mockResponse = invoke(mockRequest);
+ assertEquals(404, mockResponse.getStatus());
+
+ WinkLogHandler.turnLoggingCaptureOff();
+ ArrayList<LogRecord> records = WinkLogHandler.getRecords();
+
+ assertEquals(4, records.size());
+ assertEquals("Processing GET request to http://localhost:80/root/BAD, source content type is null, acceptable media types include text/plain", records.get(0).getMessage());
+ assertEquals("The following error occurred during the invocation of the handlers chain: WebApplicationException (404 - Not Found) while processing GET request sent to http://localhost:80/root/BAD", records.get(1).getMessage());
+ assertNotNull(records.get(1).getThrown()); // when in debug mode, exception should show up in the debug trace
+ assertEquals("Registered resources: \n" +
+ " Path: root; ClassMetadata: Class: org.apache.wink.server.serviceability.ServiceabilityTest$MyResource\n" +
+ " Path: ; ClassMetadata: Class: org.apache.wink.server.internal.resources.HtmlServiceDocumentResource", records.get(2).getMessage());
+ assertEquals("The following user-defined JAX-RS providers are registered: \n" +
+ "RawType: interface javax.ws.rs.ext.ContextResolver\nData Map: \n" +
+ "MediaType key = */*\n" +
+ "ObjectFactory Set value = {\n" +
+ " class org.apache.wink.server.serviceability.ServiceabilityTest$MyContextResolver1\n" +
+ "}\n" +
+ "\nRawType: interface javax.ws.rs.ext.MessageBodyReader\nData Map: {empty}" +
+ "\nRawType: interface javax.ws.rs.ext.MessageBodyWriter\nData Map: {empty}", records.get(3).getMessage());
+ }
+
+}