1 /** 2 * Copyright 2014 Internet2 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 /* 17 * Licensed to the Apache Software Foundation (ASF) under one or more 18 * contributor license agreements. See the NOTICE file distributed with 19 * this work for additional information regarding copyright ownership. 20 * The ASF licenses this file to You under the Apache License, Version 2.0 21 * (the "License"); you may not use this file except in compliance with 22 * the License. You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 package edu.internet2.middleware.grouperClientExt.org.apache.commons.lang3; 33 34 /** 35 * <p>Operations on {@link java.lang.CharSequence} that are 36 * {@code null} safe.</p> 37 * 38 * @see java.lang.CharSequence 39 * @since 3.0 40 * @version $Id: CharSequenceUtils.java 1199894 2011-11-09 17:53:59Z ggregory $ 41 */ 42 public class CharSequenceUtils { 43 44 /** 45 * <p>{@code CharSequenceUtils} instances should NOT be constructed in 46 * standard programming. </p> 47 * 48 * <p>This constructor is public to permit tools that require a JavaBean 49 * instance to operate.</p> 50 */ 51 public CharSequenceUtils() { 52 super(); 53 } 54 55 //----------------------------------------------------------------------- 56 /** 57 * <p>Returns a new {@code CharSequence} that is a subsequence of this 58 * sequence starting with the {@code char} value at the specified index.</p> 59 * 60 * <p>This provides the {@code CharSequence} equivalent to {@link String#substring(int)}. 61 * The length (in {@code char}) of the returned sequence is {@code length() - start}, 62 * so if {@code start == end} then an empty sequence is returned.</p> 63 * 64 * @param cs the specified subsequence, null returns null 65 * @param start the start index, inclusive, valid 66 * @return a new subsequence, may be null 67 * @throws IndexOutOfBoundsException if {@code start} is negative or if 68 * {@code start} is greater than {@code length()} 69 */ 70 public static CharSequence subSequence(CharSequence cs, int start) { 71 return cs == null ? null : cs.subSequence(start, cs.length()); 72 } 73 74 //----------------------------------------------------------------------- 75 /** 76 * <p>Finds the first index in the {@code CharSequence} that matches the 77 * specified character.</p> 78 * 79 * @param cs the {@code CharSequence} to be processed, not null 80 * @param searchChar the char to be searched for 81 * @param start the start index, negative starts at the string start 82 * @return the index where the search char was found, -1 if not found 83 */ 84 static int indexOf(CharSequence cs, int searchChar, int start) { 85 if (cs instanceof String) { 86 return ((String) cs).indexOf(searchChar, start); 87 } else { 88 int sz = cs.length(); 89 if (start < 0) { 90 start = 0; 91 } 92 for (int i = start; i < sz; i++) { 93 if (cs.charAt(i) == searchChar) { 94 return i; 95 } 96 } 97 return -1; 98 } 99 } 100 101 /** 102 * Used by the indexOf(CharSequence methods) as a green implementation of indexOf. 103 * 104 * @param cs the {@code CharSequence} to be processed 105 * @param searchChar the {@code CharSequence} to be searched for 106 * @param start the start index 107 * @return the index where the search sequence was found 108 */ 109 static int indexOf(CharSequence cs, CharSequence searchChar, int start) { 110 return cs.toString().indexOf(searchChar.toString(), start); 111 // if (cs instanceof String && searchChar instanceof String) { 112 // // TODO: Do we assume searchChar is usually relatively small; 113 // // If so then calling toString() on it is better than reverting to 114 // // the green implementation in the else block 115 // return ((String) cs).indexOf((String) searchChar, start); 116 // } else { 117 // // TODO: Implement rather than convert to String 118 // return cs.toString().indexOf(searchChar.toString(), start); 119 // } 120 } 121 122 /** 123 * <p>Finds the last index in the {@code CharSequence} that matches the 124 * specified character.</p> 125 * 126 * @param cs the {@code CharSequence} to be processed 127 * @param searchChar the char to be searched for 128 * @param start the start index, negative returns -1, beyond length starts at end 129 * @return the index where the search char was found, -1 if not found 130 */ 131 static int lastIndexOf(CharSequence cs, int searchChar, int start) { 132 if (cs instanceof String) { 133 return ((String) cs).lastIndexOf(searchChar, start); 134 } else { 135 int sz = cs.length(); 136 if (start < 0) { 137 return -1; 138 } 139 if (start >= sz) { 140 start = sz - 1; 141 } 142 for (int i = start; i >= 0; --i) { 143 if (cs.charAt(i) == searchChar) { 144 return i; 145 } 146 } 147 return -1; 148 } 149 } 150 151 /** 152 * Used by the lastIndexOf(CharSequence methods) as a green implementation of lastIndexOf 153 * 154 * @param cs the {@code CharSequence} to be processed 155 * @param searchChar the {@code CharSequence} to be searched for 156 * @param start the start index 157 * @return the index where the search sequence was found 158 */ 159 static int lastIndexOf(CharSequence cs, CharSequence searchChar, int start) { 160 return cs.toString().lastIndexOf(searchChar.toString(), start); 161 // if (cs instanceof String && searchChar instanceof String) { 162 // // TODO: Do we assume searchChar is usually relatively small; 163 // // If so then calling toString() on it is better than reverting to 164 // // the green implementation in the else block 165 // return ((String) cs).lastIndexOf((String) searchChar, start); 166 // } else { 167 // // TODO: Implement rather than convert to String 168 // return cs.toString().lastIndexOf(searchChar.toString(), start); 169 // } 170 } 171 172 /** 173 * Green implementation of toCharArray. 174 * 175 * @param cs the {@code CharSequence} to be processed 176 * @return the resulting char array 177 */ 178 static char[] toCharArray(CharSequence cs) { 179 if (cs instanceof String) { 180 return ((String) cs).toCharArray(); 181 } else { 182 int sz = cs.length(); 183 char[] array = new char[cs.length()]; 184 for (int i = 0; i < sz; i++) { 185 array[i] = cs.charAt(i); 186 } 187 return array; 188 } 189 } 190 191 /** 192 * Green implementation of regionMatches. 193 * 194 * @param cs the {@code CharSequence} to be processed 195 * @param ignoreCase whether or not to be case insensitive 196 * @param thisStart the index to start on the {@code cs} CharSequence 197 * @param substring the {@code CharSequence} to be looked for 198 * @param start the index to start on the {@code substring} CharSequence 199 * @param length character length of the region 200 * @return whether the region matched 201 */ 202 static boolean regionMatches(CharSequence cs, boolean ignoreCase, int thisStart, 203 CharSequence substring, int start, int length) { 204 if (cs instanceof String && substring instanceof String) { 205 return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); 206 } else { 207 // TODO: Implement rather than convert to String 208 return cs.toString().regionMatches(ignoreCase, thisStart, substring.toString(), start, length); 209 } 210 } 211 212 }