| /* | |
| * Copyright (c) 2005, 2024, 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 | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| package com.sun.jmx.mbeanserver; | |
| import java.util.ArrayList; | |
| import java.util.Arrays; | |
| import java.util.Collection; | |
| import java.util.Collections; | |
| import java.util.Comparator; | |
| import java.util.HashMap; | |
| import java.util.HashSet; | |
| import java.util.IdentityHashMap; | |
| import java.util.LinkedHashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.Set; | |
| import java.util.SortedMap; | |
| import java.util.TreeMap; | |
| import javax.management.MalformedObjectNameException; | |
| import javax.management.ObjectName; | |
| public class Util { | |
| static <K, V> Map<K, V> newMap() { | |
| return new HashMap<>(); | |
| } | |
| static <K, V> Map<K, V> newSynchronizedMap() { | |
| return Collections.synchronizedMap(Util.<K, V>newMap()); | |
| } | |
| static <K, V> IdentityHashMap<K, V> newIdentityHashMap() { | |
| return new IdentityHashMap<>(); | |
| } | |
| static <K, V> Map<K, V> newSynchronizedIdentityHashMap() { | |
| Map<K, V> map = newIdentityHashMap(); | |
| return Collections.synchronizedMap(map); | |
| } | |
| static <K, V> SortedMap<K, V> newSortedMap() { | |
| return new TreeMap<>(); | |
| } | |
| static <K, V> SortedMap<K, V> newSortedMap(Comparator<? super K> comp) { | |
| return new TreeMap<>(comp); | |
| } | |
| static <K, V> Map<K, V> newInsertionOrderMap() { | |
| return new LinkedHashMap<>(); | |
| } | |
| static <E> Set<E> newSet() { | |
| return new HashSet<>(); | |
| } | |
| static <E> Set<E> newSet(Collection<E> c) { | |
| return new HashSet<>(c); | |
| } | |
| static <E> List<E> newList() { | |
| return new ArrayList<>(); | |
| } | |
| static <E> List<E> newList(Collection<E> c) { | |
| return new ArrayList<>(c); | |
| } | |
| /* This method can be used by code that is deliberately violating the | |
| * allowed checked casts. Rather than marking the whole method containing | |
| * the code with @SuppressWarnings, you can use a call to this method for | |
| * the exact place where you need to escape the constraints. Typically | |
| * you will "import static" this method and then write either | |
| * X x = cast(y); | |
| * or, if that doesn't work (e.g. X is a type variable) | |
| * Util.<X>cast(y); | |
| */ | |
| @SuppressWarnings("unchecked") | |
| public static <T> T cast(Object x) { | |
| return (T) x; | |
| } | |
| /** | |
| * Computes a descriptor hashcode from its names and values. | |
| * @param names the sorted array of descriptor names. | |
| * @param values the array of descriptor values. | |
| * @return a hash code value, as described in {@link #hashCode(Descriptor)} | |
| */ | |
| public static int hashCode(String[] names, Object[] values) { | |
| int hash = 0; | |
| for (int i = 0; i < names.length; i++) { | |
| Object v = values[i]; | |
| int h; | |
| if (v == null) { | |
| h = 0; | |
| } else if (v instanceof Object[]) { | |
| h = Arrays.deepHashCode((Object[]) v); | |
| } else if (v.getClass().isArray()) { | |
| h = Arrays.deepHashCode(new Object[]{v}) - 31; | |
| // hashcode of a list containing just v is | |
| // v.hashCode() + 31, see List.hashCode() | |
| } else { | |
| h = v.hashCode(); | |
| } | |
| hash += names[i].toLowerCase().hashCode() ^ h; | |
| } | |
| return hash; | |
| } | |
| /** Match a part of a string against a shell-style pattern. | |
| The only pattern characters recognized are <code>?</code>, | |
| standing for any one character, | |
| and <code>*</code>, standing for any string of | |
| characters, including the empty string. For instance, | |
| {@code wildmatch("sandwich","sa?d*ch",1,4,1,4)} will match | |
| {@code "and"} against {@code "a?d"}. | |
| @param str the string containing the sequence to match. | |
| @param pat a string containing a pattern to match the sub string | |
| against. | |
| @param stri the index in the string at which matching should begin. | |
| @param strend the index in the string at which the matching should | |
| end. | |
| @param pati the index in the pattern at which matching should begin. | |
| @param patend the index in the pattern at which the matching should | |
| end. | |
| @return true if and only if the string matches the pattern. | |
| */ | |
| /* The algorithm is a classical one. We advance pointers in | |
| parallel through str and pat. If we encounter a star in pat, | |
| we remember its position and continue advancing. If at any | |
| stage we get a mismatch between str and pat, we look to see if | |
| there is a remembered star. If not, we fail. If so, we | |
| retreat pat to just past that star and str to the position | |
| after the last one we tried, and we let the match advance | |
| again. | |
| Even though there is only one remembered star position, the | |
| algorithm works when there are several stars in the pattern. | |
| When we encounter the second star, we forget the first one. | |
| This is OK, because if we get to the second star in A*B*C | |
| (where A etc are arbitrary strings), we have already seen AXB. | |
| We're therefore setting up a match of *C against the remainder | |
| of the string, which will match if that remainder looks like | |
| YC, so the whole string looks like AXBYC. | |
| */ | |
| public static boolean wildmatch(final String str, final String pat, | |
| int stri, final int strend, int pati, final int patend) { | |
| // System.out.println("matching "+pat.substring(pati,patend)+ | |
| // " against "+str.substring(stri, strend)); | |
| int starstri; // index for backtrack if "*" attempt fails | |
| int starpati; // index for backtrack if "*" attempt fails, +1 | |
| starstri = starpati = -1; | |
| /* On each pass through this loop, we either advance pati, | |
| or we backtrack pati and advance starstri. Since starstri | |
| is only ever assigned from pati, the loop must terminate. */ | |
| while (true) { | |
| if (pati < patend) { | |
| final char patc = pat.charAt(pati); | |
| switch (patc) { | |
| case '?': | |
| if (stri == strend) | |
| break; | |
| stri++; | |
| pati++; | |
| continue; | |
| case '*': | |
| pati++; | |
| starpati = pati; | |
| starstri = stri; | |
| continue; | |
| default: | |
| if (stri < strend && str.charAt(stri) == patc) { | |
| stri++; | |
| pati++; | |
| continue; | |
| } | |
| break; | |
| } | |
| } else if (stri == strend) | |
| return true; | |
| // Mismatched, can we backtrack to a "*"? | |
| if (starpati < 0 || starstri == strend) | |
| return false; | |
| // Retry the match one position later in str | |
| pati = starpati; | |
| starstri++; | |
| stri = starstri; | |
| } | |
| } | |
| /** Match a string against a shell-style pattern. The only pattern | |
| characters recognized are <code>?</code>, standing for any one | |
| character, and <code>*</code>, standing for any string of | |
| characters, including the empty string. | |
| @param str the string to match. | |
| @param pat the pattern to match the string against. | |
| @return true if and only if the string matches the pattern. | |
| */ | |
| public static boolean wildmatch(String str, String pat) { | |
| return wildmatch(str,pat,0,str.length(),0,pat.length()); | |
| } | |
| } |