Shuyi Chen | d7955ce | 2013-05-22 14:51:55 -0700 | [diff] [blame^] | 1 | /**
|
| 2 | * Copyright 2003-2007 Jive Software.
|
| 3 | *
|
| 4 | * All rights reserved. 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 | package org.jivesoftware.smackx.workgroup.util;
|
| 18 |
|
| 19 | import java.util.*;
|
| 20 |
|
| 21 | /**
|
| 22 | * Utility methods frequently used by data classes and design-time
|
| 23 | * classes.
|
| 24 | */
|
| 25 | public final class ModelUtil {
|
| 26 | private ModelUtil() {
|
| 27 | // Prevents instantiation.
|
| 28 | }
|
| 29 |
|
| 30 | /**
|
| 31 | * This is a utility method that compares two objects when one or
|
| 32 | * both of the objects might be <CODE>null</CODE> The result of
|
| 33 | * this method is determined as follows:
|
| 34 | * <OL>
|
| 35 | * <LI>If <CODE>o1</CODE> and <CODE>o2</CODE> are the same object
|
| 36 | * according to the <CODE>==</CODE> operator, return
|
| 37 | * <CODE>true</CODE>.
|
| 38 | * <LI>Otherwise, if either <CODE>o1</CODE> or <CODE>o2</CODE> is
|
| 39 | * <CODE>null</CODE>, return <CODE>false</CODE>.
|
| 40 | * <LI>Otherwise, return <CODE>o1.equals(o2)</CODE>.
|
| 41 | * </OL>
|
| 42 | * <p/>
|
| 43 | * This method produces the exact logically inverted result as the
|
| 44 | * {@link #areDifferent(Object, Object)} method.<P>
|
| 45 | * <p/>
|
| 46 | * For array types, one of the <CODE>equals</CODE> methods in
|
| 47 | * {@link java.util.Arrays} should be used instead of this method.
|
| 48 | * Note that arrays with more than one dimension will require some
|
| 49 | * custom code in order to implement <CODE>equals</CODE> properly.
|
| 50 | */
|
| 51 | public static final boolean areEqual(Object o1, Object o2) {
|
| 52 | if (o1 == o2) {
|
| 53 | return true;
|
| 54 | }
|
| 55 | else if (o1 == null || o2 == null) {
|
| 56 | return false;
|
| 57 | }
|
| 58 | else {
|
| 59 | return o1.equals(o2);
|
| 60 | }
|
| 61 | }
|
| 62 |
|
| 63 | /**
|
| 64 | * This is a utility method that compares two Booleans when one or
|
| 65 | * both of the objects might be <CODE>null</CODE> The result of
|
| 66 | * this method is determined as follows:
|
| 67 | * <OL>
|
| 68 | * <LI>If <CODE>b1</CODE> and <CODE>b2</CODE> are both TRUE or
|
| 69 | * neither <CODE>b1</CODE> nor <CODE>b2</CODE> is TRUE,
|
| 70 | * return <CODE>true</CODE>.
|
| 71 | * <LI>Otherwise, return <CODE>false</CODE>.
|
| 72 | * </OL>
|
| 73 | * <p/>
|
| 74 | */
|
| 75 | public static final boolean areBooleansEqual(Boolean b1, Boolean b2) {
|
| 76 | // !jwetherb treat NULL the same as Boolean.FALSE
|
| 77 | return (b1 == Boolean.TRUE && b2 == Boolean.TRUE) ||
|
| 78 | (b1 != Boolean.TRUE && b2 != Boolean.TRUE);
|
| 79 | }
|
| 80 |
|
| 81 | /**
|
| 82 | * This is a utility method that compares two objects when one or
|
| 83 | * both of the objects might be <CODE>null</CODE>. The result
|
| 84 | * returned by this method is determined as follows:
|
| 85 | * <OL>
|
| 86 | * <LI>If <CODE>o1</CODE> and <CODE>o2</CODE> are the same object
|
| 87 | * according to the <CODE>==</CODE> operator, return
|
| 88 | * <CODE>false</CODE>.
|
| 89 | * <LI>Otherwise, if either <CODE>o1</CODE> or <CODE>o2</CODE> is
|
| 90 | * <CODE>null</CODE>, return <CODE>true</CODE>.
|
| 91 | * <LI>Otherwise, return <CODE>!o1.equals(o2)</CODE>.
|
| 92 | * </OL>
|
| 93 | * <p/>
|
| 94 | * This method produces the exact logically inverted result as the
|
| 95 | * {@link #areEqual(Object, Object)} method.<P>
|
| 96 | * <p/>
|
| 97 | * For array types, one of the <CODE>equals</CODE> methods in
|
| 98 | * {@link java.util.Arrays} should be used instead of this method.
|
| 99 | * Note that arrays with more than one dimension will require some
|
| 100 | * custom code in order to implement <CODE>equals</CODE> properly.
|
| 101 | */
|
| 102 | public static final boolean areDifferent(Object o1, Object o2) {
|
| 103 | return !areEqual(o1, o2);
|
| 104 | }
|
| 105 |
|
| 106 |
|
| 107 | /**
|
| 108 | * This is a utility method that compares two Booleans when one or
|
| 109 | * both of the objects might be <CODE>null</CODE> The result of
|
| 110 | * this method is determined as follows:
|
| 111 | * <OL>
|
| 112 | * <LI>If <CODE>b1</CODE> and <CODE>b2</CODE> are both TRUE or
|
| 113 | * neither <CODE>b1</CODE> nor <CODE>b2</CODE> is TRUE,
|
| 114 | * return <CODE>false</CODE>.
|
| 115 | * <LI>Otherwise, return <CODE>true</CODE>.
|
| 116 | * </OL>
|
| 117 | * <p/>
|
| 118 | * This method produces the exact logically inverted result as the
|
| 119 | * {@link #areBooleansEqual(Boolean, Boolean)} method.<P>
|
| 120 | */
|
| 121 | public static final boolean areBooleansDifferent(Boolean b1, Boolean b2) {
|
| 122 | return !areBooleansEqual(b1, b2);
|
| 123 | }
|
| 124 |
|
| 125 |
|
| 126 | /**
|
| 127 | * Returns <CODE>true</CODE> if the specified array is not null
|
| 128 | * and contains a non-null element. Returns <CODE>false</CODE>
|
| 129 | * if the array is null or if all the array elements are null.
|
| 130 | */
|
| 131 | public static final boolean hasNonNullElement(Object[] array) {
|
| 132 | if (array != null) {
|
| 133 | final int n = array.length;
|
| 134 | for (int i = 0; i < n; i++) {
|
| 135 | if (array[i] != null) {
|
| 136 | return true;
|
| 137 | }
|
| 138 | }
|
| 139 | }
|
| 140 | return false;
|
| 141 | }
|
| 142 |
|
| 143 | /**
|
| 144 | * Returns a single string that is the concatenation of all the
|
| 145 | * strings in the specified string array. A single space is
|
| 146 | * put between each string array element. Null array elements
|
| 147 | * are skipped. If the array itself is null, the empty string
|
| 148 | * is returned. This method is guaranteed to return a non-null
|
| 149 | * value, if no expections are thrown.
|
| 150 | */
|
| 151 | public static final String concat(String[] strs) {
|
| 152 | return concat(strs, " "); //NOTRANS
|
| 153 | }
|
| 154 |
|
| 155 | /**
|
| 156 | * Returns a single string that is the concatenation of all the
|
| 157 | * strings in the specified string array. The strings are separated
|
| 158 | * by the specified delimiter. Null array elements are skipped. If
|
| 159 | * the array itself is null, the empty string is returned. This
|
| 160 | * method is guaranteed to return a non-null value, if no expections
|
| 161 | * are thrown.
|
| 162 | */
|
| 163 | public static final String concat(String[] strs, String delim) {
|
| 164 | if (strs != null) {
|
| 165 | final StringBuilder buf = new StringBuilder();
|
| 166 | final int n = strs.length;
|
| 167 | for (int i = 0; i < n; i++) {
|
| 168 | final String str = strs[i];
|
| 169 | if (str != null) {
|
| 170 | buf.append(str).append(delim);
|
| 171 | }
|
| 172 | }
|
| 173 | final int length = buf.length();
|
| 174 | if (length > 0) {
|
| 175 | // Trim trailing space.
|
| 176 | buf.setLength(length - 1);
|
| 177 | }
|
| 178 | return buf.toString();
|
| 179 | }
|
| 180 | else {
|
| 181 | return ""; // NOTRANS
|
| 182 | }
|
| 183 | }
|
| 184 |
|
| 185 | /**
|
| 186 | * Returns <CODE>true</CODE> if the specified {@link String} is not
|
| 187 | * <CODE>null</CODE> and has a length greater than zero. This is
|
| 188 | * a very frequently occurring check.
|
| 189 | */
|
| 190 | public static final boolean hasLength(String s) {
|
| 191 | return (s != null && s.length() > 0);
|
| 192 | }
|
| 193 |
|
| 194 |
|
| 195 | /**
|
| 196 | * Returns <CODE>null</CODE> if the specified string is empty or
|
| 197 | * <CODE>null</CODE>. Otherwise the string itself is returned.
|
| 198 | */
|
| 199 | public static final String nullifyIfEmpty(String s) {
|
| 200 | return ModelUtil.hasLength(s) ? s : null;
|
| 201 | }
|
| 202 |
|
| 203 | /**
|
| 204 | * Returns <CODE>null</CODE> if the specified object is null
|
| 205 | * or if its <CODE>toString()</CODE> representation is empty.
|
| 206 | * Otherwise, the <CODE>toString()</CODE> representation of the
|
| 207 | * object itself is returned.
|
| 208 | */
|
| 209 | public static final String nullifyingToString(Object o) {
|
| 210 | return o != null ? nullifyIfEmpty(o.toString()) : null;
|
| 211 | }
|
| 212 |
|
| 213 | /**
|
| 214 | * Determines if a string has been changed.
|
| 215 | *
|
| 216 | * @param oldString is the initial value of the String
|
| 217 | * @param newString is the new value of the String
|
| 218 | * @return true If both oldString and newString are null or if they are
|
| 219 | * both not null and equal to each other. Otherwise returns false.
|
| 220 | */
|
| 221 | public static boolean hasStringChanged(String oldString, String newString) {
|
| 222 | if (oldString == null && newString == null) {
|
| 223 | return false;
|
| 224 | }
|
| 225 | else if ((oldString == null && newString != null)
|
| 226 | || (oldString != null && newString == null)) {
|
| 227 | return true;
|
| 228 | }
|
| 229 | else {
|
| 230 | return !oldString.equals(newString);
|
| 231 | }
|
| 232 | }
|
| 233 |
|
| 234 | public static String getTimeFromLong(long diff) {
|
| 235 | final String HOURS = "h";
|
| 236 | final String MINUTES = "min";
|
| 237 | final String SECONDS = "sec";
|
| 238 |
|
| 239 | final long MS_IN_A_DAY = 1000 * 60 * 60 * 24;
|
| 240 | final long MS_IN_AN_HOUR = 1000 * 60 * 60;
|
| 241 | final long MS_IN_A_MINUTE = 1000 * 60;
|
| 242 | final long MS_IN_A_SECOND = 1000;
|
| 243 | diff = diff % MS_IN_A_DAY;
|
| 244 | long numHours = diff / MS_IN_AN_HOUR;
|
| 245 | diff = diff % MS_IN_AN_HOUR;
|
| 246 | long numMinutes = diff / MS_IN_A_MINUTE;
|
| 247 | diff = diff % MS_IN_A_MINUTE;
|
| 248 | long numSeconds = diff / MS_IN_A_SECOND;
|
| 249 | diff = diff % MS_IN_A_SECOND;
|
| 250 |
|
| 251 | StringBuilder buf = new StringBuilder();
|
| 252 | if (numHours > 0) {
|
| 253 | buf.append(numHours + " " + HOURS + ", ");
|
| 254 | }
|
| 255 |
|
| 256 | if (numMinutes > 0) {
|
| 257 | buf.append(numMinutes + " " + MINUTES + ", ");
|
| 258 | }
|
| 259 |
|
| 260 | buf.append(numSeconds + " " + SECONDS);
|
| 261 |
|
| 262 | String result = buf.toString();
|
| 263 | return result;
|
| 264 | }
|
| 265 |
|
| 266 |
|
| 267 | /**
|
| 268 | * Build a List of all elements in an Iterator.
|
| 269 | */
|
| 270 | public static <T> List<T> iteratorAsList(Iterator<T> i) {
|
| 271 | ArrayList<T> list = new ArrayList<T>(10);
|
| 272 | while (i.hasNext()) {
|
| 273 | list.add(i.next());
|
| 274 | }
|
| 275 | return list;
|
| 276 | }
|
| 277 |
|
| 278 | /**
|
| 279 | * Creates an Iterator that is the reverse of a ListIterator.
|
| 280 | */
|
| 281 | public static <T> Iterator<T> reverseListIterator(ListIterator<T> i) {
|
| 282 | return new ReverseListIterator<T>(i);
|
| 283 | }
|
| 284 | }
|
| 285 |
|
| 286 | /**
|
| 287 | * An Iterator that is the reverse of a ListIterator.
|
| 288 | */
|
| 289 | class ReverseListIterator<T> implements Iterator<T> {
|
| 290 | private ListIterator<T> _i;
|
| 291 |
|
| 292 | ReverseListIterator(ListIterator<T> i) {
|
| 293 | _i = i;
|
| 294 | while (_i.hasNext())
|
| 295 | _i.next();
|
| 296 | }
|
| 297 |
|
| 298 | public boolean hasNext() {
|
| 299 | return _i.hasPrevious();
|
| 300 | }
|
| 301 |
|
| 302 | public T next() {
|
| 303 | return _i.previous();
|
| 304 | }
|
| 305 |
|
| 306 | public void remove() {
|
| 307 | _i.remove();
|
| 308 | }
|
| 309 |
|
| 310 | }
|
| 311 |
|
| 312 |
|
| 313 |
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
|
| 319 |
|
| 320 |
|
| 321 |
|
| 322 | |