pax_global_header 0000666 0000000 0000000 00000000064 13522561261 0014515 g ustar 00root root 0000000 0000000 52 comment=752df9043ceef6da01760e3e538e3ccf7728f83b
jboss-logmanager-2.1.14.Final/ 0000775 0000000 0000000 00000000000 13522561261 0016064 5 ustar 00root root 0000000 0000000 jboss-logmanager-2.1.14.Final/.gitignore 0000664 0000000 0000000 00000000115 13522561261 0020051 0 ustar 00root root 0000000 0000000 *.ipr
*.iws
*.iml
.idea
target
/test-output
/.settings
/.project
/.classpath
jboss-logmanager-2.1.14.Final/LICENSE.txt 0000664 0000000 0000000 00000026135 13522561261 0017716 0 ustar 00root root 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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. jboss-logmanager-2.1.14.Final/pom.xml 0000664 0000000 0000000 00000032740 13522561261 0017407 0 ustar 00root root 0000000 0000000
4.0.0JBoss Log ManagerAn implementation of java.util.logging.LogManagerorg.jboss.logmanagerjboss-logmanagerjar2.1.14.Finalorg.jbossjboss-parent34Apache License 2.0http://repository.jboss.org/licenses/apache-2.0.txtrepo1.04.0.61.0.41.9.1.Final1.5.1.Final4.12127.0.0.14560145601.81.89org.jboss.modulesjboss-modules${version.org.jboss.modules.jboss-modules}providedtrueorg.wildfly.commonwildfly-common${version.org.wildfly.common.wildfly-common}javax.jsonjavax.json-api${version.javax.json}trueorg.glassfishjavax.json${version.org.glassfish.javax.json}trueorg.jboss.bytemanbyteman${version.org.byteman}testorg.jboss.bytemanbyteman-submit${version.org.byteman}testorg.jboss.bytemanbyteman-install${version.org.byteman}testorg.jboss.bytemanbyteman-bmunit${version.org.byteman}testjunitjunit${version.junit.junit}testjava8-test-profilejava8.homemaven-surefire-pluginjava8-testtesttest${java8.home}/bin/java${java8.home}/lib/tools.jarorg/jboss/logmanager/SystemLoggerTests.javamaven-compiler-plugindefault-compilecompilecompile8${project.build.directory}${project.compileSourceRoots}${project.build.outputDirectory}compile-java9compilecompile9${project.build.directory}${project.basedir}/src/main/java9${project.build.directory}/classes/META-INF/versions/9${project.build.outputDirectory}test-compile-java9test-compiletestCompile9${project.build.directory}${project.basedir}/src/test/java9maven-javadoc-pluginnonemaven-source-pluginmaven-surefire-plugin**/*Tests.java-Djdk.attach.allowAttachSelf=true -Djava.util.logging.manager=org.jboss.logmanager.LogManagerorg.jboss.logmanager.LogManager${project.build.directory}${file.separator}logs${file.separator}${project.basedir}/src/test/resources/server-keystore.jkstestpassword${project.basedir}/src/test/resources/client-keystore.jkstestpassword${org.jboss.test.address}${org.jboss.test.port}${org.jboss.test.alt.port}falsedefault-test**/*$*org/jboss/logmanager/formatters/FormattersTests.java${project.build.directory}/classes/META-INF/versions/9${project.build.directory}/classesmaven-enforcer-pluginmaven-jar-plugin${project.build.outputDirectory}/META-INF/MANIFEST.MFtrueorg.apache.felixmaven-bundle-plugintruebiz.aQute.bndbiz.aQute.bndlib4.2.0
<_fixupmessages>"Classes found in the wrong directory";is:=warning
${project.groupId}.*;version=${project.version};-split-package:=error
bundle-manifestprocess-classesmanifest
jboss-logmanager-2.1.14.Final/src/ 0000775 0000000 0000000 00000000000 13522561261 0016653 5 ustar 00root root 0000000 0000000 jboss-logmanager-2.1.14.Final/src/main/ 0000775 0000000 0000000 00000000000 13522561261 0017577 5 ustar 00root root 0000000 0000000 jboss-logmanager-2.1.14.Final/src/main/java/ 0000775 0000000 0000000 00000000000 13522561261 0020520 5 ustar 00root root 0000000 0000000 jboss-logmanager-2.1.14.Final/src/main/java/org/ 0000775 0000000 0000000 00000000000 13522561261 0021307 5 ustar 00root root 0000000 0000000 jboss-logmanager-2.1.14.Final/src/main/java/org/jboss/ 0000775 0000000 0000000 00000000000 13522561261 0022427 5 ustar 00root root 0000000 0000000 jboss-logmanager-2.1.14.Final/src/main/java/org/jboss/logmanager/ 0000775 0000000 0000000 00000000000 13522561261 0024543 5 ustar 00root root 0000000 0000000 jboss-logmanager-2.1.14.Final/src/main/java/org/jboss/logmanager/AtomicArray.java 0000664 0000000 0000000 00000035337 13522561261 0027634 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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 org.jboss.logmanager;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.logging.Handler;
/**
* Utility for snapshot/copy-on-write arrays. To use these methods, two things are required: an immutable array
* stored on a volatile field, and an instance of
* {@link java.util.concurrent.atomic.AtomicReferenceFieldUpdater AtomicReferenceFieldUpdater}
* which corresponds to that field. Some of these methods perform multi-step operations; if the array field value is
* changed in the middle of such an operation, the operation is retried. To avoid spinning, in some situations it
* may be advisable to hold a write lock to prevent multiple concurrent updates.
*
* @param the type which contains the target field
* @param the array value type
*/
final class AtomicArray {
private final AtomicReferenceFieldUpdater updater;
private final Class componentType;
private final V[] emptyArray;
/**
* Construct an instance.
*
* @param updater the field updater
* @param componentType the component class
*/
public AtomicArray(AtomicReferenceFieldUpdater updater, Class componentType) {
this.updater = updater;
this.componentType = componentType;
emptyArray = newInstance(componentType, 0);
}
/**
* Convenience method to create an instance.
*
* @param updater the field updater
* @param componentType the component class
* @param the type which contains the target field
* @param the array value type
* @return the new instance
*/
public static AtomicArray create(AtomicReferenceFieldUpdater updater, Class componentType) {
return new AtomicArray(updater, componentType);
}
/**
* Convenience method to set the field value to the empty array. Empty array instances are shared.
*
* @param instance the instance holding the field
*/
public void clear(T instance) {
updater.set(instance, emptyArray);
}
/**
* Update the value of this array.
*
* @param instance the instance holding the field
* @param value the new value
*/
public void set(T instance, V[] value) {
updater.set(instance, value);
}
/**
* Atomically get and update the value of this array.
*
* @param instance the instance holding the field
* @param value the new value
*/
public V[] getAndSet(T instance, V[] value) {
return updater.getAndSet(instance, value);
}
@SuppressWarnings({ "unchecked" })
private static V[] copyOf(final Class componentType, V[] old, int newLen) {
final V[] target = newInstance(componentType, newLen);
System.arraycopy(old, 0, target, 0, Math.min(old.length, newLen));
return target;
}
/**
* Atomically replace the array with a new array which is one element longer, and which includes the given value.
*
* @param instance the instance holding the field
* @param value the updated value
*/
public void add(T instance, V value) {
final AtomicReferenceFieldUpdater updater = this.updater;
for (;;) {
final V[] oldVal = updater.get(instance);
final int oldLen = oldVal.length;
final V[] newVal = copyOf(componentType, oldVal, oldLen + 1);
newVal[oldLen] = value;
if (updater.compareAndSet(instance, oldVal, newVal)) {
return;
}
}
}
/**
* Atomically replace the array with a new array which is one element longer, and which includes the given value,
* if the value is not already present within the array. This method does a linear search for the target value.
*
* @param instance the instance holding the field
* @param value the updated value
* @param identity {@code true} if comparisons should be done using reference identity, or {@code false} to use the {@code equals()} method
* @return {@code true} if the value was added, or {@code false} if it was already present
*/
public boolean addIfAbsent(T instance, V value, boolean identity) {
final AtomicReferenceFieldUpdater updater = this.updater;
for (;;) {
final V[] oldVal = updater.get(instance);
final int oldLen = oldVal.length;
if (identity || value == null) {
for (int i = 0; i < oldLen; i++) {
if (oldVal[i] == value) {
return false;
}
}
} else {
for (int i = 0; i < oldLen; i++) {
if (value.equals(oldVal[i])) {
return false;
}
}
}
final V[] newVal = copyOf(componentType, oldVal, oldLen + 1);
newVal[oldLen] = value;
if (updater.compareAndSet(instance, oldVal, newVal)) {
return true;
}
}
}
/**
* Atomically replace the array with a new array which does not include the first occurrance of the given value, if
* the value is present in the array.
*
* @param instance the instance holding the field
* @param value the updated value
* @param identity {@code true} if comparisons should be done using reference identity, or {@code false} to use the {@code equals()} method
* @return {@code true} if the value was removed, or {@code false} if it was not present
*/
public boolean remove(T instance, V value, boolean identity) {
final AtomicReferenceFieldUpdater updater = this.updater;
for (;;) {
final V[] oldVal = updater.get(instance);
final int oldLen = oldVal.length;
if (oldLen == 0) {
return false;
} else {
int index = -1;
if (identity || value == null) {
for (int i = 0; i < oldLen; i++) {
if (oldVal[i] == value) {
index = i;
break;
}
}
} else {
for (int i = 0; i < oldLen; i++) {
if (value.equals(oldVal[i])) {
index = i;
break;
}
}
}
if (index == -1) {
return false;
}
final V[] newVal = newInstance(componentType, oldLen - 1);
System.arraycopy(oldVal, 0, newVal, 0, index);
System.arraycopy(oldVal, index + 1, newVal, index, oldLen - index - 1);
if (updater.compareAndSet(instance, oldVal, newVal)) {
return true;
}
}
}
}
/**
* Atomically replace the array with a new array which does not include any occurrances of the given value, if
* the value is present in the array.
*
* @param instance the instance holding the field
* @param value the updated value
* @param identity {@code true} if comparisons should be done using reference identity, or {@code false} to use the {@code equals()} method
* @return the number of values removed
*/
public int removeAll(T instance, V value, boolean identity) {
final AtomicReferenceFieldUpdater updater = this.updater;
for (;;) {
final V[] oldVal = updater.get(instance);
final int oldLen = oldVal.length;
if (oldLen == 0) {
return 0;
} else {
final boolean[] removeSlots = new boolean[oldLen];
int removeCount = 0;
if (identity || value == null) {
for (int i = 0; i < oldLen; i++) {
if (oldVal[i] == value) {
removeSlots[i] = true;
removeCount++;
}
}
} else {
for (int i = 0; i < oldLen; i++) {
if (value.equals(oldVal[i])) {
removeSlots[i] = true;
removeCount++;
}
}
}
if (removeCount == 0) {
return 0;
}
final int newLen = oldLen - removeCount;
final V[] newVal;
if (newLen == 0) {
newVal = emptyArray;
} else {
newVal = newInstance(componentType, newLen);
for (int i = 0, j = 0; i < oldLen; i ++) {
if (! removeSlots[i]) {
newVal[j++] = oldVal[i];
}
}
}
if (updater.compareAndSet(instance, oldVal, newVal)) {
return removeCount;
}
}
}
}
/**
* Add a value to a sorted array. Does not check for duplicates.
*
* @param instance the instance holding the field
* @param value the value to add
* @param comparator a comparator, or {@code null} to use natural ordering
*/
public void add(T instance, V value, Comparator super V> comparator) {
final AtomicReferenceFieldUpdater updater = this.updater;
for (;;) {
final V[] oldVal = updater.get(instance);
final int oldLen = oldVal.length;
final int pos = insertionPoint(Arrays.binarySearch(oldVal, value, comparator));
final V[] newVal = newInstance(componentType, oldLen + 1);
System.arraycopy(oldVal, 0, newVal, 0, pos);
newVal[pos] = value;
System.arraycopy(oldVal, pos, newVal, pos + 1, oldLen - pos);
if (updater.compareAndSet(instance, oldVal, newVal)) {
return;
}
}
}
/**
* Add a value to a sorted array if it is not already present. Does not check for duplicates.
*
* @param instance the instance holding the field
* @param value the value to add
* @param comparator a comparator, or {@code null} to use natural ordering
*/
public boolean addIfAbsent(T instance, V value, Comparator super V> comparator) {
final AtomicReferenceFieldUpdater updater = this.updater;
for (;;) {
final V[] oldVal = updater.get(instance);
final int oldLen = oldVal.length;
final int pos = Arrays.binarySearch(oldVal, value, comparator);
if (pos < 0) {
return false;
}
final V[] newVal = newInstance(componentType, oldLen + 1);
System.arraycopy(oldVal, 0, newVal, 0, pos);
newVal[pos] = value;
System.arraycopy(oldVal, pos, newVal, pos + 1, oldLen - pos);
if (updater.compareAndSet(instance, oldVal, newVal)) {
return true;
}
}
}
/**
* Remove a value to a sorted array. Does not check for duplicates. If there are multiple occurrances of a value,
* there is no guarantee as to which one is removed.
*
* @param instance the instance holding the field
* @param value the value to remove
* @param comparator a comparator, or {@code null} to use natural ordering
*/
public boolean remove(T instance, V value, Comparator super V> comparator) {
final AtomicReferenceFieldUpdater updater = this.updater;
for (;;) {
final V[] oldVal = updater.get(instance);
final int oldLen = oldVal.length;
if (oldLen == 0) {
return false;
} else {
final int pos = Arrays.binarySearch(oldVal, value, comparator);
if (pos < 0) {
return false;
}
final V[] newVal = newInstance(componentType, oldLen - 1);
System.arraycopy(oldVal, 0, newVal, 0, pos);
System.arraycopy(oldVal, pos + 1, newVal, pos, oldLen - pos - 1);
if (updater.compareAndSet(instance, oldVal, newVal)) {
return true;
}
}
}
}
/**
* Sort an array.
*
* @param instance the instance holding the field
* @param comparator a comparator, or {@code null} to use natural ordering
*/
public void sort(T instance, Comparator super V> comparator) {
final AtomicReferenceFieldUpdater updater = this.updater;
for (;;) {
final V[] oldVal = updater.get(instance);
if (oldVal.length == 0) {
return;
}
final V[] newVal = oldVal.clone();
Arrays.sort(newVal, comparator);
if (updater.compareAndSet(instance, oldVal, newVal)) {
return;
}
}
}
private static int insertionPoint(int searchResult) {
return searchResult > 0 ? searchResult : - (searchResult + 1);
}
@SuppressWarnings({ "unchecked" })
private static V[] newInstance(Class componentType, int length) {
if (componentType == Handler.class) {
return (V[]) new Handler[length];
} else if (componentType == Object.class) {
return (V[]) new Object[length];
} else {
return (V[]) Array.newInstance(componentType, length);
}
}
/**
* Compare and set the array.
*
* @param instance the instance holding the field
* @param expect the expected value
* @param update the update value
* @return {@code true} if the value was updated or {@code false} if the expected value did not match
*/
public boolean compareAndSet(final T instance, final V[] expect, final V[] update) {
return updater.compareAndSet(instance, expect, update);
}
}
CallerClassLoaderLogContextSelector.java 0000664 0000000 0000000 00000020522 13522561261 0034357 0 ustar 00root root 0000000 0000000 jboss-logmanager-2.1.14.Final/src/main/java/org/jboss/logmanager /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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 org.jboss.logmanager;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
/**
* A log context selector which chooses a log context based on the caller's classloader. The first caller that is not
* a {@linkplain #addLogApiClassLoader(ClassLoader) log API} or does not have a {@code null} classloader will be the
* class loader used.
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public final class CallerClassLoaderLogContextSelector implements LogContextSelector {
private static final Permission REGISTER_LOG_CONTEXT_PERMISSION = new RuntimePermission("registerLogContext", null);
private static final Permission UNREGISTER_LOG_CONTEXT_PERMISSION = new RuntimePermission("unregisterLogContext", null);
private static final Permission LOG_API_PERMISSION = new RuntimePermission("logApiPermission", null);
/**
* Construct a new instance. If no matching log context is found, the provided default selector is consulted.
*
* @param defaultSelector the selector to consult if no matching log context is found
*/
public CallerClassLoaderLogContextSelector(final LogContextSelector defaultSelector) {
this(defaultSelector, false);
}
/**
* Construct a new instance. If no matching log context is found, the provided default selector is consulted.
*
* If the {@code checkParentClassLoaders} is set to {@code true} this selector recursively searches the class loader
* parents until a match is found or a {@code null} parent is found.
*
*
* @param defaultSelector the selector to consult if no matching log context is found
* @param checkParentClassLoaders {@code true} if the {@link LogContext log context} could not
* found for the class loader and the {@link ClassLoader#getParent() parent class
* loader} should be checked
*/
public CallerClassLoaderLogContextSelector(final LogContextSelector defaultSelector, final boolean checkParentClassLoaders) {
this.defaultSelector = defaultSelector == null ? LogContext.DEFAULT_LOG_CONTEXT_SELECTOR : defaultSelector;
this.checkParentClassLoaders = checkParentClassLoaders;
}
/**
* Construct a new instance. If no matching log context is found, the system context is used.
*/
public CallerClassLoaderLogContextSelector() {
this(false);
}
/**
* Construct a new instance. If no matching log context is found, the system context is used.
*
* If the {@code checkParentClassLoaders} is set to {@code true} this selector recursively searches the class loader
* parents until a match is found or a {@code null} parent is found.
*
*
* @param checkParentClassLoaders {@code true} if the {@link LogContext log context} could not
* found for the class loader and the {@link ClassLoader#getParent() parent class
* loader} should be checked
*/
public CallerClassLoaderLogContextSelector(final boolean checkParentClassLoaders) {
this(LogContext.DEFAULT_LOG_CONTEXT_SELECTOR, checkParentClassLoaders);
}
private final LogContextSelector defaultSelector;
private final ConcurrentMap contextMap = new CopyOnWriteMap();
private final Set logApiClassLoaders = Collections.newSetFromMap(new CopyOnWriteMap());
private final boolean checkParentClassLoaders;
private final PrivilegedAction logContextAction = new PrivilegedAction() {
public LogContext run() {
final Class> callingClass = JDKSpecific.findCallingClass(logApiClassLoaders);
return callingClass == null ? defaultSelector.getLogContext() : check(callingClass.getClassLoader());
}
private LogContext check(final ClassLoader classLoader) {
final LogContext context = contextMap.get(classLoader);
if (context != null) {
return context;
}
final ClassLoader parent = classLoader.getParent();
if (parent != null && checkParentClassLoaders && ! logApiClassLoaders.contains(parent)) {
return check(parent);
}
return defaultSelector.getLogContext();
}
};
/**
* {@inheritDoc} This instance will consult the call stack to see if the first callers classloader is associated
* with a log context. The first caller is determined by the first class loader that is not registered as a
* {@linkplain #addLogApiClassLoader(ClassLoader) log API}.
*/
@Override
public LogContext getLogContext() {
return System.getSecurityManager() == null? logContextAction.run() :
AccessController.doPrivileged(logContextAction);
}
/**
* Register a class loader which is a known log API, and thus should be skipped over when searching for the
* log context to use for the caller class.
*
* @param apiClassLoader the API class loader
*
* @return {@code true} if this class loader was previously unknown, or {@code false} if it was already registered
*/
public boolean addLogApiClassLoader(ClassLoader apiClassLoader) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOG_API_PERMISSION);
}
return logApiClassLoaders.add(apiClassLoader);
}
/**
* Remove a class loader from the known log APIs set.
*
* @param apiClassLoader the API class loader
*
* @return {@code true} if the class loader was removed, or {@code false} if it was not known to this selector
*/
public boolean removeLogApiClassLoader(ClassLoader apiClassLoader) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOG_API_PERMISSION);
}
return logApiClassLoaders.remove(apiClassLoader);
}
/**
* Register a class loader with a log context. This method requires the {@code registerLogContext} {@link RuntimePermission}.
*
* @param classLoader the classloader
* @param logContext the log context
*
* @throws IllegalArgumentException if the classloader is already associated with a log context
*/
public void registerLogContext(ClassLoader classLoader, LogContext logContext) throws IllegalArgumentException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(REGISTER_LOG_CONTEXT_PERMISSION);
}
if (contextMap.putIfAbsent(classLoader, logContext) != null) {
throw new IllegalArgumentException("ClassLoader instance is already registered to a log context (" + classLoader + ")");
}
}
/**
* Unregister a class loader/log context association. This method requires the {@code unregisterLogContext} {@link RuntimePermission}.
*
* @param classLoader the classloader
* @param logContext the log context
*
* @return {@code true} if the association exists and was removed, {@code false} otherwise
*/
public boolean unregisterLogContext(ClassLoader classLoader, LogContext logContext) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(UNREGISTER_LOG_CONTEXT_PERMISSION);
}
return contextMap.remove(classLoader, logContext);
}
}
jboss-logmanager-2.1.14.Final/src/main/java/org/jboss/logmanager/ClassLoaderLogContextSelector.java 0000664 0000000 0000000 00000020046 13522561261 0033314 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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 org.jboss.logmanager;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Permission;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
/**
* A log context selector which chooses a log context based on the caller's classloader.
*/
public final class ClassLoaderLogContextSelector implements LogContextSelector {
private static final Permission REGISTER_LOG_CONTEXT_PERMISSION = new RuntimePermission("registerLogContext", null);
private static final Permission UNREGISTER_LOG_CONTEXT_PERMISSION = new RuntimePermission("unregisterLogContext", null);
private static final Permission LOG_API_PERMISSION = new RuntimePermission("logApiPermission", null);
/**
* Construct a new instance. If no matching log context is found, the provided default selector is consulted.
*
* @param defaultSelector the selector to consult if no matching log context is found
*/
public ClassLoaderLogContextSelector(final LogContextSelector defaultSelector) {
this(defaultSelector, false);
}
/**
* Construct a new instance. If no matching log context is found, the provided default selector is consulted.
*
* If the {@code checkParentClassLoaders} is set to {@code true} this selector recursively searches the class loader
* parents until a match is found or a {@code null} parent is found.
*
* @param defaultSelector the selector to consult if no matching log context is found
* @param checkParentClassLoaders {@code true} if the {@link org.jboss.logmanager.LogContext log context} could not
* found for the class loader and the {@link ClassLoader#getParent() parent class
* loader} should be checked
*/
public ClassLoaderLogContextSelector(final LogContextSelector defaultSelector, final boolean checkParentClassLoaders) {
this.defaultSelector = defaultSelector;
this.checkParentClassLoaders = checkParentClassLoaders;
}
/**
* Construct a new instance. If no matching log context is found, the system context is used.
*/
public ClassLoaderLogContextSelector() {
this(false);
}
/**
* Construct a new instance. If no matching log context is found, the system context is used.
*
* If the {@code checkParentClassLoaders} is set to {@code true} this selector recursively searches the class loader
* parents until a match is found or a {@code null} parent is found.
*
* @param checkParentClassLoaders {@code true} if the {@link org.jboss.logmanager.LogContext log context} could not
* found for the class loader and the {@link ClassLoader#getParent() parent class
* loader} should be checked
*/
public ClassLoaderLogContextSelector(final boolean checkParentClassLoaders) {
this(LogContext.DEFAULT_LOG_CONTEXT_SELECTOR, checkParentClassLoaders);
}
private final LogContextSelector defaultSelector;
private final ConcurrentMap contextMap = new CopyOnWriteMap();
private final Set logApiClassLoaders = Collections.newSetFromMap(new CopyOnWriteMap());
private final boolean checkParentClassLoaders;
private final PrivilegedAction logContextAction = new PrivilegedAction() {
public LogContext run() {
final Collection> callingClasses = JDKSpecific.findCallingClasses(logApiClassLoaders);
for (Class> caller : callingClasses) {
final LogContext result = check(caller.getClassLoader());
if (result != null) {
return result;
}
}
return defaultSelector.getLogContext();
}
private LogContext check(final ClassLoader classLoader) {
final LogContext context = contextMap.get(classLoader);
if (context != null) {
return context;
}
final ClassLoader parent = classLoader.getParent();
if (parent != null && checkParentClassLoaders && ! logApiClassLoaders.contains(parent)) {
return check(parent);
}
return null;
}
};
/**
* {@inheritDoc} This instance will consult the call stack to see if any calling classloader is associated
* with any log context.
*/
public LogContext getLogContext() {
return System.getSecurityManager() == null? logContextAction.run() :
AccessController.doPrivileged(logContextAction);
}
/**
* Register a class loader which is a known log API, and thus should be skipped over when searching for the
* log context to use for the caller class.
*
* @param apiClassLoader the API class loader
* @return {@code true} if this class loader was previously unknown, or {@code false} if it was already registered
*/
public boolean addLogApiClassLoader(ClassLoader apiClassLoader) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOG_API_PERMISSION);
}
return logApiClassLoaders.add(apiClassLoader);
}
/**
* Remove a class loader from the known log APIs set.
*
* @param apiClassLoader the API class loader
* @return {@code true} if the class loader was removed, or {@code false} if it was not known to this selector
*/
public boolean removeLogApiClassLoader(ClassLoader apiClassLoader) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOG_API_PERMISSION);
}
return logApiClassLoaders.remove(apiClassLoader);
}
/**
* Register a class loader with a log context. This method requires the {@code registerLogContext} {@link RuntimePermission}.
*
* @param classLoader the classloader
* @param logContext the log context
* @throws IllegalArgumentException if the classloader is already associated with a log context
*/
public void registerLogContext(ClassLoader classLoader, LogContext logContext) throws IllegalArgumentException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(REGISTER_LOG_CONTEXT_PERMISSION);
}
if (contextMap.putIfAbsent(classLoader, logContext) != null) {
throw new IllegalArgumentException("ClassLoader instance is already registered to a log context (" + classLoader + ")");
}
}
/**
* Unregister a class loader/log context association. This method requires the {@code unregisterLogContext} {@link RuntimePermission}.
*
* @param classLoader the classloader
* @param logContext the log context
* @return {@code true} if the association exists and was removed, {@code false} otherwise
*/
public boolean unregisterLogContext(ClassLoader classLoader, LogContext logContext) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(UNREGISTER_LOG_CONTEXT_PERMISSION);
}
return contextMap.remove(classLoader, logContext);
}
}
jboss-logmanager-2.1.14.Final/src/main/java/org/jboss/logmanager/ConcurrentReferenceHashMap.java 0000664 0000000 0000000 00000175027 13522561261 0032625 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
/*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/licenses/publicdomain
*/
package org.jboss.logmanager;
import java.io.IOException;
import java.io.Serializable;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
/**
* An advanced hash table supporting configurable garbage collection semantics
* of keys and values, optional referential-equality, full concurrency of
* retrievals, and adjustable expected concurrency for updates.
*
* This table is designed around specific advanced use-cases. If there is any
* doubt whether this table is for you, you most likely should be using
* {@link java.util.concurrent.ConcurrentHashMap} instead.
*
* This table supports strong, weak, and soft keys and values. By default keys
* are weak, and values are strong. Such a configuration offers similar behavior
* to {@link java.util.WeakHashMap}, entries of this table are periodically
* removed once their corresponding keys are no longer referenced outside of
* this table. In other words, this table will not prevent a key from being
* discarded by the garbage collector. Once a key has been discarded by the
* collector, the corresponding entry is no longer visible to this table;
* however, the entry may occupy space until a future table operation decides to
* reclaim it. For this reason, summary functions such as size and
* isEmpty might return a value greater than the observed number of
* entries. In order to support a high level of concurrency, stale entries are
* only reclaimed during blocking (usually mutating) operations.
*
* Enabling soft keys allows entries in this table to remain until their space
* is absolutely needed by the garbage collector. This is unlike weak keys which
* can be reclaimed as soon as they are no longer referenced by a normal strong
* reference. The primary use case for soft keys is a cache, which ideally
* occupies memory that is not in use for as long as possible.
*
* By default, values are held using a normal strong reference. This provides
* the commonly desired guarantee that a value will always have at least the
* same life-span as it's key. For this reason, care should be taken to ensure
* that a value never refers, either directly or indirectly, to its key, thereby
* preventing reclamation. If this is unavoidable, then it is recommended to use
* the same reference type in use for the key. However, it should be noted that
* non-strong values may disappear before their corresponding key.
*
* While this table does allow the use of both strong keys and values, it is
* recommended to use {@link java.util.concurrent.ConcurrentHashMap} for such a
* configuration, since it is optimized for that case.
*
* Just like {@link java.util.concurrent.ConcurrentHashMap}, this class obeys
* the same functional specification as {@link java.util.Hashtable}, and
* includes versions of methods corresponding to each method of
* Hashtable. However, even though all operations are thread-safe,
* retrieval operations do not entail locking, and there is
* not any support for locking the entire table in a way that
* prevents all access. This class is fully interoperable with
* Hashtable in programs that rely on its thread safety but not on
* its synchronization details.
*
*
* Retrieval operations (including get) generally do not block, so
* may overlap with update operations (including put and
* remove). Retrievals reflect the results of the most recently
* completed update operations holding upon their onset. For
* aggregate operations such as putAll and clear,
* concurrent retrievals may reflect insertion or removal of only some entries.
* Similarly, Iterators and Enumerations return elements reflecting the state of
* the hash table at some point at or since the creation of the
* iterator/enumeration. They do not throw
* {@link ConcurrentModificationException}. However, iterators are designed to
* be used by only one thread at a time.
*
*
* The allowed concurrency among update operations is guided by the optional
* concurrencyLevel constructor argument (default 16),
* which is used as a hint for internal sizing. The table is internally
* partitioned to try to permit the indicated number of concurrent updates
* without contention. Because placement in hash tables is essentially random,
* the actual concurrency will vary. Ideally, you should choose a value to
* accommodate as many threads as will ever concurrently modify the table. Using
* a significantly higher value than you need can waste space and time, and a
* significantly lower value can lead to thread contention. But overestimates
* and underestimates within an order of magnitude do not usually have much
* noticeable impact. A value of one is appropriate when it is known that only
* one thread will modify and all others will only read. Also, resizing this or
* any other kind of hash table is a relatively slow operation, so, when
* possible, it is a good idea to provide estimates of expected table sizes in
* constructors.
*
*
* This class and its views and iterators implement all of the optional
* methods of the {@link Map} and {@link Iterator} interfaces.
*
*
* Like {@link Hashtable} but unlike {@link HashMap}, this class does
* not allow null to be used as a key or value.
*
*
* This class is a member of the
* Java Collections Framework.
*
* @author Doug Lea
* @author Jason T. Greene
* @param the type of keys maintained by this map
* @param the type of mapped values
*/
final class ConcurrentReferenceHashMap extends AbstractMap
implements java.util.concurrent.ConcurrentMap, Serializable {
private static final long serialVersionUID = 7249069246763182397L;
/*
* The basic strategy is to subdivide the table among Segments,
* each of which itself is a concurrently readable hash table.
*/
/**
* An option specifying which Java reference type should be used to refer
* to a key and/or value.
*/
public static enum ReferenceType {
/** Indicates a normal Java strong reference should be used */
STRONG,
/** Indicates a {@link WeakReference} should be used */
WEAK,
/** Indicates a {@link SoftReference} should be used */
SOFT
};
public static enum Option {
/** Indicates that referential-equality (== instead of .equals()) should
* be used when locating keys. This offers similar behavior to {@link IdentityHashMap} */
IDENTITY_COMPARISONS
};
/* ---------------- Constants -------------- */
static final ReferenceType DEFAULT_KEY_TYPE = ReferenceType.WEAK;
static final ReferenceType DEFAULT_VALUE_TYPE = ReferenceType.STRONG;
/**
* The default initial capacity for this table,
* used when not otherwise specified in a constructor.
*/
static final int DEFAULT_INITIAL_CAPACITY = 16;
/**
* The default load factor for this table, used when not
* otherwise specified in a constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* The default concurrency level for this table, used when not
* otherwise specified in a constructor.
*/
static final int DEFAULT_CONCURRENCY_LEVEL = 16;
/**
* The maximum capacity, used if a higher value is implicitly
* specified by either of the constructors with arguments. MUST
* be a power of two <= 1<<30 to ensure that entries are indexable
* using ints.
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* The maximum number of segments to allow; used to bound
* constructor arguments.
*/
static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
/**
* Number of unsynchronized retries in size and containsValue
* methods before resorting to locking. This is used to avoid
* unbounded retries if tables undergo continuous modification
* which would make it impossible to obtain an accurate result.
*/
static final int RETRIES_BEFORE_LOCK = 2;
/* ---------------- Fields -------------- */
/**
* Mask value for indexing into segments. The upper bits of a
* key's hash code are used to choose the segment.
*/
final int segmentMask;
/**
* Shift value for indexing within segments.
*/
final int segmentShift;
/**
* The segments, each of which is a specialized hash table
*/
final Segment[] segments;
boolean identityComparisons;
transient Set keySet;
transient Set> entrySet;
transient Collection values;
/* ---------------- Small Utilities -------------- */
/**
* Applies a supplemental hash function to a given hashCode, which
* defends against poor quality hash functions. This is critical
* because ConcurrentReferenceHashMap uses power-of-two length hash tables,
* that otherwise encounter collisions for hashCodes that do not
* differ in lower or upper bits.
*/
private static int hash(int h) {
// Spread bits to regularize both segment and index locations,
// using variant of single-word Wang/Jenkins hash.
h += (h << 15) ^ 0xffffcd7d;
h ^= (h >>> 10);
h += (h << 3);
h ^= (h >>> 6);
h += (h << 2) + (h << 14);
return h ^ (h >>> 16);
}
/**
* Returns the segment that should be used for key with given hash
* @param hash the hash code for the key
* @return the segment
*/
final Segment segmentFor(int hash) {
return segments[(hash >>> segmentShift) & segmentMask];
}
private int hashOf(Object key) {
return hash(identityComparisons ?
System.identityHashCode(key) : key.hashCode());
}
/* ---------------- Inner Classes -------------- */
static interface KeyReference {
int keyHash();
Object keyRef();
}
/**
* A weak-key reference which stores the key hash needed for reclamation.
*/
static final class WeakKeyReference extends WeakReference implements KeyReference {
final int hash;
WeakKeyReference(K key, int hash, ReferenceQueue