src/share/jaxws_classes/com/sun/xml/internal/ws/policy/privateutil/PolicyUtils.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.ws.policy.privateutil;
  27 
  28 import com.sun.xml.internal.ws.policy.PolicyException;
  29 import java.io.Closeable;
  30 import java.io.IOException;
  31 import java.io.UnsupportedEncodingException;
  32 import java.lang.reflect.InvocationTargetException;
  33 import java.lang.reflect.Method;
  34 import java.net.URL;
  35 import java.util.ArrayList;
  36 import java.util.Arrays;
  37 import java.util.Collection;
  38 import java.util.Comparator;
  39 import java.util.LinkedList;
  40 import java.util.List;
  41 import java.util.Queue;

  42 import javax.xml.namespace.QName;
  43 import javax.xml.stream.XMLStreamException;
  44 import javax.xml.stream.XMLStreamReader;
  45 
  46 /**
  47  * This is a wrapper class for various utilities that may be reused within Policy API implementation.
  48  * The class is not part of public Policy API. Do not use it from your client code!
  49  *
  50  * @author Marek Potociar
  51  */
  52 public final class PolicyUtils {
  53     private PolicyUtils() { }
  54 
  55     public static class Commons {
  56         /**
  57          * Method returns the name of the method that is on the {@code methodIndexInStack}
  58          * position in the call stack of the current {@link Thread}.
  59          *
  60          * @param methodIndexInStack index to the call stack to get the method name for.
  61          * @return the name of the method that is on the {@code methodIndexInStack}


 183          * @return {@code -1} if {@code b1 < b2}, {@code 0} if {@code b1 == b2}, {@code 1} if {@code b1 > b2}
 184          */
 185         public static int compareBoolean(final boolean b1, final boolean b2) {
 186             final int i1 = (b1) ? 1 : 0;
 187             final int i2 = (b2) ? 1 : 0;
 188 
 189             return i1 - i2;
 190         }
 191 
 192         /**
 193          * Compares two String values, that may possibly be null in the following way: {@code null < "string value"}
 194          *
 195          * @return {@code -1} if {@code s1 < s2}, {@code 0} if {@code s1 == s2}, {@code 1} if {@code s1 > s2}
 196          */
 197         public static int compareNullableStrings(final String s1, final String s2) {
 198             return ((s1 == null) ? ((s2 == null) ? 0 : -1) : ((s2 == null) ? 1 : s1.compareTo(s2)));
 199         }
 200     }
 201 
 202     public static class Collections {

 203         /**
 204          * TODO javadocs
 205          *
 206          * @param initialBase the combination base that will be present in each combination. May be {@code null} or empty.
 207          * @param options options that should be combined. May be {@code null} or empty.
 208          * @param ignoreEmptyOption flag identifies whether empty options should be ignored or whether the method should halt
 209          *        processing and return {@code null} when an empty option is encountered
 210          * @return TODO
 211          */
 212         public static <E, T extends Collection<? extends E>, U extends Collection<? extends E>> Collection<Collection<E>> combine(final U initialBase, final Collection<T> options, final boolean ignoreEmptyOption) {
 213             List<Collection<E>> combinations = null;
 214             if (options == null || options.isEmpty()) {
 215                 // no combination creation needed
 216                 if (initialBase != null) {
 217                     combinations = new ArrayList<Collection<E>>(1);
 218                     combinations.add(new ArrayList<E>(initialBase));
 219                 }
 220                 return combinations;
 221             }
 222 


 228             /**
 229              * now we iterate over all options and build up an option processing queue:
 230              *   1. if ignoreEmptyOption flag is not set and we found an empty option, we are going to stop processing and return null. Otherwise we
 231              *      ignore the empty option.
 232              *   2. if the option has one child only, we add the child directly to the base.
 233              *   3. if there are more children in examined node, we add it to the queue for further processing and precoumpute the final size of
 234              *      resulting collection of combinations.
 235              */
 236             int finalCombinationsSize = 1;
 237             final Queue<T> optionProcessingQueue = new LinkedList<T>();
 238             for (T option : options) {
 239                 final int optionSize =  option.size();
 240 
 241                 if (optionSize == 0) {
 242                     if (!ignoreEmptyOption) {
 243                         return null;
 244                     }
 245                 } else if (optionSize == 1) {
 246                     base.addAll(option);
 247                 } else {
 248                     optionProcessingQueue.offer(option);



 249                     finalCombinationsSize *= optionSize;
 250                 }
 251             }
 252 
 253             // creating final combinations
 254             combinations = new ArrayList<Collection<E>>(finalCombinationsSize);
 255             combinations.add(base);
 256             if (finalCombinationsSize > 1) {
 257                 T processedOption;
 258                 while ((processedOption = optionProcessingQueue.poll()) != null) {
 259                     final int actualSemiCombinationCollectionSize = combinations.size();
 260                     final int newSemiCombinationCollectionSize = actualSemiCombinationCollectionSize * processedOption.size();
 261 
 262                     int semiCombinationIndex = 0;
 263                     for (E optionElement : processedOption) {
 264                         for (int i = 0; i < actualSemiCombinationCollectionSize; i++) {
 265                             final Collection<E> semiCombination = combinations.get(semiCombinationIndex); // unfinished combination
 266 
 267                             if (semiCombinationIndex + actualSemiCombinationCollectionSize < newSemiCombinationCollectionSize) {
 268                                 // this is not the last optionElement => we create a new combination copy for the next child


   1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.ws.policy.privateutil;
  27 
  28 import com.sun.xml.internal.ws.policy.PolicyException;
  29 import java.io.Closeable;
  30 import java.io.IOException;
  31 import java.io.UnsupportedEncodingException;
  32 import java.lang.reflect.InvocationTargetException;
  33 import java.lang.reflect.Method;
  34 import java.net.URL;
  35 import java.util.ArrayList;
  36 import java.util.Arrays;
  37 import java.util.Collection;
  38 import java.util.Comparator;
  39 import java.util.LinkedList;
  40 import java.util.List;
  41 import java.util.Queue;
  42 import java.util.logging.Level;
  43 import javax.xml.namespace.QName;
  44 import javax.xml.stream.XMLStreamException;
  45 import javax.xml.stream.XMLStreamReader;
  46 
  47 /**
  48  * This is a wrapper class for various utilities that may be reused within Policy API implementation.
  49  * The class is not part of public Policy API. Do not use it from your client code!
  50  *
  51  * @author Marek Potociar
  52  */
  53 public final class PolicyUtils {
  54     private PolicyUtils() { }
  55 
  56     public static class Commons {
  57         /**
  58          * Method returns the name of the method that is on the {@code methodIndexInStack}
  59          * position in the call stack of the current {@link Thread}.
  60          *
  61          * @param methodIndexInStack index to the call stack to get the method name for.
  62          * @return the name of the method that is on the {@code methodIndexInStack}


 184          * @return {@code -1} if {@code b1 < b2}, {@code 0} if {@code b1 == b2}, {@code 1} if {@code b1 > b2}
 185          */
 186         public static int compareBoolean(final boolean b1, final boolean b2) {
 187             final int i1 = (b1) ? 1 : 0;
 188             final int i2 = (b2) ? 1 : 0;
 189 
 190             return i1 - i2;
 191         }
 192 
 193         /**
 194          * Compares two String values, that may possibly be null in the following way: {@code null < "string value"}
 195          *
 196          * @return {@code -1} if {@code s1 < s2}, {@code 0} if {@code s1 == s2}, {@code 1} if {@code s1 > s2}
 197          */
 198         public static int compareNullableStrings(final String s1, final String s2) {
 199             return ((s1 == null) ? ((s2 == null) ? 0 : -1) : ((s2 == null) ? 1 : s1.compareTo(s2)));
 200         }
 201     }
 202 
 203     public static class Collections {
 204         private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyUtils.Collections.class);
 205         /**
 206          * TODO javadocs
 207          *
 208          * @param initialBase the combination base that will be present in each combination. May be {@code null} or empty.
 209          * @param options options that should be combined. May be {@code null} or empty.
 210          * @param ignoreEmptyOption flag identifies whether empty options should be ignored or whether the method should halt
 211          *        processing and return {@code null} when an empty option is encountered
 212          * @return TODO
 213          */
 214         public static <E, T extends Collection<? extends E>, U extends Collection<? extends E>> Collection<Collection<E>> combine(final U initialBase, final Collection<T> options, final boolean ignoreEmptyOption) {
 215             List<Collection<E>> combinations = null;
 216             if (options == null || options.isEmpty()) {
 217                 // no combination creation needed
 218                 if (initialBase != null) {
 219                     combinations = new ArrayList<Collection<E>>(1);
 220                     combinations.add(new ArrayList<E>(initialBase));
 221                 }
 222                 return combinations;
 223             }
 224 


 230             /**
 231              * now we iterate over all options and build up an option processing queue:
 232              *   1. if ignoreEmptyOption flag is not set and we found an empty option, we are going to stop processing and return null. Otherwise we
 233              *      ignore the empty option.
 234              *   2. if the option has one child only, we add the child directly to the base.
 235              *   3. if there are more children in examined node, we add it to the queue for further processing and precoumpute the final size of
 236              *      resulting collection of combinations.
 237              */
 238             int finalCombinationsSize = 1;
 239             final Queue<T> optionProcessingQueue = new LinkedList<T>();
 240             for (T option : options) {
 241                 final int optionSize =  option.size();
 242 
 243                 if (optionSize == 0) {
 244                     if (!ignoreEmptyOption) {
 245                         return null;
 246                     }
 247                 } else if (optionSize == 1) {
 248                     base.addAll(option);
 249                 } else {
 250                     boolean entered = optionProcessingQueue.offer(option);
 251                     if (!entered) {
 252                         throw LOGGER.logException(new RuntimePolicyUtilsException(LocalizationMessages.WSP_0096_ERROR_WHILE_COMBINE(option)), false, Level.WARNING);
 253                     }
 254                     finalCombinationsSize *= optionSize;
 255                 }
 256             }
 257 
 258             // creating final combinations
 259             combinations = new ArrayList<Collection<E>>(finalCombinationsSize);
 260             combinations.add(base);
 261             if (finalCombinationsSize > 1) {
 262                 T processedOption;
 263                 while ((processedOption = optionProcessingQueue.poll()) != null) {
 264                     final int actualSemiCombinationCollectionSize = combinations.size();
 265                     final int newSemiCombinationCollectionSize = actualSemiCombinationCollectionSize * processedOption.size();
 266 
 267                     int semiCombinationIndex = 0;
 268                     for (E optionElement : processedOption) {
 269                         for (int i = 0; i < actualSemiCombinationCollectionSize; i++) {
 270                             final Collection<E> semiCombination = combinations.get(semiCombinationIndex); // unfinished combination
 271 
 272                             if (semiCombinationIndex + actualSemiCombinationCollectionSize < newSemiCombinationCollectionSize) {
 273                                 // this is not the last optionElement => we create a new combination copy for the next child