< 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 >