Project

General

Profile

Bug #2442 » Utility.java

Michael Lee, 06/02/2006 09:39 AM

 
1
package org.vegbank.common.utility;
2

    
3
import java.io.*;
4
import java.net.URL;
5
import java.sql.*;
6
import java.text.DateFormat;
7
import java.util.*;
8
import java.util.regex.Matcher;
9
import java.util.regex.Pattern;
10
import javax.servlet.http.*;
11

    
12
import org.apache.commons.beanutils.BeanUtils;
13
import org.apache.commons.logging.Log;
14
import org.apache.commons.logging.LogFactory;
15
import org.vegbank.common.dbAdapter.AbstractDatabase;
16
import org.vegbank.common.model.Aux_role;
17
import org.vegbank.common.model.Place;
18
import org.vegbank.common.model.Plantconcept;
19
import org.vegbank.common.model.Plantstatus;
20
import org.vegbank.common.model.VBModelBean;
21
import org.vegbank.common.utility.mail.*;
22
import org.vegbank.common.Constants;
23

    
24
/*
25
 * '$RCSfile: Utility.java,v $'
26
 *
27
 * Purpose: An utility class for Vegbank project.
28
 *
29
 * '$Author: anderson $'
30
 * '$Date: 2005/07/27 22:24:35 $'
31
 * '$Revision: 1.52 $'
32
 *
33
 * This program is free software; you can redistribute it and/or modify
34
 * it under the terms of the GNU General Public License as published by
35
 * the Free Software Foundation; either version 2 of the License, or
36
 * (at your option) any later version.
37
 *
38
 * This program is distributed in the hope that it will be useful,
39
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
40
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
41
 * GNU General Public License for more details.
42
 *
43
 * You should have received a copy of the GNU General Public License
44
 * along with this program; if not, write to the Free Software
45
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
46
 */
47

    
48
public class Utility implements Constants
49
{
50
	/**
51
	 * Handle for logging
52
	 */
53
	private static Log log = LogFactory.getLog(Utility.class);
54

    
55
	public static AbstractDatabase dbAdapter;
56
	// FIXME: Read from properties
57
	public static  String DB_ADAPTER_NAME = "org.vegbank.common.dbAdapter.PostgresqlAdapter";
58

    
59
	// Bundle:  database
60
	public static String DATABASE_NAME;
61

    
62
	// Bundle:  general
63
	public static boolean AUTO_APPEND_WILDCARD = false;
64

    
65
	// Bundle:  vegbank
66
	public static ResourceBundle vegbankPropFile;
67
	public static ResourceBundle dbPropFile;
68
	public static String SMTP_SERVER;
69
	public static String SMTP_PORT;
70
	public static String VEGBANK_SCHEMA_LOCATION;
71
	public static String VEGBANK_SCHEMA_NAME;
72
	public static String VEGBANK_XML_SCHEMA;
73
	public static String VEGBANK_VERSION;
74
	public static String VEGBANK_XML_SCHEM;
75
	public static String VB_HOME_DIR;
76
	public static String VB_DATA_DIR;
77
	public static String VB_EXPORT_DIR;
78
	public static String VB_EXPORT_DIRNAME;
79
	public static String SERVER_ADDRESS;
80
	public static String WEBAPP_DIR;
81
	public static String WEB_DIR;
82
	public static String MODELBEAN_CACHING;
83
	public static String VB_EMAIL_FROM;
84
	public static String VB_EMAIL_ADMIN_TO;
85
	public static String VB_EMAIL_ADMIN_FROM;
86
	public static String DATABASE_ACCESSION_KEY_PREASSIGN;
87
	public static List DS_CANDIDATES;
88
	public static String PARAM_DELIM = "__";
89
	public static String DATACART_KEY = "datacart";   // found in session
90
	public static String DATACART_COUNT_KEY = "datacart-count";   // found in session
91

    
92

    
93
	static { try {
94
		// Bundle:  database; used elsewhere (e.g. dataload)
95
		dbPropFile = ResourceBundle.getBundle("database");
96
		DATABASE_NAME = dbPropFile.getString("databaseName");
97

    
98
		// Bundle:  general
99
		AUTO_APPEND_WILDCARD = false;
100
		String tmp = ResourceBundle.getBundle("general").getString("queries.auto_append_wildcard");
101
		if (!isStringNullOrEmpty(tmp) && !tmp.equals("false") && !tmp.equals("0")) {
102
			AUTO_APPEND_WILDCARD = true;
103
		}
104

    
105
		// Bundle:  vegbank
106
		vegbankPropFile = ResourceBundle.getBundle("vegbank");
107
		VEGBANK_SCHEMA_LOCATION = vegbankPropFile.getString("schemaLocation");
108
		if (!VEGBANK_SCHEMA_LOCATION.endsWith("/")) { VEGBANK_SCHEMA_LOCATION += "/"; }
109
		VEGBANK_SCHEMA_NAME = vegbankPropFile.getString("vegbankSchemaName");
110
		VEGBANK_VERSION = vegbankPropFile.getString("vegbankVersion");
111
		VEGBANK_XML_SCHEMA = VEGBANK_SCHEMA_LOCATION + VEGBANK_SCHEMA_NAME;
112

    
113
		SERVER_ADDRESS = vegbankPropFile.getString("serverAddress");
114
		WEBAPP_DIR = vegbankPropFile.getString("vegbank.webapp.dir");
115
		WEB_DIR = vegbankPropFile.getString("vegbank.web.dir");
116
		VB_HOME_DIR = vegbankPropFile.getString("vegbank.home.dir");
117
		VB_DATA_DIR = vegbankPropFile.getString("vegbank.data.dir");
118
		VB_EXPORT_DIRNAME = vegbankPropFile.getString("vegbank.export.dirname");
119
		VB_EXPORT_DIR = WEB_DIR + VB_EXPORT_DIRNAME;
120
		MODELBEAN_CACHING = vegbankPropFile.getString("modelbean.caching");
121

    
122
		SMTP_SERVER = vegbankPropFile.getString("mailHost");
123
		SMTP_PORT = vegbankPropFile.getString("mailPort");
124
		VB_EMAIL_FROM = vegbankPropFile.getString("systemEmail");
125
		VB_EMAIL_ADMIN_TO = vegbankPropFile.getString("admin.email.to");
126
		VB_EMAIL_ADMIN_FROM = vegbankPropFile.getString("admin.email.from");
127

    
128
        // accessionCode properties for this database:
129
        DATABASE_ACCESSION_KEY_PREASSIGN = vegbankPropFile.getString("database.accession.key.preassign");
130

    
131
	} catch (Exception ex) {
132
		log.error("There was a problem loading Utility properties", ex);
133
	} }
134

    
135

    
136
	/**
137
	 * Determine our db adapter class and create an instance of that class
138
	 */
139
	static
140
	{
141
		try
142
		{
143
			dbAdapter = (AbstractDatabase) createObject(DB_ADAPTER_NAME);
144
		}
145
		catch (Exception e)
146
		{
147
			log.error("Error in Vegbank Util static block:" + e.getMessage());
148
		}
149
	}
150

    
151
	/**
152
	 * There are some characters that need to be escaped before they are being
153
	 * written to the database, this escaping needs to be removed before usage.
154
	 *
155
	 * @param  s -- String to escape chars on
156
	 * @return ready for db write
157
	 */
158
	public static String decodeFromDB(String s)
159
	{
160
		// Handle nulls
161
		if ( s == null)
162
			return null;
163

    
164
		//String origString = s;
165

    
166
		// TODO: Implement this method
167
		// '' -> ', '$ -> $, '^ -> ^ ( perhaps removing all ' will work?)
168
		// needs experimentation
169

    
170
		//System.out.println("---->" + origString + " VS. " + s );
171
		return s;
172
	}
173

    
174
	/**
175
	 * There are some characters that need to be escaped before they are being
176
	 * written to the database
177
	 *
178
	 * @param s -- String to escape chars on
179
	 * @return String -- ready for db write
180
	 */
181
	public static String encodeForDB(String s)
182
	{
183
		// Handle nulls
184
		if ( s == null)
185
			return null;
186

    
187
		// List of characters to escape
188
		char[] specialChar = {'\'', '$', '^'};
189

    
190
		for (int i = 0; i < specialChar.length ; i++)
191
		{
192
			char currentChar = specialChar[i];
193
			//System.out.println("----->" + currentChar);
194

    
195
			if ( s.indexOf ( currentChar) != -1 )
196
			{
197
				StringBuffer hold = new StringBuffer();
198
				char c;
199
				for ( int ii = 0; ii < s.length(); ii++ )
200
				{
201
					if ( (c=s.charAt(ii)) == currentChar  )
202
						hold.append ("\\" + currentChar );
203
					else
204
						hold.append(c);
205
				}
206
				s = hold.toString();
207
			}
208
		}
209
		//System.out.println("---->" + origString + " VS. " + s );
210
		return s;
211
	}
212

    
213
  /**
214
   * Convert a string to a boolean.
215
   * Vegbank sometimes stores booleans in Strings for ease of use ( laziness )
216
   * This attemps to right that wrong by converting certain String patterns into
217
   * boolean values
218
   *
219
   * @param string String to test for true/t equality
220
   * @return is this a Stringified true?
221
   */
222
   public static boolean isTrue( String string)
223
   {
224
    boolean result = false;
225

    
226
    // Check for braindead stuff first
227
    if ( string == null || string.equals("") )
228
      return false;
229

    
230
    if ( string.equals("true") )
231
      return true;
232
    if ( string.equals("t") )
233
      return true;
234

    
235
    return result;
236

    
237
   }
238

    
239
	/**
240
	 * Thin wrapper around setting a date field in a PreparedStatement to handle
241
	 * adding nulls when needed, e.g. empty string.
242
	 *
243
	 * @param date
244
	 * @param psmnt
245
	 * @param i
246
	 * @throws SQLException
247
	 */
248
	public static void insertDateField ( String date, PreparedStatement psmnt, int i)
249
		throws SQLException
250
	{
251
		int sqlDateType = java.sql.Types.DATE;
252
		if ( date == null  ||  date.equals("") )
253
		{
254
			psmnt.setNull(i, sqlDateType);
255
		}
256
		else
257
		{
258
			// this maybe should be setDate
259
			psmnt.setString(i, date);
260
		}
261
	}
262

    
263
	/**
264
	 * Thin wrapper around setting a double field in a PreparedStatement to handle
265
	 * adding nulls when needed, e.g. empty string.
266
	 *
267
	 * @param number
268
	 * @param psmnt
269
	 * @param i
270
	 * @throws SQLException
271
	 */
272
	public static void insertDoubleField ( String number, PreparedStatement psmnt, int i)
273
		throws SQLException
274
	{
275
		int sqlDoubleType = java.sql.Types.DOUBLE;
276
		if ( number == null  ||  number.equals("") )
277
		{
278
			psmnt.setNull(i, sqlDoubleType);
279
		}
280
		else
281
		{
282
			// this maybe should be setDate
283
			psmnt.setString(i, number);
284
		}
285
	}
286

    
287
	/**
288
	 * Retrieves the content of a URL as a string
289
	 *
290
	 * @param u - the URL
291
	 * @return	String - the content of the URL
292
	 * @throws java.io.IOException
293
	 */
294
	public static String getURLContent(URL u) throws java.io.IOException
295
	{
296
			//System.out.println("url: " + u.toString());
297
			char istreamChar;
298
			int istreamInt;
299
			InputStreamReader istream = new InputStreamReader(u.openStream());
300
			StringBuffer serverResponse = new StringBuffer();
301
			while((istreamInt = istream.read()) != -1)
302
			{
303
				istreamChar = (char)istreamInt;
304
				serverResponse.append(istreamChar);
305
			}
306

    
307
			return serverResponse.toString();
308
		}
309

    
310

    
311
/**
312
 * <p>
313
 * Instantiate a class using the name of the class at runtime
314
 * </p>
315
 *
316
 * @param className
317
 *          the fully qualified name of the class to instantiate
318
 * @return Instance of the requested class
319
 * @throws Exception
320
 *           the class finding/creation exceptions
321
 */
322
	public static Object createObject(String className) throws Exception
323
	{
324

    
325
		Object object = null;
326
		try
327
		{
328
			Class classDefinition = Class.forName(className);
329
			object = classDefinition.newInstance();
330
		} catch (InstantiationException e)
331
		{
332
			throw e;
333
		} catch (IllegalAccessException e)
334
		{
335
			throw e;
336
		} catch (ClassNotFoundException e)
337
		{
338
			throw e;
339
		}
340
		return object;
341
	}
342

    
343
    /**
344
     * Generates a VBModelBean from the field names in a ResultSet.
345
     */
346
    public static VBModelBean buildBean(ResultSetMetaData meta, ResultSet rs, String beanName) {
347

    
348
        Object bean = null;
349
        try {
350
            if (rs == null || !rs.first()) { return null; }
351

    
352
            int colCount = meta.getColumnCount();
353
            bean = Utility.createObject(VBObjectUtils.DATA_MODEL_PACKAGE + beanName);
354

    
355
            // use DB column names to set properties
356
            for (int i=1; i<=colCount; i++) {
357
                String propName = meta.getColumnName(i);
358
                Object value = rs.getObject(i);
359
                //String value = rs.getString(i);
360
                try {
361
                    if (value != null) {
362
                        BeanUtils.copyProperty(bean, propName, value);
363
                    }
364
                } catch (Exception ex) {
365
                    log.debug("unable to set " + propName + " in bean " + beanName);
366
                }
367
            }
368
        } catch (Exception ex) {
369
            log.error("Problem building bean from DB results.", ex);
370
        }
371

    
372
        return (VBModelBean)bean;
373
    }
374

    
375

    
376
	/**
377
	 * <p>
378
	 * Utility Method to check for nulls and empty String
379
	 * </p>
380
	 *
381
	 * @param stringToCheck
382
	 * @return Is this Empty or null?
383
	 */
384
	public static boolean isStringNullOrEmpty(String stringToCheck)
385
	{
386
		return ( stringToCheck == null || stringToCheck.equals("") );
387
	}
388

    
389
	/**
390
	 * Return true if string is not "false", "no", "O", empty or null.
391
	 */
392
	public static boolean isStringTrue(String stringToCheck)
393
	{
394
		return !(Utility.isStringNullOrEmpty(stringToCheck) ||
395
				stringToCheck.equalsIgnoreCase("false") ||
396
				stringToCheck.equalsIgnoreCase("no") ||
397
				stringToCheck.equalsIgnoreCase("0"));
398
	}
399

    
400
	/**
401
	 * <p>
402
	 * Utility Method to check for nulls and empty array.
403
	 * </p>
404
	 *
405
	 * @param arrayToCheck
406
	 * @return Is this Empty or null?
407
	 */
408
	public static boolean isArrayNullOrEmpty(Object[] arrayToCheck)
409
	{
410
		return arrayToCheck == null || arrayToCheck.length == 0;
411
	}
412

    
413
	/**
414
	 * <p>
415
	 * Convience method to check several string for nullness or emtyness
416
	 * </p>
417
	 *
418
	 * @param stringsToCheck -- Array of Strings to check
419
	 * @return Are any of these Strings empty or null?
420
	 */
421
	public static boolean isAnyStringNullorEmpty( String[] stringsToCheck)
422
	{
423
		boolean result = false;
424
		for (int i = 0; i < stringsToCheck.length; i++)
425
		{
426
			if ( isStringNullOrEmpty(stringsToCheck[i]) )
427
			{
428
				result = true;
429
				return result;
430
			}
431
		}
432
		return result;
433
	}
434

    
435
	/**
436
	 * <p>
437
	 * Convience method to check several string for non nullness or non emtyness
438
	 * </p>
439
	 *
440
	 * @param stringsToCheck Array of <code>String</code>s to check
441
	 * @return Are any of these <code>Strings</code> NOT empty or null?
442
	 */
443
	public static boolean isAnyStringNotNullorEmpty( String[] stringsToCheck)
444
	{
445
		boolean result = false;
446
		for (int i = 0; i < stringsToCheck.length; i++)
447
		{
448
			if ( ! isStringNullOrEmpty(stringsToCheck[i]) )
449
			{
450
				result = true;
451
				return result;
452
			}
453
		}
454
		return result;
455
	}
456

    
457
	/**
458
	 * <p>
459
	 * Convience method to create a simple comma separted string from an <code>Object[]</code>.
460
	 * </p>
461
	 *
462
	 * @param objects
463
	 * 		Array of <code>Object</code>s to convert to comma separate <code>String</code>
464
	 * @return String
465
	 */
466
	public static String arrayToCommaSeparatedString(Object[] objects)
467
	{
468
		return joinArray(objects, ",");
469
	}
470

    
471
	/**
472
	 * <p>
473
	 * Convience method to create a simple delimetted <code>String</code> from
474
	 * an <code>Object[]</code>.
475
	 * </p>
476
	 *
477
	 * @param objects
478
	 * @param delimiter
479
	 * 		The delimeter to use when constructing the <code>String</code>
480
	 * @return The delimited List as <code>String</code>
481
	 */
482
	public static String joinArray(Object[] objects, String delimiter)
483
	{
484
		StringBuffer sb = new StringBuffer();
485
		for (int i=0; i < objects.length; i++)
486
		{
487
			sb.append(objects[i]);
488
			if( (i +1) < objects.length )
489
			{
490
				sb.append(delimiter);
491
			}
492
		}
493
		return sb.toString();
494
	}
495

    
496
	/**
497
	 * Capitalizes the first letter of a string. Leaves the rest of the Sting alone
498
	 * @param text
499
	 * @return String
500
	 */
501
	public static String upperCaseFirstLetter(String text)
502
	{
503
		String result = text.substring(0, 1).toUpperCase() + text.substring(1);
504
		//System.out.println("Utiltiy > " +result);
505
		return result;
506
	}
507

    
508
	/**
509
	 * Prints out a hashtable in an easy to read fashion
510
	 *
511
	 * @param hash -- hashtable to pretty print
512
	 */
513
	public static void prettyPrintHash( Hashtable hash )
514
	{
515
        if (hash == null) {
516
            return;
517
        }
518
		log.debug(prettyPrintHash(hash, 0));
519
	}
520

    
521
	private static String prettyPrintHash( Hashtable hash,  int indent)
522
	{
523
		//log.debug(indent +" -- "+hash.hashCode());
524
		StringBuffer sb = new StringBuffer(256);
525
		Iterator keys = hash.keySet().iterator();
526
		while ( keys.hasNext() )
527
		{
528
			Object key = keys.next();
529
			sb.append(getIdent( indent ) + key + ":");
530
			Object value = hash.get( key  );
531
			if ( value instanceof  java.util.Hashtable )
532
			{
533
				sb.append("\n");
534
				sb.append( prettyPrintHash( (Hashtable) value, indent + 1));
535
			}
536
			else if ( value instanceof java.util.Vector )
537
			{
538
				Iterator it =  ((Vector) value).iterator();
539
				while ( it.hasNext())
540
				{
541
					Object element = it.next();
542
					if ( element instanceof  java.util.Hashtable )
543
					{
544
						sb.append( "--->" +((Hashtable) element).get("TableName") );
545
						sb.append("\n");
546
						sb.append( prettyPrintHash( (Hashtable) element, indent + 1));
547
					}
548
				}
549
			}
550
			else
551
			{
552
				sb.append( "\t" + value + "\n");
553
			}
554
		}
555
		return sb.toString();
556
	}
557

    
558
	/**
559
	 * Gets current date and time using UTC Timezone.
560
	 *
561
	 * @return Date-- current Date
562
	 */
563
	public static java.util.Date getNow( )
564
	{
565
		// TODO: not tested yet
566
		Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
567
    	return cal.getTime();
568
	}
569

    
570
	/**
571
	 * Gets current date in a format that can be accepted
572
	 * by the RDBMS and that is like: Aug 9, 2002
573
	 *
574
	 * @return the date in a RDBMS format
575
	 */
576
	 public static String getCurrentDate()
577
	 {
578
	 	// TODO: use getNow() when it has been tested
579
		java.util.Date now = new java.util.Date();  //Set Date variable now to the current date and time
580
		DateFormat med = DateFormat.getDateInstance (DateFormat.MEDIUM);
581
		return med.format(now);
582
	 }
583

    
584
	/**
585
	 * Convience method for get a string of tabs
586
	 *
587
	 * @param indent
588
	 * @return
589
	 */
590
	private static String getIdent(int indent)
591
	{
592
		StringBuffer sb = new StringBuffer();
593
		for ( int i=0; i<indent; i++)
594
		{
595
			sb.append("\t");
596
		}
597
		return sb.toString();
598
	}
599

    
600
	/**
601
	 * <p>
602
	 * Convience method to get the VB Primary Key Name, basically
603
	 * handles expections to the naming conviention.
604
	 * </p>
605
	 *
606
	 * @param table The name of this table
607
	 * @return the PKName for this table
608
	 */
609
	public static String getPKNameFromTableName(String table)
610
	{
611
		String PKname = "";
612
		if ( table.equalsIgnoreCase("place"))
613
		{
614
			PKname = Place.PKNAME;
615
		}
616
		else if ( table.equalsIgnoreCase("aux_role") )
617
		{
618
			PKname = Aux_role.PKNAME;
619
		}
620
		else
621
		{
622
			PKname = table + "_ID";
623
		}
624
		return PKname;
625
	}
626

    
627
	/**
628
	 * <p>
629
	 * Foreign Key don't always have the same name as the primary key of the
630
	 * the the primary table, this is a utility to allow this lookup to happen.
631
	 * </br>
632
	 *
633
	 * <b>Not</b> a comprehensive lookup!
634
	 * </p>
635
	 *
636
	 * @param FKName The Foriegn Key name
637
	 * @return The Primary Key name that corresponds to the inputed FK name.
638
	 */
639
	public static String getPKNameFromFKName(String FKName)
640
	{
641
		// TODO: this is not comprehesive as this is only a problem
642
		// for some lookups, should be comprehensive to avoid misuse
643
		String PKname = "";
644
		if ( FKName.equalsIgnoreCase(Plantstatus.PLANTPARENT_ID))
645
		{
646
			PKname = Plantconcept.PKNAME;
647
		}
648
		else
649
		{
650
			PKname = FKName;
651
		}
652
		return PKname;
653
	}
654

    
655
	/**
656
	 * Only certain database names need to have accessionCodes loaded
657
	 *
658
	 * @return boolean
659
	 */
660
	public static boolean isLoadAccessionCodeOn()
661
	{
662
        // I'm not sure what we were thinking when this code was written,
663
        // but I'm disabling it.  2/1/2005 PMA
664
        return true;
665

    
666
        /*
667
		boolean genAC = false;
668
		log.debug("Utility: databaseName = " + DATABASE_NAME);
669

    
670
		if (DATABASE_NAME.equalsIgnoreCase("vegbank") || DATABASE_NAME.equalsIgnoreCase("vegtest")) {
671
			genAC = true;
672
		} else {
673
			genAC = false;
674
		}
675
		return genAC;
676
        */
677
	}
678

    
679
	/**
680
	 * @return
681
	 */
682
	public static String getAccessionPrefix()
683
	{
684
		String accessionPrefix = "";
685

    
686
		// This is a function of database name and host machine
687
		if ( DATABASE_NAME.equalsIgnoreCase("vegbank"))
688
		{
689
			accessionPrefix = vegbankPropFile.getString("vegbank.accession.prefix");
690
			if (Utility.isStringNullOrEmpty(accessionPrefix)) {
691
			    accessionPrefix = "VB";
692
            } else {
693
			    accessionPrefix = accessionPrefix.toUpperCase();
694
            }
695
		}
696
		else if ( DATABASE_NAME.equalsIgnoreCase("vegtest"))
697
		{
698
			accessionPrefix = "VT";
699
		}
700
		else
701
		{
702
			accessionPrefix = "NOTVALID";
703
		}
704

    
705
		return accessionPrefix;
706
	}
707

    
708
	/**
709
	 * Convert an inputstream to a String. Not sure how the handle encoding
710
	 * so using System default for now.
711
	 *
712
	 * @param is
713
	 * @return
714
	 * @throws IOException
715
	 */
716
	public static String getStringFromInputStream(InputStream is) throws IOException
717
	{
718
		InputStreamReader reader = new InputStreamReader(is);
719
		char[] buffer = new char[4096];
720

    
721
		StringWriter writer = new StringWriter();
722

    
723
		int bytes_read;
724
		while ((bytes_read = reader.read(buffer)) != -1)
725
		{
726
			writer.write(buffer, 0, bytes_read);
727
		}
728

    
729
		String result = writer.toString();
730
		return result;
731
	}
732

    
733
	/**
734
	 * Convience method to Uppercase first char of a String and lower case
735
	 * the rest
736
	 * @param stringToCapitalize
737
	 * @return
738
	 */
739
	public static String upperCaseFirstChar(String stringToCapitalize )
740
	{
741
		StringBuffer result = new StringBuffer();
742
		result.append( stringToCapitalize.substring(0,1).toUpperCase() );
743
		result.append( stringToCapitalize.substring(1).toLowerCase() );
744
		return result.toString();
745
	}
746

    
747
	/**
748
	 * Parse up an Accessioncode into its parts
749
	 *
750
	 * @param accessionCode Vegbank AC to be parsed.
751
	 * @return code, entityname, key in a <code>String[]</code>
752
	 */
753
	public static HashMap parseAccessionCode(String accessionCode)
754
	{
755
		String DBCODE = "DBCODE";
756
		String ENTITYCODE = "ENTITYCODE";
757
		String KEYVALUE = "KEYVALUE";
758
		String CONFIMATIONCODE = "CONFIMATIONCODE";
759

    
760
		HashMap parsedAC = new HashMap();
761
		// method
762
		log.debug("Utility: accessionCode = " + accessionCode);
763
		Pattern pattern = Pattern.compile("([^\\.]*)\\.([^\\.]*)\\.([^\\.]*)\\.{0,1}([^\\.]*)");
764
		Matcher m = pattern.matcher(accessionCode);
765
		if ( m.find() )
766
		{
767
			parsedAC.put("DBCODE", m.group(1) );
768
			parsedAC.put("ENTITYCODE", m.group(2) );
769
			parsedAC.put("KEYVALUE", m.group(3) );
770
			parsedAC.put("CONFIMATIONCODE", m.group(4) );
771
		}
772
		log.debug("Parsed an AccessionCode: DBCode > '" + parsedAC.get(DBCODE) + "' ENTITYCODE > '" + parsedAC.get(ENTITYCODE) + "' KEYVALUE > '" + parsedAC.get(KEYVALUE) + "' CONFIMATIONCODE > '" + parsedAC.get(CONFIMATIONCODE) + "'"  );
773
		return parsedAC;
774
	}
775

    
776
	/**
777
	 * Ugly hack to test if an entityCode is a root entity or not.
778
	 *
779
	 * @param entityCode
780
 	 * @return Is root entity?
781
	 */
782
	public static boolean isRootEntity(String entityCode)
783
	{
784
		boolean result = false;
785

    
786
		if (entityCode.equalsIgnoreCase("OB") || entityCode.equalsIgnoreCase("PC")
787
				|| entityCode.equalsIgnoreCase("CC"))
788
		{
789
			result = true;
790
		}
791

    
792
		return result;
793
	}
794

    
795
	/**
796
	 * Create and write a temp file in the system tmp dir (/tmp).
797
	 *
798
	 * @param in
799
	 *          Reader to write out to filesystem
800
	 * @throws IOException
801
	 * @return path to temp file
802
	 */
803
	public static String writeTempFile(Reader in) throws IOException
804
	{
805
        File outputFile = File.createTempFile(Integer.toString(in.hashCode()), null);
806

    
807
        FileWriter out = new FileWriter(outputFile);
808
        int c;
809

    
810
        while ((c = in.read()) != -1)
811
            out.write(c);
812

    
813
        out.close();
814
        in.close();
815
        return outputFile.getAbsolutePath();
816
	}
817

    
818

    
819
	/**
820
	 * Tool to save a file to the filesystem.
821
	 *
822
	 * @param in
823
	 *          Reader to write out to filesystem
824
	 * @param filename
825
	 *          The name of the file to write to
826
	 * @throws IOException
827
	 */
828
	public static void saveFile( Reader in, String filename) throws IOException
829
	{
830
		File outputFile = new File(filename);
831

    
832
        if (!outputFile.exists()) {
833
            // create the file
834
            outputFile.createNewFile();
835
        }
836

    
837
        FileWriter out = new FileWriter(outputFile);
838
        int c;
839

    
840
        while ((c = in.read()) != -1)
841
            out.write(c);
842

    
843
        out.close();
844
        in.close();
845
	}
846

    
847

    
848
	/**
849
	 * Tool to delete a file from the filesystem.
850
	 *
851
	 * @param filename
852
	 *          The name of the file to write to
853
	 * @throws IOException
854
	 */
855
	public static void deleteFile(String filename) throws IOException
856
	{
857
		(new File(filename)).delete();
858
	}
859

    
860

    
861
    /**
862
     * Serialize a file.
863
     *
864
     * @param fileName
865
     * @param the Object
866
     * @throws IOException
867
     */
868
    public static void saveBinaryFile(String fileName, Object o) throws IOException {
869
        FileOutputStream fileOut = new FileOutputStream(new File(fileName));
870
        ObjectOutputStream objectOut = new ObjectOutputStream (fileOut);
871
        objectOut.writeObject(o);
872
    }
873

    
874

    
875
    /**
876
     * Deserialize a file.
877
     *
878
     * @param fileName
879
     * @param the Object
880
     * @throws IOException
881
     */
882
    public static Object loadBinaryFile(String fileName) throws IOException {
883
        FileInputStream fileIn = new FileInputStream(new File(fileName));
884
        ObjectInputStream objectIn = new ObjectInputStream(fileIn);
885
        try {
886
            return objectIn.readObject();
887
        } catch (Exception ex) {
888
            log.error("couldn't load binary file " + fileName, ex);
889
        }
890
        return null;
891
    }
892

    
893

    
894

    
895
	/**
896
	 *
897
	 */
898
	public static String capitalize(String str) {
899
		if (isStringNullOrEmpty(str)) {
900
			return "";
901
		}
902

    
903
		return Character.toUpperCase(str.charAt(0)) +
904
				str.toLowerCase().substring(1);
905
	}
906

    
907

    
908
	/**
909
	 * @return true if the value of the given string is a number
910
	 */
911
	public static boolean isNumeric(String s) {
912
		if (Utility.isStringNullOrEmpty(s)) {
913
			return false;
914
		}
915

    
916
		try { Long.parseLong(s); }
917
		catch (NumberFormatException nfex) { return false; }
918

    
919
		return true;
920
	}
921

    
922

    
923
	/**
924
	 * @return true if the first/only value of the given
925
	 *    comma-separated list is a number
926
	 */
927
	public static boolean isNumericList(String csv) {
928
		if (Utility.isStringNullOrEmpty(csv)) {
929
			return false;
930
		}
931

    
932
		String value = csv;
933
		if (csv.indexOf(',') != -1 || csv.indexOf('|') != -1) {
934
			// a list
935
			StringTokenizer st = new StringTokenizer(csv, ",|");
936
			if (st.hasMoreTokens()) { value = st.nextToken(); }
937
		}
938

    
939
		return isNumeric(value);
940
	}
941

    
942

    
943
	/**
944
	 *
945
	 */
946
	public static void notifyAdmin(String subject, String body) {
947
		String adminFromEmail = vegbankPropFile.getString("admin.email.from");
948
		String adminToEmail = vegbankPropFile.getString("admin.email.to");
949
		String server = vegbankPropFile.getString("machine_url");
950

    
951
		if (isStringNullOrEmpty(adminFromEmail)) { adminFromEmail = "site@vegbank.org"; }
952
		if (isStringNullOrEmpty(adminToEmail)) { adminToEmail = "dba@vegbank.org"; }
953
		if (isStringNullOrEmpty(server)) { server = "unknown vegbank host"; }
954

    
955
		try {
956
			Mailer m = new Mailer();
957
			m.sendPlain("ADMIN NOTIFICATION FROM " + server,
958
					"SUBJECT:  " + subject + "\n\n" + body, adminToEmail,
959
					null, null, adminFromEmail);
960
			log.info("Sent an email notification to admin re: " + subject);
961
		} catch (MailerException  mex) {
962
			log.error("Problem notifying admin", mex);
963
		}
964
	}
965

    
966
	/**
967
     *
968
	 * @return
969
	 */
970
	public static boolean canAddToDatasetOnLoad(String tableName) {
971
        if (Utility.isStringNullOrEmpty(tableName)) {
972
            log.debug("canAddToDatasetOnLoad(): given empty string");
973
            return false;
974
        }
975

    
976
        if (DS_CANDIDATES == null) {
977
            String s = vegbankPropFile.getString("dataset.candidates");
978
            StringTokenizer st = new StringTokenizer(s, ",");
979
            DS_CANDIDATES = new ArrayList();
980
            while (st.hasMoreTokens()) {
981
                DS_CANDIDATES.add(st.nextToken().toLowerCase());
982
            }
983
        }
984

    
985
        return DS_CANDIDATES.contains(tableName.toLowerCase());
986
    }
987

    
988
    /**
989
     * Returns a version of the given string that is no
990
     * longer than len chars and ends in "..." if
991
     * any chars were abbreviated (string was long).
992
     */
993
    public static String abbreviate(String src, int len) {
994
        if (Utility.isStringNullOrEmpty(src)) {
995
            return "";
996
        }
997
        if (src.length() > len) {
998
            return src.substring(0, len-3) + "...";
999
        } else {
1000
            return src;
1001
        }
1002
    }
1003

    
1004
    /**
1005
     * Returns usr_id of authenticated user, or null if not logged in.
1006
     */
1007
    public static Long getAuthenticatedUsrId(HttpSession session) {
1008
        return (Long)session.getAttribute(USER_KEY);
1009
    }
1010

    
1011
    /**
1012
     * Returns path and parameters for last search.
1013
     */
1014
    public static String getLastSearchURL(HttpSession session) {
1015
        String url = (String)session.getAttribute(LAST_SEARCH_URL);
1016
        if (url == null) {
1017
            url = "";
1018
        }
1019
        log.debug("GOT " + LAST_SEARCH_URL + ": " + url);
1020
        return url;
1021
    }
1022

    
1023
    /**
1024
     * Saves path and parameters for last search.
1025
     */
1026
    public static void setLastSearchURL(HttpServletRequest request) {
1027
        StringBuffer url = request.getRequestURL();
1028
        String qs = request.getQueryString();
1029
        if (qs != null) {
1030
            url.append("?").append(qs);
1031
        }
1032
        log.debug("setting " + LAST_SEARCH_URL + " to " + url.toString());
1033
        request.getSession().setAttribute(LAST_SEARCH_URL, url.toString());
1034
    }
1035

    
1036
    /**
1037
     *
1038
     */
1039
    public static String getVegBankProperty(String key) {
1040
        return vegbankPropFile.getString(key);
1041
    }
1042
}
(2-2/3)