From f06fd06706145bb4ef9a4ec7a1eabb3a2a2cb3db Mon Sep 17 00:00:00 2001 From: ribeaudc <ribeaudc> Date: Mon, 25 Feb 2008 15:10:16 +0000 Subject: [PATCH] [LMS-207] add: - 'ClientSafeException' and its test. - 'ServiceExceptionTranslator' as 'ThrowAdvice' implementation. change: - 'webServiceContext.xml' adds this advice via Spring. SVN: 4469 --- .../exceptions/ClientSafeException.java | 118 ++++++++++++++++++ .../exceptions/ClientSafeExceptionTest.java | 34 +++++ 2 files changed, 152 insertions(+) create mode 100644 common/source/java/ch/systemsx/cisd/common/exceptions/ClientSafeException.java create mode 100644 common/sourceTest/java/ch/systemsx/cisd/common/exceptions/ClientSafeExceptionTest.java diff --git a/common/source/java/ch/systemsx/cisd/common/exceptions/ClientSafeException.java b/common/source/java/ch/systemsx/cisd/common/exceptions/ClientSafeException.java new file mode 100644 index 00000000000..3c27080a6d9 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/exceptions/ClientSafeException.java @@ -0,0 +1,118 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed 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 ch.systemsx.cisd.common.exceptions; + +import org.apache.commons.lang.exception.ExceptionUtils; + +import ch.systemsx.cisd.common.utilities.ClassUtils; + +/** + * A <code>RuntimeException</code> extension which is client safe, meaning that it does not contain any third-party + * specific or proprietary <code>Exception</code> extension that the client does not know about and does not + * understand. + * <p> + * Note that this class can only be instantiated via {@link #createClientSafeExceptionIfNeeded(Exception)}. + * </p> + * + * @author Christian Ribeaud + */ +public final class ClientSafeException extends RuntimeException +{ + + private static final long serialVersionUID = 1L; + + /** + * The class name of the root exception. + * <p> + * Can not be <code>null</code>. + * </p> + */ + private final String rootClassName; + + private ClientSafeException(final Exception rootException) + { + super(rootException.getMessage()); + setStackTrace(rootException.getStackTrace()); + rootClassName = rootException.getClass().getName(); + } + + /** + * Creates a new <code>ClientSafeException</code> from given <var>exception</var> only if it is needed ({@link #isClientSafe(Exception)} + * returns <code>false</code>). Otherwise returns given <var>exception</var>. + */ + private final static Exception createClientSafeException(final Exception exception) + { + if (isClientSafe(exception) == false) + { + return new ClientSafeException(exception); + } else + { + return exception; + } + } + + /** + * Whether given <var>exception</var> is client-safe or not. + */ + private final static boolean isClientSafe(final Exception exception) + { + assert exception != null : "Unspecified exception."; + final String className = exception.getClass().getName(); + return className.startsWith("java.lang") || className.startsWith("ch.systemsx.cisd"); + } + + /** Recursively copies cause exception from <var>fromException</var> to <var>toException</var>. */ + private final static void copyCauseException(final Exception fromException, final Exception toException) + { + assert fromException != null : "Unspecified 'from' Exception."; + assert toException != null : "Unspecified 'to' Exception."; + final Exception fromCauseException = + CheckedExceptionTunnel.unwrapIfNecessary((Exception) ExceptionUtils.getCause(fromException)); + if (fromCauseException != null && fromCauseException != fromException) + { + final Exception toCauseException = createClientSafeException(fromCauseException); + if (toException.getCause() != toCauseException) + { + ClassUtils.setFieldValue(toException, "cause", toCauseException); + } + copyCauseException(fromCauseException, toCauseException); + } + } + + /** + * Analyzes given <var>exception</var> and makes it client-safe. + */ + public final static Exception createClientSafeExceptionIfNeeded(final Exception exception) + { + assert exception != null : "Unspecified SQL Exception."; + final Exception rootException = createClientSafeException(exception); + copyCauseException(rootException, rootException); + return rootException; + } + + // + // RuntimeException + // + + @Override + public final String toString() + { + final String s = rootClassName; + final String message = getMessage(); + return (message != null) ? (s + ": " + message) : s; + } +} \ No newline at end of file diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/exceptions/ClientSafeExceptionTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/exceptions/ClientSafeExceptionTest.java new file mode 100644 index 00000000000..f6700e70165 --- /dev/null +++ b/common/sourceTest/java/ch/systemsx/cisd/common/exceptions/ClientSafeExceptionTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed 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 ch.systemsx.cisd.common.exceptions; + +import org.testng.annotations.Test; + +/** + * Test cases for the {@link ClientSafeExceptionTest}. + * + * @author Christian Ribeaud + */ +public final class ClientSafeExceptionTest +{ + + @Test + public final void test() + { + System.out.println(null instanceof String); + } +} -- GitLab