home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Languages Suite
/
ProgLangD.iso
/
VCAFE.3.0A
/
Sample.bin
/
WLAUtil.java
< prev
next >
Wrap
Text File
|
1998-11-05
|
20KB
|
545 lines
// Copyright (c) 1997, 1998 Symantec, Inc. All Rights Reserved.
// Static utility routines for the web log analyzer
import java.awt.Rectangle;
import java.awt.Component;
import java.awt.Window;
import java.awt.Frame;
import java.awt.Dialog;
import java.awt.TextField;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/*
This class encapsulates miscellaneous static utility routines used by the
web log analyzer.
*/
final class WLAUtil {
// Time conversion constants
static final long MILLISECS_PER_SECOND = 1000;
static final long MILLISECS_PER_MINUTE = 1000L*60L;
static final long MILLISECS_PER_HOUR = 1000L*60L*60L;
static final long MILLISECS_PER_DAY = 1000L*60L*60L*24L;
static final long MILLISECS_PER_WEEK = 1000L*60L*60L*24L*7L;
static final long MILLISECS_PER_YEAR = 1000L*60L*60L*24L*7L*52L;
static final long DAYS_AGO[] = {
MILLISECS_PER_DAY,
MILLISECS_PER_DAY * 6L,
MILLISECS_PER_DAY * 14L,
MILLISECS_PER_DAY * 29L,
MILLISECS_PER_DAY * 59L,
MILLISECS_PER_DAY * 89L
};
static final String TIME_INTERVAL_CP_NAMES[] = {
"Minutes", "Hours", "Days", "Weeks", "Years"
};
static final String TIME_INTERVAL_LS_NAMES[] = {
"minute", "hour", "day", "week", "year"
};
// Time formaters
static DateFormat dateFormat = makeGoodFor2000(DateFormat.getDateInstance(DateFormat.SHORT));
static DateFormat dateTimeFormat = makeGoodFor2000(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM));
static DateFormat dateTimeLongFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM);
static DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
// for recursion protection of the fatalProgramError method
static boolean bFatalProgramError = false;
/*
This is an all-static class.
Make the constructor private to no one accidentally tries to instantiate it.
*/
private WLAUtil() {
//{{INIT_CONTROLS
//}}
}
/*
Called when an unexpected error occurs (due to programming bug, etc).
Prints a stack trace to stderr, displays an alert, then exits the program.
*/
public static void fatalProgramError() {
fatalProgramError(null);
}
/*
Called when an unexpected error occurs (due to programming bug, etc).
Prints a stack trace to stderr, displays an alert, then exits the program.
If an exception is provided, uses that for its message and stack trace.
*/
public static void fatalProgramError(Throwable x) {
// Send error info to std err
System.err.println("Fatal program error:");
if(x == null) {
x = new Throwable();
} else {
System.err.println(x.toString());
}
x.printStackTrace();
System.err.flush();
// Try to display err message before stopping program
if(!bFatalProgramError && WebLogAnalyzer.theWLA != null) {
// protect against recursion
bFatalProgramError = true;
new AlertDialog(WebLogAnalyzer.theWLA,
false,
"Fatal progam error (software bug!)."
);
bFatalProgramError = false;
}
// Exit program
System.exit(-1);
}
/*
Parses date & time text (in local timezone), returning Date.
Throws a ParseException if a problem occurs.
*/
static Date string2DateTime(String dateTimeString) throws java.text.ParseException {
Date d;
// first assume time is included
try {
d = dateTimeFormat.parse(dateTimeString);
return d;
} catch(java.text.ParseException x) {
}
// try without time
d = dateFormat.parse(dateTimeString);
return d;
}
/*
Parses date text (in local timezone), returning Date.
Throws a ParseException if a problem occurs.
*/
static Date string2Date(String dateString) throws java.text.ParseException {
return dateFormat.parse(dateString);
}
/*
Parses time text (in local timezone), returning Date.
Throws a ParseException if a problem occurs.
*/
static Date string2Time(String timeString) throws java.text.ParseException {
return timeFormat.parse(timeString);
}
/*
Converts a Date to a String.
Returns a date-only string (without time) in the local timezone.
*/
static String date2String(Date date) {
return dateFormat.format(date);
}
/*
Converts a Date to a String.
Returns a date & time string in the local timezone.
*/
static String dateTime2String(Date date) {
return dateTimeFormat.format(date);
}
/*
Converts a date millisecond value (in GMT) to a String.
Returns a date & time string in the local timezone.
*/
static String millisecondsTime2String(long ms) {
return dateTime2String(new Date(ms));
}
/*
Converts a Date to a String.
Returns a verbose date & time string in the local timezone.
*/
static String dateTime2StringLong(Date date) {
return dateTimeLongFormat.format(date);
}
/*
Converts a time delta in milliseconds to a String.
Returns an HH:MM:SS formatted string.
*/
static String timeDelta2String(long millisecs) {
long hours = millisecs / MILLISECS_PER_HOUR;
long milliLeft = millisecs - (hours*MILLISECS_PER_HOUR);
long minutes = milliLeft / MILLISECS_PER_MINUTE;
milliLeft = milliLeft - (minutes*MILLISECS_PER_MINUTE);
long seconds = (milliLeft+500) / MILLISECS_PER_SECOND;
return hours + ":" + minutes + ":" + seconds;
}
/*
Converts a H:M:S formatted string into millisecs.
*/
static long string2TimeDelta(String str) throws java.text.ParseException {
int idx = 0;
try {
int idxEnd = str.indexOf(':');
long ms = 0;
ms += MILLISECS_PER_HOUR * Long.parseLong(str.substring(0, idxEnd));
idx = idxEnd+1;
idxEnd = str.indexOf(':', idx);
ms += MILLISECS_PER_MINUTE * Long.parseLong(str.substring(idx, idxEnd));
idx = idxEnd+1;
idxEnd = str.length();
ms += MILLISECS_PER_SECOND * Long.parseLong(str.substring(idx, idxEnd));
return ms;
} catch(NumberFormatException x) {
throw new java.text.ParseException("Invalid time delta numeric format in \"" + str + "\"", idx);
} catch(ArrayIndexOutOfBoundsException x) {
throw new java.text.ParseException("Invalid time delta format in \"" + str + "\"", idx);
}
}
/*
Validates the date & time entered in the given TextField.
If OK, returns true.
If fails, displays an alert then moves focus to offending TextField.
*/
static boolean validateDateField(Window dialogOrFrame, TextField dateField) {
try {
// Parse the date to ensure OK
string2Date(dateField.getText());
// Parsed OK. Passes validation
return true;
} catch(java.text.ParseException x) {
// Can't parse the given date. Move focus to offending field
dateField.requestFocus();
dateField.selectAll();
// Alert user
new AlertDialog(getFrame(dialogOrFrame), false, x.getMessage());
return false;
}
}
/**
Centers the given component relative to that component's parent.
*/
public static void centerInParent(Component comp) {
Rectangle bounds = comp.getParent().getBounds();
Rectangle abounds = comp.getBounds();
comp.setLocation( bounds.x + (bounds.width - abounds.width)/ 2,
bounds.y + (bounds.height - abounds.height)/2
);
}
/*
Determines the parent Frame of the given Dialog or Frame.
*/
static Frame getFrame(Window dialogOrFrame) {
Window w = dialogOrFrame;
while(w instanceof Dialog) {
w = (Window)w.getParent();
}
return (Frame)w;
}
/*
Given a timeframe choice (like: Report.TIMEFRAME_PAST_2_DAYS) returns
either the appropriate start or end date as text.
*/
static String timeframeChoice2DateString(int TIMEFRAME_, boolean wantStartDate) {
if(TIMEFRAME_ == Report.TIMEFRAME_ALL) {
return "(all dates)";
}
if(TIMEFRAME_ == Report.TIMEFRAME_SPECIFIC) {
fatalProgramError(); // unexpected
return null;
}
Date date = new Date();
if(TIMEFRAME_ == Report.TIMEFRAME_TODAY) {
return date2String(date);
}
long millisecs = date.getTime() - MILLISECS_PER_DAY;
if(TIMEFRAME_ != Report.TIMEFRAME_YESTERDAY && wantStartDate) {
millisecs -= DAYS_AGO[TIMEFRAME_ - Report.TIMEFRAME_PAST_2_DAYS];
}
date.setTime(millisecs);
return date2String(date);
}
/*
Given a time interval in milliseconds (like: WLAUtil.MILLISECS_PER_HOUR),
returns an index value:
0="Minutes", 1="Hours", 2="Days", 3="Weeks", 4="Years".
*/
static int timeInterval2Index(long timeInterval) {
switch((int)timeInterval) {
case (int)WLAUtil.MILLISECS_PER_MINUTE:
return 0;
case (int)WLAUtil.MILLISECS_PER_HOUR:
return 1;
case (int)WLAUtil.MILLISECS_PER_DAY:
return 2;
case (int)WLAUtil.MILLISECS_PER_WEEK:
return 3;
case (int)WLAUtil.MILLISECS_PER_YEAR:
return 4;
default:
WLAUtil.fatalProgramError();
return 0;
}
}
/*
Given a time interval in milliseconds (like: WLAUtil.MILLISECS_PER_HOUR),
returns an appropriate plural word starting with a capitalized letter:
"Minutes", "Hours", "Days", "Weeks", "Years".
*/
static String timeInterval2CapPluralString(long timeInterval) {
return TIME_INTERVAL_CP_NAMES[timeInterval2Index(timeInterval)];
}
/*
Given a time interval in milliseconds (like: WLAUtil.MILLISECS_PER_HOUR),
returns an appropriate singular word starting with a non-capitalized letter:
"minute", "hour", "day", "week", "year"
*/
static String timeInterval2LowerSingularString(long timeInterval) {
return TIME_INTERVAL_LS_NAMES[timeInterval2Index(timeInterval)];
}
/*
Given a string as entered by a user, automatically clean it up into the
desired URL string.
Sample actions:
"mylog.log" -> "http://mylog.log/"
"http://mylog.log" -> "http://mylog.log/"
"\mylog.log" -> "file:///\mylog.log"
"c:\mylog.log" -> "file:///c:\mylog.log"
*/
static String cleanupURLName(String messyURLText) {
// Infer starting "file://", etc as needed
try {
char ch;
StringBuffer buf;
// Colon?
int idx = messyURLText.indexOf(':');
if(idx < 0) {
// No colon.
buf = new StringBuffer(messyURLText.length() + 9);
ch = messyURLText.charAt(0);
if(ch == java.io.File.separatorChar) {
// Presume file entry
buf.append("file:///");
buf.append(messyURLText);
} else {
//Prepend http:// by default
buf.append("http://");
buf.append(messyURLText);
// if no slashes in messyURL, presume only domain given and end with one
if(-1 == messyURLText.indexOf('/')) {
buf.append('/');
}
}
return buf.toString();
}
// Have a colon in the messyURLText, look at char after the colon
ch = messyURLText.charAt(++idx);
if(ch == '/') {
ch = messyURLText.charAt(++idx);
if(ch == '/') {
idx = messyURLText.indexOf(':', ++idx);
if(idx < 0) {
// only initial "//" provided. Add ending one.
buf = new StringBuffer(messyURLText.length() + 2);
buf.append(messyURLText);
buf.append('/');
return buf.toString();
}
}
// protocol specified. Nothing to do.
return messyURLText;
}
if(ch == '\\') {
// MSDOS file path. Prefix file: protocol
return "file:///" + messyURLText;
}
//colon, but no slash...do nothing
} catch(StringIndexOutOfBoundsException x) {
// if get this, no cleanup
}
return messyURLText;
}
/*
Allows the user to browse locally for a log file.
Shows the standard open dialog, then, if the user chooses a file,
it "cleans up" the filename into a URL using the cleanupURLName()
method.
Template is the inititial filename in the open dialog.
If the user cancels the dialog, null is returned.
*/
public static String browseForURL(String template) {
// Access main frame which has the open dialog off it
WebLogAnalyzer wla = WebLogAnalyzer.theWLA;
// set the default suffix
wla.openFileURLDialog.setFile(template);
// Show the OpenFileDialog
wla.openFileURLDialog.show();
// get the results
String results = wla.openFileURLDialog.getFile();
if(results != null) {
results = wla.openFileURLDialog.getDirectory() + results;
results = WLAUtil.cleanupURLName(results);
}
return results;
}
/*
This sort routine was modified from Sun's SortDemo, and thus the long copyright, etc.
The original sorted an array of integers.
The modified version sorts an array of Objects the implement the Sortable interface.
*/
/*
* @(#)QSortAlgorithm.java 1.6 96/12/06
*
* Copyright (c) 1994-1996 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
public static void quickSort(Sortable a[])
{
doQuickSort(a, 0, a.length - 1);
}
/** This is a generic version of C.A.R Hoare's Quick Sort
* algorithm. This will handle arrays that are already
* sorted, and arrays with duplicate keys.<BR>
*
* If you think of a one dimensional array as going from
* the lowest index on the left to the highest index on the right
* then the parameters to this function are lowest index or
* left and highest index or right. The first time you call
* this function it will be with the parameters 0, a.length - 1.
*
* @param a an Sortable array
* @param lo0 left boundary of array partition
* @param hi0 right boundary of array partition
*/
private static void doQuickSort(Sortable a[], int lo0, int hi0)
{
int lo = lo0;
int hi = hi0;
Sortable midObj;
if ( hi0 > lo0)
{
/* Arbitrarily establishing partition element as the midpoint of
* the array.
*/
midObj = a[ ( lo0 + hi0 ) / 2 ];
// loop through the array until indices cross
while( lo <= hi )
{
/* find the first element that is greater than or equal to
* the partition element starting from the left Index.
*/
while( ( lo < hi0 ) && midObj.isLessThan(a[lo]))
++lo;
/* find an element that is smaller than or equal to
* the partition element starting from the right Index.
*/
while( ( hi > lo0 ) && !midObj.isLessThanOrEqual(a[hi]))
--hi;
// if the indexes have not crossed, swap
if( lo <= hi )
{
// swap
Sortable T;
T = a[lo];
a[lo] = a[hi];
a[hi] = T;
//
++lo;
--hi;
}
}
/* If the right index has not reached the left side of array
* must now sort the left partition.
*/
if( lo0 < hi )
doQuickSort( a, lo0, hi );
/* If the left index has not reached the right side of array
* must now sort the right partition.
*/
if( lo < hi0 )
doQuickSort( a, lo, hi0 );
}
}
/*
Ensures the given DateFormat has 4 year digits so that it may
handle the year 2000.
*/
private static DateFormat makeGoodFor2000(DateFormat dateFormat) {
SimpleDateFormat sdf;
try {
sdf = (SimpleDateFormat)dateFormat;
} catch(ClassCastException x) {
// can't handle this uncommon dateFormat
return dateFormat;
}
// ensure year displayed as 4 digits
String pattern = sdf.toLocalizedPattern();
int i = pattern.indexOf("yyyy");
if(i != -1) {
// pattern is already as a 4 digit year
return dateFormat;
}
// modify the pattern so that it has a 4 digit year
i = pattern.indexOf("yy");
if(i != -1) {
pattern = pattern.substring(0,i) + "yyyy" + pattern.substring(i+2, pattern.length());
sdf = new SimpleDateFormat(pattern);
}
return sdf;
}
//{{DECLARE_CONTROLS
//}}
}