/** Formats the specified position. */ static String toString(final DirectPosition position) { final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(position)).append('['); final int dimension = position.getDimension(); for (int i = 0; i < dimension; i++) { if (i != 0) { buffer.append(", "); } buffer.append(position.getOrdinate(i)); } return buffer.append(']').toString(); }
/** * Returns a string representation of this envelope. The default implementation is okay for * occasional formatting (for example for debugging purpose). */ @Override public String toString() { final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(this)).append('['); final int dimension = getDimension(); for (int i = 0; i < dimension; i++) { if (i != 0) { buffer.append(", "); } buffer.append(getMinimum(i)).append(" : ").append(getMaximum(i)); } return buffer.append(']').toString(); }
/** Invoked when a factory can't be loaded. Log a warning, but do not stop the process. */ private static void loadingFailure( final Class<?> category, final Throwable error, final boolean showStackTrace) { final String name = Classes.getShortName(category); final StringBuilder cause = new StringBuilder(Classes.getShortClassName(error)); final String message = error.getLocalizedMessage(); if (message != null) { cause.append(": "); cause.append(message); } final LogRecord record = Loggings.format(Level.WARNING, LoggingKeys.CANT_LOAD_SERVICE_$2, name, cause.toString()); if (showStackTrace) { record.setThrown(error); } record.setSourceClassName(FactoryRegistry.class.getName()); record.setSourceMethodName("scanForPlugins"); record.setLoggerName(LOGGER.getName()); LOGGER.log(record); }
/** * {@linkplain #registerServiceProvider Registers} all factories given by the supplied iterator. * * @param factories The factories (or "service providers") to register. * @param category the category under which to register the providers. * @param message A buffer where to write the logging message. * @return {@code true} if at least one factory has been registered. */ private <T> boolean register( final Iterator<T> factories, final Class<T> category, final StringBuilder message) { boolean newServices = false; final String lineSeparator = System.getProperty("line.separator", "\n"); while (factories.hasNext()) { T factory; try { factory = factories.next(); } catch (OutOfMemoryError error) { // Makes sure that we don't try to handle this error. throw error; } catch (NoClassDefFoundError error) { /* * A provider can't be registered because of some missing dependencies. * This occurs for example when trying to register the WarpTransform2D * math transform on a machine without JAI installation. Since the factory * may not be essential (this is the case of WarpTransform2D), just skip it. */ loadingFailure(category, error, false); continue; } catch (ExceptionInInitializerError error) { /* * If an exception occured during class initialization, log the cause. * The ExceptionInInitializerError alone doesn't help enough. */ final Throwable cause = error.getCause(); if (cause != null) { loadingFailure(category, cause, true); } throw error; } catch (Error error) { if (!Classes.getShortClassName(error).equals("ServiceConfigurationError")) { // We want to handle sun.misc.ServiceConfigurationError only. Unfortunatly, we // need to rely on reflection because this error class is not a commited API. // TODO: Check if the error is catchable with JSE 6. throw error; } /* * Failed to register a factory for a reason probably related to the plugin * initialisation. It may be some factory-dependent missing resources. */ loadingFailure(category, error, true); continue; } if (category.isAssignableFrom(factory.getClass())) { final Class<? extends T> factoryClass = factory.getClass().asSubclass(category); /* * If the factory implements more than one interface and an * instance were already registered, reuse the same instance * instead of duplicating it. */ final T replacement = getServiceProviderByClass(factoryClass); if (replacement != null) { factory = replacement; // Need to register anyway, because the category may not be // the same. } if (registerServiceProvider(factory, category)) { /* * The factory is now registered. Add it to the message to * be logged. We will log all factories together in a single * log event because some registration (e.g. * MathTransformProviders) would be otherwise quite verbose. */ message.append(lineSeparator); message.append(" "); message.append(factoryClass.getName()); newServices = true; } } } return newServices; }
/** * Implementation of {@link #unexpectedException(Logger, Class, String, Throwable)}. * * @param logger Where to log the error, or {@code null}. * @param classe The fully qualified class name where the error occurred, or {@code null}. * @param method The method where the error occurred, or {@code null}. * @param error The error. * @param level The logging level. * @return {@code true} if the error has been logged, or {@code false} if the logger doesn't log * anything at the specified level. */ private static boolean unexpectedException( Logger logger, String classe, String method, final Throwable error, final Level level) { /* * Checks if loggable, inferring the logger from the classe name if needed. */ if (error == null) { return false; } if (logger == null && classe != null) { final int separator = classe.lastIndexOf('.'); final String paquet = (separator >= 1) ? classe.substring(0, separator - 1) : ""; logger = getLogger(paquet); } if (logger != null && !logger.isLoggable(level)) { return false; } /* * Loggeable, so complete the null argument from the stack trace if we can. */ if (logger == null || classe == null || method == null) { String paquet = (logger != null) ? logger.getName() : null; final StackTraceElement[] elements = error.getStackTrace(); for (int i = 0; i < elements.length; i++) { /* * Searchs for the first stack trace element with a classname matching the * expected one. We compare preferably against the name of the class given * in argument, or against the logger name (taken as the package name) otherwise. */ final StackTraceElement element = elements[i]; final String classname = element.getClassName(); if (classe != null) { if (!classname.equals(classe)) { continue; } } else if (paquet != null) { if (!classname.startsWith(paquet)) { continue; } final int length = paquet.length(); if (classname.length() > length) { // We expect '.' but we accept also '$' or end of string. final char separator = classname.charAt(length); if (Character.isJavaIdentifierPart(separator)) { continue; } } } /* * Now that we have a stack trace element from the expected class (or any * element if we don't know the class), make sure that we have the right method. */ final String methodName = element.getMethodName(); if (method != null && !methodName.equals(method)) { continue; } /* * Now computes every values that are null, and stop the loop. */ if (paquet == null) { final int separator = classname.lastIndexOf('.'); paquet = (separator >= 1) ? classname.substring(0, separator - 1) : ""; logger = getLogger(paquet); if (!logger.isLoggable(level)) { return false; } } if (classe == null) { classe = classname; } if (method == null) { method = methodName; } break; } /* * The logger may stay null if we have been unable to find a suitable * stack trace. Fallback on the global logger. * * TODO: Use GLOBAL_LOGGER_NAME constant when we will be allowed to target Java 6. */ if (logger == null) { logger = getLogger("global"); if (!logger.isLoggable(level)) { return false; } } } /* * Now prepare the log message. If we have been unable to figure out a source class and * method name, we will fallback on Java logging default mechanism, which may returns a * less relevant name than our attempt to use the logger name as the package name. */ final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(error)); final String message = error.getLocalizedMessage(); if (message != null) { buffer.append(": ").append(message); } final LogRecord record = new LogRecord(level, buffer.toString()); if (classe != null) { record.setSourceClassName(classe); } if (method != null) { record.setSourceMethodName(method); } if (level.intValue() > 500) { record.setThrown(error); } record.setLoggerName(logger.getName()); logger.log(record); return true; }
/** Returns a string representation of this entry. */ @Override public String toString() { return Classes.getShortClassName(this) + "[key=" + key + ", value=" + value + ']'; }