< prev index next >
src/java.logging/share/classes/java/util/logging/Level.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 22,38 ****
--- 22,45 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.util.logging;
+ import java.lang.ref.Reference;
+ import java.lang.ref.ReferenceQueue;
+ import java.lang.ref.WeakReference;
import java.lang.reflect.Module;
import java.util.ArrayList;
+ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+ import java.util.Optional;
import java.util.ResourceBundle;
+ import java.util.function.Function;
+ import java.util.stream.Stream;
/**
* The Level class defines a set of standard logging levels that
* can be used to control logging output. The logging Level objects
* are ordered and are specified by ordered integers. Enabling logging
*** 265,275 ****
private String computeLocalizedLevelName(Locale newLocale) {
// Resource bundle should be loaded from the defining module
// or its defining class loader, if it's unnamed module,
// of this Level instance that can be a custom Level subclass;
Module module = this.getClass().getModule();
! ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName, newLocale, module);
final String localizedName = rb.getString(name);
final boolean isDefaultBundle = defaultBundle.equals(resourceBundleName);
if (!isDefaultBundle) return localizedName;
--- 272,283 ----
private String computeLocalizedLevelName(Locale newLocale) {
// Resource bundle should be loaded from the defining module
// or its defining class loader, if it's unnamed module,
// of this Level instance that can be a custom Level subclass;
Module module = this.getClass().getModule();
! ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName,
! newLocale, module);
final String localizedName = rb.getString(name);
final boolean isDefaultBundle = defaultBundle.equals(resourceBundleName);
if (!isDefaultBundle) return localizedName;
*** 348,385 ****
static Level findLevel(String name) {
if (name == null) {
throw new NullPointerException();
}
! KnownLevel level;
// Look for a known Level with the given non-localized name.
! level = KnownLevel.findByName(name);
! if (level != null) {
! return level.mirroredLevel;
}
// Now, check if the given name is an integer. If so,
// first look for a Level with the given value and then
// if necessary create one.
try {
int x = Integer.parseInt(name);
! level = KnownLevel.findByValue(x);
! if (level == null) {
// add new Level
Level levelObject = new Level(name, x);
! level = KnownLevel.findByValue(x);
}
- return level.mirroredLevel;
} catch (NumberFormatException ex) {
// Not an integer.
// Drop through.
}
! level = KnownLevel.findByLocalizedLevelName(name);
! if (level != null) {
! return level.mirroredLevel;
}
return null;
}
--- 356,393 ----
static Level findLevel(String name) {
if (name == null) {
throw new NullPointerException();
}
! Optional<Level> level;
// Look for a known Level with the given non-localized name.
! level = KnownLevel.findByName(name, KnownLevel::mirrored);
! if (level.isPresent()) {
! return level.get();
}
// Now, check if the given name is an integer. If so,
// first look for a Level with the given value and then
// if necessary create one.
try {
int x = Integer.parseInt(name);
! level = KnownLevel.findByValue(x, KnownLevel::mirrored);
! if (!level.isPresent()) {
// add new Level
Level levelObject = new Level(name, x);
! return KnownLevel.findByValue(x, KnownLevel::mirrored).get();
}
} catch (NumberFormatException ex) {
// Not an integer.
// Drop through.
}
! level = KnownLevel.findByLocalizedLevelName(name,
! KnownLevel::mirrored);
! if (level.isPresent()) {
! return level.get();
}
return null;
}
*** 406,424 ****
private static final long serialVersionUID = -8176160795706313070L;
// Serialization magic to prevent "doppelgangers".
// This is a performance optimization.
private Object readResolve() {
! KnownLevel o = KnownLevel.matches(this);
! if (o != null) {
! return o.levelObject;
}
-
// Woops. Whoever sent us this object knows
// about a new log level. Add it to our list.
! Level level = new Level(this.name, this.value, this.resourceBundleName);
! return level;
}
/**
* Parse a level name string into a Level.
* <p>
--- 414,430 ----
private static final long serialVersionUID = -8176160795706313070L;
// Serialization magic to prevent "doppelgangers".
// This is a performance optimization.
private Object readResolve() {
! Optional<Level> level = KnownLevel.matches(this);
! if (level.isPresent()) {
! return level.get();
}
// Woops. Whoever sent us this object knows
// about a new log level. Add it to our list.
! return new Level(this.name, this.value, this.resourceBundleName);
}
/**
* Parse a level name string into a Level.
* <p>
*** 448,488 ****
*/
public static synchronized Level parse(String name) throws IllegalArgumentException {
// Check that name is not null.
name.length();
! KnownLevel level;
// Look for a known Level with the given non-localized name.
! level = KnownLevel.findByName(name);
! if (level != null) {
! return level.levelObject;
}
// Now, check if the given name is an integer. If so,
// first look for a Level with the given value and then
// if necessary create one.
try {
int x = Integer.parseInt(name);
! level = KnownLevel.findByValue(x);
! if (level == null) {
! // add new Level
! Level levelObject = new Level(name, x);
! level = KnownLevel.findByValue(x);
}
! return level.levelObject;
} catch (NumberFormatException ex) {
// Not an integer.
// Drop through.
}
// Finally, look for a known level with the given localized name,
// in the current default locale.
// This is relatively expensive, but not excessively so.
! level = KnownLevel.findByLocalizedLevelName(name);
! if (level != null) {
! return level.levelObject;
}
// OK, we've tried everything and failed
throw new IllegalArgumentException("Bad level \"" + name + "\"");
}
--- 454,494 ----
*/
public static synchronized Level parse(String name) throws IllegalArgumentException {
// Check that name is not null.
name.length();
! Optional<Level> level;
// Look for a known Level with the given non-localized name.
! level = KnownLevel.findByName(name, KnownLevel::referent);
! if (level.isPresent()) {
! return level.get();
}
// Now, check if the given name is an integer. If so,
// first look for a Level with the given value and then
// if necessary create one.
try {
int x = Integer.parseInt(name);
! level = KnownLevel.findByValue(x, KnownLevel::referent);
! if (level.isPresent()) {
! return level.get();
}
! // add new Level.
! Level levelObject = new Level(name, x);
! return KnownLevel.findByValue(x, KnownLevel::referent).get();
} catch (NumberFormatException ex) {
// Not an integer.
// Drop through.
}
// Finally, look for a known level with the given localized name,
// in the current default locale.
// This is relatively expensive, but not excessively so.
! level = KnownLevel.findByLocalizedLevelName(name, KnownLevel::referent);
! if (level .isPresent()) {
! return level.get();
}
// OK, we've tried everything and failed
throw new IllegalArgumentException("Bad level \"" + name + "\"");
}
*** 528,553 ****
//
// Implementation Notes:
// If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
// were final, the following KnownLevel implementation can be removed.
// Future API change should take this into consideration.
! static final class KnownLevel {
private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>();
private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>();
! final Level levelObject; // instance of Level class or Level subclass
final Level mirroredLevel; // mirror of the custom Level
KnownLevel(Level l) {
! this.levelObject = l;
if (l.getClass() == Level.class) {
this.mirroredLevel = l;
} else {
// this mirrored level object is hidden
! this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName, false);
}
}
static synchronized void add(Level l) {
// the mirroredLevel object is always added to the list
// before the custom Level instance
KnownLevel o = new KnownLevel(l);
List<KnownLevel> list = nameToLevels.get(l.name);
if (list == null) {
--- 534,588 ----
//
// Implementation Notes:
// If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
// were final, the following KnownLevel implementation can be removed.
// Future API change should take this into consideration.
! static final class KnownLevel extends WeakReference<Level> {
private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>();
private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>();
! private static final ReferenceQueue<Level> QUEUE = new ReferenceQueue<>();
!
final Level mirroredLevel; // mirror of the custom Level
KnownLevel(Level l) {
! super(l, QUEUE);
if (l.getClass() == Level.class) {
this.mirroredLevel = l;
} else {
// this mirrored level object is hidden
! this.mirroredLevel = new Level(l.name, l.value,
! l.resourceBundleName, false);
! }
! }
!
! Stream<Level> mirrored() {
! return Stream.of(mirroredLevel);
! }
!
! Stream<Level> referent() {
! final Level ref = get();
! return ref == null ? Stream.empty() : Stream.of(ref);
! }
!
! private void remove() {
! Optional.ofNullable(nameToLevels.get(mirroredLevel.name))
! .ifPresent((x) -> x.remove(this));
! Optional.ofNullable(intToLevels.get(mirroredLevel.value))
! .ifPresent((x) -> x.remove(this));
! }
!
! // Remove all stale KnownLevel instances
! static synchronized void purge() {
! Reference<? extends Level> ref;
! while ((ref = QUEUE.poll()) != null) {
! if (ref instanceof KnownLevel) {
! ((KnownLevel)ref).remove();
! }
}
}
static synchronized void add(Level l) {
+ purge();
// the mirroredLevel object is always added to the list
// before the custom Level instance
KnownLevel o = new KnownLevel(l);
List<KnownLevel> list = nameToLevels.get(l.name);
if (list == null) {
*** 563,619 ****
}
list.add(o);
}
// Returns a KnownLevel with the given non-localized name.
! static synchronized KnownLevel findByName(String name) {
! List<KnownLevel> list = nameToLevels.get(name);
! if (list != null) {
! return list.get(0);
! }
! return null;
}
// Returns a KnownLevel with the given value.
! static synchronized KnownLevel findByValue(int value) {
! List<KnownLevel> list = intToLevels.get(value);
! if (list != null) {
! return list.get(0);
! }
! return null;
}
// Returns a KnownLevel with the given localized name matching
// by calling the Level.getLocalizedLevelName() method (i.e. found
// from the resourceBundle associated with the Level object).
// This method does not call Level.getLocalizedName() that may
// be overridden in a subclass implementation
! static synchronized KnownLevel findByLocalizedLevelName(String name) {
! for (List<KnownLevel> levels : nameToLevels.values()) {
! for (KnownLevel l : levels) {
! String lname = l.levelObject.getLocalizedLevelName();
! if (name.equals(lname)) {
! return l;
! }
! }
! }
! return null;
}
! static synchronized KnownLevel matches(Level l) {
List<KnownLevel> list = nameToLevels.get(l.name);
if (list != null) {
! for (KnownLevel level : list) {
! Level other = level.mirroredLevel;
if (l.value == other.value &&
(l.resourceBundleName == other.resourceBundleName ||
(l.resourceBundleName != null &&
l.resourceBundleName.equals(other.resourceBundleName)))) {
! return level;
}
}
}
! return null;
}
}
}
--- 598,658 ----
}
list.add(o);
}
// Returns a KnownLevel with the given non-localized name.
! static synchronized Optional<Level> findByName(String name,
! Function<KnownLevel, Stream<Level>> selector) {
! purge();
! return nameToLevels.getOrDefault(name, Collections.emptyList())
! .stream()
! .flatMap(selector)
! .findFirst();
}
// Returns a KnownLevel with the given value.
! static synchronized Optional<Level> findByValue(int value,
! Function<KnownLevel, Stream<Level>> selector) {
! purge();
! return intToLevels.getOrDefault(value, Collections.emptyList())
! .stream()
! .flatMap(selector)
! .findFirst();
}
// Returns a KnownLevel with the given localized name matching
// by calling the Level.getLocalizedLevelName() method (i.e. found
// from the resourceBundle associated with the Level object).
// This method does not call Level.getLocalizedName() that may
// be overridden in a subclass implementation
! static synchronized Optional<Level> findByLocalizedLevelName(String name,
! Function<KnownLevel, Stream<Level>> selector) {
! purge();
! return nameToLevels.values()
! .stream()
! .flatMap(List::stream)
! .flatMap(selector)
! .filter(lo -> name.equals(lo.getLocalizedLevelName()))
! .findFirst();
}
! static synchronized Optional<Level> matches(Level l) {
! purge();
List<KnownLevel> list = nameToLevels.get(l.name);
if (list != null) {
! for (KnownLevel ref : list) {
! Level levelObject = ref.get();
! if (levelObject == null) continue;
! Level other = ref.mirroredLevel;
if (l.value == other.value &&
(l.resourceBundleName == other.resourceBundleName ||
(l.resourceBundleName != null &&
l.resourceBundleName.equals(other.resourceBundleName)))) {
! return Optional.of(levelObject);
}
}
}
! return Optional.empty();
}
}
}
< prev index next >