implemented a couple of getUuidAndTitleCache methods for agents
[cdmlib.git] / cdmlib-commons / src / main / java / eu / etaxonomy / cdm / common / CdmUtils.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.common;
12
13 import java.io.BufferedReader;
14 import java.io.File;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.InputStreamReader;
18 import java.lang.annotation.Annotation;
19 import java.lang.reflect.Field;
20 import java.lang.reflect.Modifier;
21 import java.net.HttpURLConnection;
22 import java.net.MalformedURLException;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import java.net.URL;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31 import org.apache.log4j.Logger;
32
33 /**
34 * @author a.mueller
35 *
36 */
37 public class CdmUtils {
38 private static final Logger logger = Logger.getLogger(CdmUtils.class);
39
40
41 static final String MUST_EXIST_FILE = "MUST-EXIST.txt";
42
43 //folder seperator
44 static String folderSeperator;
45
46
47 public static String getHomeDir() throws IOException{
48 String homeDirString = System.getenv("USERPROFILE") != null ? System.getenv("USERPROFILE") : System.getProperty("user.home");
49
50 if( ! new File(homeDirString).canWrite()){
51 throw new IOException("Can not write to home directory. Assumed path is: " + homeDirString);
52 }
53
54 return homeDirString;
55 }
56
57 /**
58 * Returns the an InputStream for a read-only source
59 * @param resourceFileName the resources path within the classpath(!)
60 * @return
61 * @throws IOException
62 */
63 public static InputStream getReadableResourceStream(String resourceFileName)
64 throws IOException{
65 InputStream urlStream = CdmUtils.class.getResourceAsStream("/"+ resourceFileName);
66 return urlStream;
67 }
68
69 /**
70 * Returns the an InputStream for a read-only source
71 * @param resourceFileName the resources path within the classpath(!)
72 * @return
73 * @throws IOException
74 */
75 public static InputStreamReader getUtf8ResourceReader(String resourceFileName)
76 throws IOException{
77 InputStream urlStream = CdmUtils.class.getResourceAsStream("/"+ resourceFileName);
78 InputStreamReader inputStreamReader = new InputStreamReader(urlStream, "UTF8");
79 return inputStreamReader;
80 }
81
82
83 /**
84 * @return
85 */
86 static public String getFolderSeperator(){
87 if (folderSeperator == null){
88 URL url = CdmUtils.class.getResource("/"+ MUST_EXIST_FILE);
89 if ( url != null && ! urlIsJarOrBundle(url) ){
90 folderSeperator = File.separator;
91 }else{
92 folderSeperator = "/";
93 }
94 }
95 return folderSeperator;
96 }
97
98
99 /**
100 * @param url
101 * @return
102 */
103 static private boolean urlIsJarOrBundle(URL url){
104 return url.getProtocol().startsWith("jar") || url.getProtocol().startsWith("bundleresource");
105 }
106
107 /**
108 * Returns the file name for the file in which 'clazz' is to be found (helps finding according libraries)
109 * @param clazz
110 * @return
111 */
112 static public String findLibrary(Class<?> clazz){
113 String result = null;
114 if (clazz != null){
115 String fullPackageName = clazz.getCanonicalName();
116 fullPackageName = fullPackageName.replace(".", "/");
117 URL url = CdmUtils.class.getResource("/" + fullPackageName + ".class" );
118 if (url != null){
119 result = url.getFile();
120 }else{
121 result = "";
122 }
123 logger.debug("LibraryURL for " + clazz.getCanonicalName() + " : " + result);
124 }
125 return result;
126 }
127
128 static public String testMe(){
129 String message = "This is a test";
130 System.out.println(message);
131 return message;
132 }
133
134 static public String readInputLine(String inputQuestion){
135 try {
136
137 System.out.print(inputQuestion);
138 BufferedReader in = new BufferedReader( new java.io.InputStreamReader( System.in ));
139 String input;
140 input = in.readLine();
141 return input;
142 } catch (IOException e) {
143 logger.warn("IOExeption");
144 return null;
145 }
146 }
147
148
149 /**
150 * Returns the trimmed value string if value is not <code>null</code>.
151 * Returns the empty string if value is <code>null</code>.
152 * @param value
153 * @return
154 */
155 static public String NzTrim(String value){
156 return (value == null ? "" : value);
157 }
158
159
160 /**
161 * Returns value if value is not <code>null</code>. Returns empty string if value is <code>null</code>.
162 * @param value
163 * @return
164 */
165 static public String Nz(String value){
166 return (value == null ? "" : value);
167 }
168
169
170 /**
171 * Returns value if value is not <code>null</code>. Returns 0 if value is <code>null</code>.
172 * @param value
173 * @return
174 */
175 static public Integer Nz(Integer value){
176 return (value == null ? 0 : value);
177 }
178
179 /**
180 * Returns value if value is not <code>null</code>. Returns 0 if value is <code>null</code>.
181 * @param value
182 * @return
183 */
184 static public Long Nz(Long value){
185 return (value == null ? 0 : value);
186 }
187
188 /**
189 * Concatenates an array of strings using the defined seperator.<BR>
190 * <code>Null</code> values are interpreted as empty strings.<BR>
191 * If all strings are <code>null</code> then <code>null</code> is returned.
192 * @param strings
193 * @param seperator
194 * @return String
195 */
196 static public String concat(CharSequence seperator, String[] strings){
197 String result = "";
198 boolean allNull = true;
199 for (String string : strings){
200 if (string != null){
201 if (result.length() > 0 && string.length() > 0){
202 result += seperator;
203 }
204 result += string;
205 allNull = false;
206 }
207 }
208 //if all strings are null result should be null, not ""
209 if (allNull){
210 return null;
211 }else {
212 return result;
213 }
214 }
215
216 /**
217 * Concatenates two strings, using the defined seperator.<BR>
218 * <code>Null</code> values are interpreted as empty Strings.<BR>
219 * If both strings are <code>null</code> then <code>null</code> is returned.
220 * @see #concat(CharSequence, String[])
221 * @param seperator
222 * @param string1
223 * @param string2
224 * @return String
225 */
226 static public String concat(CharSequence seperator, String string1, String string2){
227 String[] strings = {string1, string2};
228 return concat(seperator, strings);
229 }
230
231
232 /** Returns a version of the input where all contiguous
233 * whitespace characters are replaced with a single
234 * space. Line terminators are treated like whitespace.
235 *
236 * @param inputStr
237 * @return
238 */
239 public static CharSequence removeDuplicateWhitespace(CharSequence inputStr) {
240
241 String patternStr = "\\s+";
242 String replaceStr = " ";
243 Pattern pattern = Pattern.compile(patternStr);
244 Matcher matcher = pattern.matcher(inputStr);
245 return matcher.replaceAll(replaceStr);
246 }
247
248
249 /** Builds a list of strings by splitting an input string
250 * with delimiters whitespace, comma, or semicolon
251 * @param value
252 * @return
253 */
254 public static ArrayList<String> buildList(String value) {
255
256 ArrayList<String> resultList = new ArrayList<String>();
257 for (String tag : value.split("[\\s,;]+")) {
258 resultList.add(tag);
259 }
260 return resultList;
261 }
262
263
264 static public boolean urlExists(String strUrl, boolean withWarning){
265 try {
266 HttpURLConnection.setFollowRedirects(false);
267 // note : you may also need
268 // HttpURLConnection.setInstanceFollowRedirects(false)
269 HttpURLConnection con =
270 (HttpURLConnection) new URL(strUrl).openConnection();
271 con.setRequestMethod("HEAD");
272 return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
273 } catch (MalformedURLException e) {
274 if (withWarning) {
275 logger.warn(e);
276 }
277 } catch (IOException e) {
278 //
279 };
280 return false;
281 }
282
283 static public URI string2Uri(String string) {
284 URI uri = null;
285 try {
286 uri = new URI(string);
287 logger.debug("uri: " + uri.toString());
288 } catch (URISyntaxException ex) {
289 logger.error("Problem converting string " + string + " to URI " + uri);
290 return null;
291 }
292 return uri;
293 }
294
295 static public boolean isNumeric(String string){
296 if (string == null){
297 return false;
298 }
299 try {
300 Double.valueOf(string);
301 return true;
302 } catch (NumberFormatException e) {
303 return false;
304 }
305
306 }
307
308 /**
309 * Returns true if string is null, "" or string.trim() is ""
310 * @see isNotEmpty(String string)
311 * @param string
312 * @return
313 */
314 static public boolean isEmpty(String string){
315 if (string == null){
316 return true;
317 }
318 if ("".equals(string.trim())){
319 return true;
320 }
321 return false;
322 }
323
324 /**
325 * Tests if two objects are equal or both null. Otherwise returns false
326 * @param obj1
327 * @param obj2
328 * @return
329 */
330 public static boolean nullSafeEqual(Object obj1, Object obj2) {
331 if (obj1 == null && obj2 == null){
332 return true;
333 }
334 if (obj1 == null && obj2 != null){
335 return false;
336 }
337 return (obj1.equals(obj2));
338 }
339
340 /**
341 * Returns false if string is null, "" or string.trim() is ""
342 * Else true.
343 * @see isEmpty(String string)
344 * @param string
345 * @return
346 */
347 static public boolean isNotEmpty(String string){
348 return !isEmpty(string);
349 }
350
351
352 /**
353 * Computes all fields recursively
354 * @param clazz
355 * @return
356 */
357 public static Map<String, Field> getAllFields(Class clazz, Class highestClass, boolean includeStatic, boolean includeTransient, boolean makeAccessible, boolean includeHighestClass) {
358 Map<String, Field> result = new HashMap<String, Field>();
359 if ( highestClass.isAssignableFrom(clazz) && (clazz != highestClass || includeHighestClass)){
360 //exclude static
361 for (Field field: clazz.getDeclaredFields()){
362 if (includeStatic || ! Modifier.isStatic(field.getModifiers())){
363 if (includeTransient || ! isTransient(field)){
364 field.setAccessible(makeAccessible);
365 result.put(field.getName(), field);
366 }
367 }
368 }
369
370 //include superclass fields
371 Class superclass = clazz.getSuperclass();
372 if (superclass != null){
373 result.putAll(getAllFields(superclass, highestClass, includeStatic, includeTransient, makeAccessible, includeHighestClass));
374 }
375 }
376 return result;
377 }
378
379
380 /**
381 * Returns true, if field has an annotation of type javax.persistence.Annotation
382 * @param field
383 * @return
384 */
385 protected static boolean isTransient(Field field) {
386 for (Annotation annotation : field.getAnnotations()){
387 //if (Transient.class.isAssignableFrom(annotation.annotationType())){
388 if (annotation.annotationType().getSimpleName().equals("Transient")){
389 return true;
390 }
391 }
392 return false;
393 }
394 }