001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package core.tut.pori.utils; 017 018import java.text.ParseException; 019import java.util.Date; 020 021import org.apache.commons.lang3.ArrayUtils; 022import org.apache.commons.lang3.time.FastDateFormat; 023import org.apache.log4j.Logger; 024 025 026/** 027 * A thread-safe utility class for processing Strings. 028 */ 029public final class StringUtils { 030 private static final FastDateFormat ISO_DATE = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZ"); 031 private static final Logger LOGGER = Logger.getLogger(StringUtils.class); 032 private static final String ZULU = "Z"; 033 034 /** 035 * 036 */ 037 private StringUtils(){ 038 // nothing needed 039 } 040 041 /** 042 * 043 * @param started 044 * @param finished 045 * @return string representation of the time interval between the given dates 046 */ 047 public static String getDurationString(Date started, Date finished){ 048 long duration_ms = finished.getTime() - started.getTime(); 049 long ms = ((duration_ms % 86400000) % 3600000) % 1000; 050 long s = (((duration_ms % 86400000) % 3600000) % 60000) /1000; 051 long min = ((duration_ms % 86400000) % 3600000)/60000; 052 long h = (duration_ms % 86400000)/3600000; 053 StringBuilder sb = new StringBuilder(); 054 if(h > 0){ 055 sb.append(String.valueOf(h)); 056 sb.append(" h"); 057 } 058 if(min > 0){ 059 if(sb.length() > 0) 060 sb.append(" "); 061 sb.append(String.valueOf(min)); 062 sb.append(" min"); 063 } 064 if(s > 0){ 065 if(sb.length() > 0) 066 sb.append(" "); 067 sb.append(String.valueOf(s)); 068 sb.append(" s"); 069 } 070 if(ms > 0){ 071 if(sb.length() > 0) 072 sb.append(" "); 073 sb.append(String.valueOf(ms)); 074 sb.append(" ms"); 075 } 076 if(sb.length() < 1){ 077 sb.append(" less than 1 ms"); 078 } 079 return sb.toString(); 080 } 081 082 /** 083 * This method is synchronized for the conversion 084 * 085 * @param date 086 * @return null if null passed, otherwise the passed string in format yyyy-MM-dd'T'HH:mm:ssZ 087 */ 088 public static String dateToISOString(Date date){ 089 return (date == null ? null : ISO_DATE.format(date)); 090 } 091 092 /** 093 * Note: this method will accept microseconds, but the actual microsecond values will be ignored, 094 * passing 2012-05-23T10:32:20.000000Z equals to passing 2012-05-23T10:32:20Z. 095 * 096 * Both Z and +XXXX are accepted timezone formats. 097 * 098 * @param date the passed string in format yyyy-MM-dd'T'HH:mm:ssZ 099 * @return the given string as ISODate or null if the string does not contain a valid date 100 */ 101 public static Date ISOStringToDate(String date){ 102 try { 103 int pointIndex = date.indexOf('.'); 104 if(pointIndex > 0){ // strip milliseconds 2012-05-23T10:32:20.XXXXXXZ 105 if(date.endsWith(ZULU)){ // strip the tailing Z as it creates issues with simple date format 106 date = date.substring(0, pointIndex)+"+0000"; 107 }else{ 108 int plusIndex = date.indexOf('+', pointIndex); 109 if(plusIndex < 0){ 110 LOGGER.error("Invalid date string."); 111 return null; 112 } 113 date = date.substring(0, pointIndex) + date.substring(plusIndex); 114 } 115 }else if(date.endsWith(ZULU)){ // strip the tailing Z as it creates issues with simple date format 116 date = date.substring(0, date.length()-1)+"+0000"; 117 } 118 return ISO_DATE.parse(date); 119 } catch (ParseException ex) {//+0300 120 LOGGER.error(ex, ex); 121 return null; 122 } 123 } 124 125 /** 126 * Uses DataTypeConverter to parse arbitrary date string to Date. 127 * @see javax.xml.bind.DatatypeConverter#parseDateTime(String) 128 * @param date 129 * @return the parsed date or null if null or empty date was passed 130 */ 131 public static Date stringToDate(String date){ 132 if(org.apache.commons.lang3.StringUtils.isBlank(date)){ 133 return null; 134 } 135 return javax.xml.bind.DatatypeConverter.parseDateTime(date).getTime(); 136 } 137 138 /** 139 * 140 * @param sb 141 * @param array array of items to append, if empty or null, this is a no-op 142 * @param separator separator used for the join operation, if empty or null the values will appended without separator 143 * @return the passed builder 144 * @throws IllegalArgumentException on bad data 145 */ 146 public static StringBuilder append(StringBuilder sb, int[] array, String separator) throws IllegalArgumentException{ 147 if(sb == null){ 148 throw new IllegalArgumentException("null builder."); 149 } 150 if(ArrayUtils.isEmpty(array)){ 151 LOGGER.debug("Ignored empty array."); 152 return sb; 153 } 154 155 boolean hasSeparator = !org.apache.commons.lang3.StringUtils.isBlank(separator); 156 157 sb.append(array[0]); 158 for(int i=1;i<array.length;++i){ 159 if(hasSeparator){ 160 sb.append(separator); 161 } 162 sb.append(array[i]); 163 } 164 return sb; 165 } 166 167 /** 168 * 169 * @param sb 170 * @param array array of items to append, if empty or null, this is a no-op 171 * @param separator separator used for the join operation, if empty or null the values will appended without separator 172 * @return the passed builder 173 * @throws IllegalArgumentException on bad data 174 */ 175 public static StringBuilder append(StringBuilder sb, long[] array, String separator) throws IllegalArgumentException{ 176 if(sb == null){ 177 throw new IllegalArgumentException("null builder."); 178 } 179 if(ArrayUtils.isEmpty(array)){ 180 LOGGER.debug("Ignored empty array."); 181 return sb; 182 } 183 184 boolean hasSeparator = !org.apache.commons.lang3.StringUtils.isBlank(separator); 185 186 sb.append(array[0]); 187 for(int i=1;i<array.length;++i){ 188 if(hasSeparator){ 189 sb.append(separator); 190 } 191 sb.append(array[i]); 192 } 193 return sb; 194 } 195}