Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) OSGi Alliance (2005, 2020). All Rights Reserved.
*
* 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.osgi.framework;
import static java.util.Objects.requireNonNull;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
import org.eclipse.osgi.internal.framework.FilterImpl;
import org.osgi.framework.connect.FrameworkUtilHelper;
/**
* Framework Utility class.
*
*
* This class contains utility methods which access Framework functions that may
* be useful to bundles.
*
* @since 1.3
* @ThreadSafe
* @author $Id: 587b532f95beab9767783aac4093d435516c4c08 $
*/
public class FrameworkUtil {
/**
* FrameworkUtil objects may not be constructed.
*/
private FrameworkUtil() {
// private empty constructor to prevent construction
}
/**
* Creates a {@code Filter} object. This {@code Filter} object may be used
* to match a {@code ServiceReference} object or a {@code Dictionary}
* object.
*
*
* If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
* thrown with a human readable message where the filter became unparsable.
*
*
* This method returns a Filter implementation which may not perform as well
* as the framework implementation-specific Filter implementation returned
* by {@link BundleContext#createFilter(String)}.
*
* @param filter The filter string.
* @return A {@code Filter} object encapsulating the filter string.
* @throws InvalidSyntaxException If {@code filter} contains an invalid
* filter string that cannot be parsed.
* @throws NullPointerException If {@code filter} is null.
*
* @see Filter
*/
public static Filter createFilter(String filter) throws InvalidSyntaxException {
return FilterImpl.newInstance(filter);
}
/**
* Match a Distinguished Name (DN) chain against a pattern. DNs can be
* matched using wildcards. A wildcard ({@code '*'} \u002A) replaces all
* possible values. Due to the structure of the DN, the comparison is more
* complicated than string-based wildcard matching.
*
* A wildcard can stand for zero or more DNs in a chain, a number of
* relative distinguished names (RDNs) within a DN, or the value of a single
* RDN. The DNs in the chain and the matching pattern are canonicalized
* before processing. This means, among other things, that spaces must be
* ignored, except in values.
*
* The most simple case is a single wildcard; it must match any DN. A
* wildcard can also replace the first list of RDNs of a DN. The first RDNs
* are the least significant. Such lists of matched RDNs can be empty.
*
* For example, a match pattern with a wildcard that matches all DNs that
* end with RDNs of o=ACME and c=US would look like this:
*
*
* *, o=ACME, c=US
*
*
* This match pattern would match the following DNs:
*
*
* cn = Bugs Bunny, o = ACME, c = US
* ou = Carrots, cn=Daffy Duck, o=ACME, c=US
* street = 9C\, Avenue St. Drézéry, o=ACME, c=US
* dc=www, dc=acme, dc=com, o=ACME, c=US
* o=ACME, c=US
*
*
* The following DNs would not match:
*
*
* street = 9C\, Avenue St. Drézéry, o=ACME, c=FR
* dc=www, dc=acme, dc=com, c=US
*
*
* If a wildcard is used for a value of an RDN, the value must be exactly *.
* The wildcard must match any value, and no substring matching must be
* done. For example:
*
*
* cn=*,o=ACME,c=*
*
*
* This match pattern with wildcard must match the following DNs:
*
*
* cn=Bugs Bunny,o=ACME,c=US
* cn = Daffy Duck , o = ACME , c = US
* cn=Road Runner, o=ACME, c=NL
*
* A match pattern may contain a chain of DN match patterns. The semicolon(
* {@code ';'} \u003B) must be used to separate DN match patterns in a
* chain. Wildcards can also be used to match against a complete DN within a
* chain.
*
* The following example matches a certificate signed by Tweety Inc. in the
* US.
*
*
*
* * ; ou=S & V, o=Tweety Inc., c=US
*
*
* The wildcard ('*') matches zero or one DN in the chain, however,
* sometimes it is necessary to match a longer chain. The minus sign (
* {@code '-'} \u002D) represents zero or more DNs, whereas the asterisk
* only represents a single DN. For example, to match a DN where the Tweety
* Inc. is in the DN chain, use the following expression:
*
*
*
* - ; *, o=Tweety Inc., c=US
*
*
* @param matchPattern The pattern against which to match the DN chain.
* @param dnChain The DN chain to match against the specified pattern. Each
* element of the chain must be of type {@code String} and use the
* format defined in RFC 2253.
* @return {@code true} If the pattern matches the DN chain; otherwise
* {@code false} is returned.
* @throws IllegalArgumentException If the specified match pattern or DN
* chain is invalid.
* @since 1.5
*/
public static boolean matchDistinguishedNameChain(String matchPattern, List dnChain) {
return DNChainMatching.match(matchPattern, dnChain);
}
/**
* Return a {@code Bundle} for the specified bundle class loader.
*
* @param bundleClassLoader A bundle class loader.
* @return An Optional containing {@code Bundle} for the specified bundle
* class loader or an empty Optional if the specified class loader
* is not associated with a specific bundle.
* @since 1.10
*/
public static Optional getBundle(ClassLoader bundleClassLoader) {
requireNonNull(bundleClassLoader);
return Optional
.ofNullable((bundleClassLoader instanceof BundleReference)
? ((BundleReference) bundleClassLoader).getBundle()
: null);
}
/**
* Return a {@code Bundle} for the specified bundle class.
*
* @param classFromBundle A class defined by a bundle.
* @return A {@code Bundle} for the specified bundle class or {@code null}
* if the specified class was not defined by a bundle.
* @since 1.5
*/
public static Bundle getBundle(Class< ? > classFromBundle) {
// We use doPriv since the caller may not have permission
// to call getClassLoader.
Optional cl = Optional
.ofNullable(AccessController.doPrivileged(
(PrivilegedAction) () -> classFromBundle
.getClassLoader()));
return cl.flatMap(FrameworkUtil::getBundle)
.orElseGet(() -> helpers.stream()
.map(helper -> helper.getBundle(classFromBundle))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst()
.orElse(null));
}
private final static List helpers;
static {
List l = new ArrayList<>();
try {
ServiceLoader helperLoader = AccessController
.doPrivileged(
(PrivilegedAction>) () -> ServiceLoader
.load(FrameworkUtilHelper.class,
FrameworkUtilHelper.class
.getClassLoader()));
helperLoader.forEach(l::add);
} catch (Throwable error) {
// try hard not to fail static
try {
Thread t = Thread.currentThread();
t.getUncaughtExceptionHandler().uncaughtException(t, error);
} catch (Throwable ignored) {
// we ignore this
}
}
helpers = Collections.unmodifiableList(l);
}
/**
* This class contains a method to match a distinguished name (DN) chain
* against and DN chain pattern.
*
* The format of DNs are given in RFC 2253. We represent a signature chain
* for an X.509 certificate as a semicolon separated list of DNs. This is
* what we refer to as the DN chain. Each DN is made up of relative
* distinguished names (RDN) which in turn are made up of key value pairs.
* For example:
*
*
*
* is made up of two DNs: "{@code cn=ben+ou=research,o=ACME,c=us} " and "
* {@code ou=Super CA,c=CA} ". The first DN is made of of three RDNs: "
* {@code cn=ben+ou=research}" and "{@code o=ACME}" and " {@code c=us}
* ". The first RDN has two name value pairs: " {@code cn=ben}" and "
* {@code ou=research}".
*
* A chain pattern makes use of wildcards ('*' or '-') to match against DNs,
* and wildcards ('*') to match againts DN prefixes, and value. If a DN in a
* match pattern chain is made up of a wildcard ("*"), that wildcard will
* match zero or one DNs in the chain. If a DN in a match pattern chain is
* made up of a wildcard ("-"), that wildcard will match zero or more DNs in
* the chain. If the first RDN of a DN is the wildcard ("*"), that DN will
* match any other DN with the same suffix (the DN with the wildcard RDN
* removed). If a value of a name/value pair is a wildcard ("*"), the value
* will match any value for that name.
*/
static private final class DNChainMatching {
private static final String MINUS_WILDCARD = "-";
private static final String STAR_WILDCARD = "*";
/**
* Check the name/value pairs of the rdn against the pattern.
*
* @param rdn List of name value pairs for a given RDN.
* @param rdnPattern List of name value pattern pairs.
* @return true if the list of name value pairs match the pattern.
*/
private static boolean rdnmatch(List> rdn, List> rdnPattern) {
if (rdn.size() != rdnPattern.size()) {
return false;
}
for (int i = 0; i < rdn.size(); i++) {
String rdnNameValue = (String) rdn.get(i);
String patNameValue = (String) rdnPattern.get(i);
int rdnNameEnd = rdnNameValue.indexOf('=');
int patNameEnd = patNameValue.indexOf('=');
if (rdnNameEnd != patNameEnd || !rdnNameValue.regionMatches(0, patNameValue, 0, rdnNameEnd)) {
return false;
}
String patValue = patNameValue.substring(patNameEnd);
String rdnValue = rdnNameValue.substring(rdnNameEnd);
if (!rdnValue.equals(patValue) && !patValue.equals("=*") && !patValue.equals("=#16012a")) {
return false;
}
}
return true;
}
private static boolean dnmatch(List> dn, List> dnPattern) {
int dnStart = 0;
int patStart = 0;
int patLen = dnPattern.size();
if (patLen == 0) {
return false;
}
if (dnPattern.get(0).equals(STAR_WILDCARD)) {
patStart = 1;
patLen--;
}
if (dn.size() < patLen) {
return false;
} else {
if (dn.size() > patLen) {
if (!dnPattern.get(0).equals(STAR_WILDCARD)) {
// If the number of rdns do not match we must have a
// prefix map
return false;
}
// The rdnPattern and rdn must have the same number of
// elements
dnStart = dn.size() - patLen;
}
}
for (int i = 0; i < patLen; i++) {
if (!rdnmatch((List>) dn.get(i + dnStart), (List>) dnPattern.get(i + patStart))) {
return false;
}
}
return true;
}
/**
* Parses a distinguished name chain pattern and returns a List where
* each element represents a distinguished name (DN) in the chain of
* DNs. Each element will be either a String, if the element represents
* a wildcard ("*" or "-"), or a List representing an RDN. Each element
* in the RDN List will be a String, if the element represents a
* wildcard ("*"), or a List of Strings, each String representing a
* name/value pair in the RDN.
*
* @param pattern
* @return a list of DNs.
* @throws IllegalArgumentException
*/
private static List