com.sun.jersey.spi.inject.Errors Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.jersey.spi.inject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
* TODO do not use static thread local?
*
* @author [email protected]
*/
public final class Errors {
public static class ErrorMessagesException extends RuntimeException {
public final List messages;
private ErrorMessagesException(List messages) {
this.messages = messages;
}
}
public static class ErrorMessage {
final String message;
final boolean isFatal;
private ErrorMessage(String message, boolean isFatal) {
this.message = message;
this.isFatal = isFatal;
}
@Override
public int hashCode() {
int hash = 3;
hash = 37 * hash + (this.message != null ? this.message.hashCode() : 0);
hash = 37 * hash + (this.isFatal ? 1 : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ErrorMessage other = (ErrorMessage) obj;
if ((this.message == null) ? (other.message != null) : !this.message.equals(other.message)) {
return false;
}
if (this.isFatal != other.isFatal) {
return false;
}
return true;
}
}
private final ArrayList messages = new ArrayList(0);
private int mark = -1;
private int stack = 0;
private boolean fieldReporting = true;
private void _mark() {
mark = messages.size();
}
private void _unmark() {
mark = -1;
}
private void _reset() {
if (mark >= 0 && mark < messages.size()) {
messages.subList(mark, messages.size()).clear();
_unmark();
}
}
private void preProcess() {
stack++;
}
private void postProcess(boolean throwException) {
stack--;
fieldReporting = true;
if (stack == 0) {
try {
if (!messages.isEmpty()) {
processErrorMessages(throwException, messages);
}
} finally {
errors.remove();
}
}
}
private static final Logger LOGGER = Logger.getLogger(Errors.class.getName());
private static void processErrorMessages(boolean throwException, List messages) {
final StringBuilder sb = new StringBuilder();
boolean isFatal = false;
for (ErrorMessage em : messages) {
if (sb.length() > 0) {
sb.append("\n");
}
sb.append(" ");
if (em.isFatal) {
sb.append("SEVERE: ");
} else {
sb.append("WARNING: ");
}
isFatal |= em.isFatal;
sb.append(em.message);
}
final String message = sb.toString();
if (isFatal) {
LOGGER.severe("The following errors and warnings have been detected with resource and/or provider classes:\n" + message);
if (throwException) {
throw new ErrorMessagesException(new ArrayList(messages));
}
} else {
LOGGER.warning("The following warnings have been detected with resource and/or provider classes:\n" + message);
}
}
private static ThreadLocal errors = new ThreadLocal();
public static interface Closure {
public T f();
}
public static T processWithErrors(Closure c) {
Errors e = errors.get();
if (e == null) {
e = new Errors();
errors.set(e);
}
e.preProcess();
RuntimeException caught = null;
try {
return c.f();
} catch (RuntimeException re) {
// If a runtime exception is caught then report errors and
// rethrow
caught = re;
} finally {
e.postProcess(caught == null);
}
throw caught;
}
private static Errors getInstance() {
Errors e = errors.get();
// No error processing in scope
if (e == null) {
throw new IllegalStateException("There is no error processing in scope");
}
// The following should not be necessary but given the fragile nature of
// static thread local probably best to add it in case some internals of
// this class change
if (e.stack == 0) {
errors.remove();
throw new IllegalStateException("There is no error processing in scope");
}
return e;
}
public static void mark() {
getInstance()._mark();
}
public static void unmark() {
getInstance()._unmark();
}
public static void reset() {
getInstance()._reset();
}
public static void error(String message) {
error(message, true);
}
public static void error(String message, boolean isFatal) {
final ErrorMessage em = new ErrorMessage(message, isFatal);
getInstance().messages.add(em);
}
public int numberOfErrors() {
return getInstance().messages.size();
}
public static void innerClass(Class c) {
error("The inner class " + c.getName() + " is not a static inner class and cannot be instantiated.");
}
public static void nonPublicClass(Class c) {
error("The class " + c.getName() + " is a not a public class and cannot be instantiated.");
}
public static void nonPublicConstructor(Class c) {
error("The class " + c.getName() + " does not have a public constructor and cannot be instantiated.");
}
public static void abstractClass(Class c) {
error("The class " + c.getName() + " is an abstract class and cannot be instantiated.");
}
public static void interfaceClass(Class c) {
error("The class " + c.getName() + " is an interface and cannot be instantiated.");
}
public static void missingDependency(Constructor ctor, int i) {
error("Missing dependency for constructor " + ctor + " at parameter index " + i);
}
public static void setReportMissingDependentFieldOrMethod(boolean fieldReporting) {
getInstance().fieldReporting = fieldReporting;
}
public static boolean getReportMissingDependentFieldOrMethod() {
return getInstance().fieldReporting;
}
public static void missingDependency(Field f) {
if (getReportMissingDependentFieldOrMethod()) {
error("Missing dependency for field: " + f.toGenericString());
}
}
public static void missingDependency(Method m, int i) {
if (getReportMissingDependentFieldOrMethod()) {
error("Missing dependency for method " + m + " at parameter at index " + i);
}
}
}