Update of /cvsroot/displaytag/table-ben/src/com/tablelib/core/lang
In directory sc8-pr-cvs1:/tmp/cvs-serv11524
Added Files:
ArrayUtils.java CaseInsensitiveStringAndNumberComparator.java
LongUtils.java NumberUtils.java StringUtils.java
Log Message:
--- NEW FILE: ArrayUtils.java ---
/**
* Created by IntelliJ IDEA.
* User: Benjamin Simpson
* Date: Jan 11, 2003
* Time: 8:44:51 PM
*/
package com.tablelib.core.lang;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
public final class ArrayUtils {
private static final Class[] NO_CLASSES = new Class[0];
/**
* for each element in the array,
* @param values
* @param indexes
*/
private static void reorder(Object[] values, int[] indexes) {
int length = indexes.length;
Object[] newvalues = new Object[length];
for (int i = 0; i < length; i++) {
newvalues[i] = values[indexes[i]];
}
System.arraycopy(newvalues, 0, values, 0, length);
}
/**
* Why would you use this class.method?
* An object [] contains a value that you are interested in. The normal path
* to getting an array of the values would be:
* <ul>
* <li>Get the array
* <li>create another array
* <li>for each element in the array get the element's value
* <li>put the value in the other array
* <li>return the other array.
* </ul>
* Now imagine the simplicity of getting the values via the new method below:
* <ul>
* <li>Get the array
* <li>Call this class with the array, method name
* </ul>
*
* The overhead incurred in the encapsulation of the logic is that for each
* element in the object [] we are accessing, we call a reflective invoke:
*
* which invokes the native
*
*
*
*
* @param objs
* @param accessorName
* @param declaringClass
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws NoSuchMethodException
*/
public static Object[] accessValues(final Object[] objs, String accessorName,
Class declaringClass)
throws InvocationTargetException, IllegalAccessException,
NoSuchMethodException {
return getInnerValues(objs, makeAccessorMethod(accessorName, declaringClass));
}
/**
* Find the method in the class that returns the property named propname.
*
* This is done by checking for an accessor(anycase) for the prop. get(prop_name)
* we will be taking the first one.
*
* This task is done once per lifetime of the application.
* @param classObj
* @param methKey
* @param propName
* @return
*/
private static Method getMethod(final Class classObj,
final Object methKey,
String propName) {
Object methObj = methods.get(methKey);
if (methObj != null) return (Method) methObj;
Method[] methodArr = classObj.getMethods();
propName = "get"+propName.toLowerCase();
Method method = null;
for (int i = 0, len = methodArr.length; i < len; i++)
if ((method = methodArr[i]).getName().toLowerCase().indexOf(propName) >
-1) break;
if (method != null) methods.put(methKey, method);
return method;
}
public static void sort(final Object[] objs, String propName, boolean direction)
throws InvocationTargetException, IllegalAccessException {
int size = objs.length;
if (size < 2) return;
Class classObj = objs[0].getClass();
final String methodKey = classObj.getName() + "." +"get"+
propName.toLowerCase();
Method method = getMethod(classObj, methodKey, propName);
Object[] unsortedValues = getInnerValues(objs, method);
Object[] sortedValues = new Object[size];
System.arraycopy(unsortedValues, 0, sortedValues, 0, size);
Object[] returnObjs = new Object[size];
Arrays.sort(sortedValues);
for (int i = 0; i < size; i++) {
Object val = sortedValues[i];
for (int j = 0; j < size; j++) {
if (!val.equals(unsortedValues[j])) continue;
returnObjs[i] = objs[j];
}
}
if(!direction) {
System.arraycopy(returnObjs,0,objs,0,size);
return;
}
for (int i = 0, len = objs.length; i < len; i++) objs[i] = returnObjs[--size];
}
/**
*
* @param objs
* @param method
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
private static Object[] getInnerValues(final Object[] objs, Method method)
throws InvocationTargetException, IllegalAccessException {
int size = objs.length;
Object[] values = new Object[size];
for (int i = 0; i < size; i++)
values[i] = method.invoke(objs[i], NO_CLASSES);
return values;
}
/**
*
* @param comp
* @param objs
* @param accessorName
* @param declaringClass
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws NoSuchMethodException
*/
private static Object[] getSortedInnerValues(Comparator comp,
final Object[] objs,
String accessorName,
Class declaringClass)
throws InvocationTargetException, IllegalAccessException,
NoSuchMethodException {
Object[] values = accessValues(objs, accessorName, declaringClass);
Arrays.sort(values, comp);
return values;
}
/**
*
* @param accessorName
* @param declaringClass
* @return
* @throws NoSuchMethodException
*/
private static Method makeAccessorMethod(String accessorName, Class declaringClass)
throws NoSuchMethodException {
final String methodKey = accessorName + declaringClass.getName();
Object obj = methods.get(methodKey);
if (obj != null) return (Method) obj;
Method method = declaringClass.getMethod(accessorName, NO_CLASSES);
methods.put(methodKey, method); //added to system state.
return method;
}
public static String[] asStrings(Object[] objs) {
int len = objs.length;
String[] strs = new String[len];
for (int i = 0; i < len; i++) strs[i] = (String) objs[i];
return strs;
}
/****************** static state **************************/
private static final Map methods = makeMethodsMap(1);
private static Map makeMethodsMap(int size) {
return Collections.synchronizedMap(new HashMap(size, 1f));
}
/******************* test case ******************************/
/**
* Test case :)
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Object[] testStrings = {"All", "Cool", "dudes", "eat", "apple", "pie"};
int[] neworder = new int[]{0, 2, 3, 1, 4, 5};
System.out.println(StringUtils.delimit(testStrings, " "));
ArrayUtils.reorder(testStrings, neworder);
System.out.println(StringUtils.delimit(testStrings, " "));
if (true) return;
Object[] objs = new Object[30];
for (int i = 0, size = objs.length; i < size; i++) {
KvPair kvp = new KeyValuePair(new Integer(i), " testing " +
getRandomNumber(false) + " more test");
objs[i] = kvp;
}
Object[] retObjs =
ArrayUtils.getSortedInnerValues(StringUtils.STRING_NUMBER_CASE_INSENSITIVE, objs,
"getValue", KeyValuePair.class);
for (int i = 0, size = retObjs.length; i < size; i++) {
System.out.println("getting getValue value" + retObjs[i]);
}
}
private static String getRandomNumber(boolean whole) {
String number = String.valueOf(Math.random() / 2);
if (!whole) return number;
char[] chars = number.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (!Character.isDigit(chars[i])) number = number.substring(i + 1);
}
return number;
}
static interface KvPair {
public Object getKey();
public Object getValue();
public String toString();
}
static class KeyValuePair implements KvPair {
Object key = null;
Object value = null;
public KeyValuePair(Object obj, Object obj1) {
key = obj;
value = obj1;
}
public Object getKey() {
return key;
}
public Object getValue() {
return value;
}
public String toString() {
return key + " : " + value;
}
}
}
--- NEW FILE: CaseInsensitiveStringAndNumberComparator.java ---
/**
* Created by IntelliJ IDEA.
* User: Benjamin Simpson
* Date: Jan 11, 2003
* Time: 8:44:51 PM
*/
package com.tablelib.core.lang;
import java.io.Serializable;
import java.util.Comparator;
class CaseInsensitiveStringAndNumberComparator implements Comparator, Serializable {
/**
* You might recognise the code as the same java.lang.String.Comparator
* code for CaseInsensitive
* @param o1
* @param o2
* @return int difference of the two strings
*/
public int compare(Object o1, Object o2) {
String s1 = o1.toString();
String s2 = o2.toString();
int n1=s1.length(), n2=s2.length();
for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
char c1 = s1.charAt(i1);
char c2 = s2.charAt(i2);
if (c1 == c2) continue;
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 == c2) continue;
c1 = Character.toLowerCase(c1);
c2 = Character.toLowerCase(c2);
if (c1 == c2) continue;
return areNumbers(c1,c2) ? compareNumbers(s1,i1,s2,i2) :
c1 -c2;
}
return n1 - n2;
}
/**
* Convenience method to check if both characters are "Digits"
* @param c1
* @param c2
* @return boolean are they numbers
*/
private static boolean areNumbers(char c1, char c2) {
return Character.isDigit(c1) && Character.isDigit(c2);
}
/**
* Base of the comparators if the string is "like" up until the end where the
* end is a number.
*
* @param s1 Origianal String being compared
* @param difLoc1 index of the first dissimilar character that is a number in
string1
* @param s2 Origianal String being compared to
* @param difLoc2 index of the first dissimilar character that is a number.
* @return int value of (s1 - s2) where s1 + s2 are numbers || string comparison if
it fails due to a nfe.
*/
private int compareNumbers(final String s1, final int difLoc1,
final String s2, final int difLoc2) {
try {
return Double.valueOf(getInnerNumber(s1.trim(),difLoc1)).compareTo(
Double.valueOf(getInnerNumber(s2.trim(),difLoc2))
);
} catch(NumberFormatException nfe) {
return s1.compareToIgnoreCase(s2);
}
}
/**
* Comparators way of finding the entire number
* This is necessary in the cases of: doubles, different length numbers.
*
* @param str The string containing a mix of words and number(s)
* @param idx
* @return the untrimed substring containing a number of 0-n length.
*/
private final String getInnerNumber(final String str, final int idx) {
final char [] chars = str.toCharArray();
final int len = chars.length;
int startOfNumber = idx;
int endOfNumber = len;
for(int i = idx; i != 0; i--) {
char c = chars[i];
if(Character.isDigit(c) || c == '.') continue;
startOfNumber = i;
break;
}
for(int i = idx; i < len; i++) {
if(Character.isDigit(chars[i])) continue;
endOfNumber = i;
break;
}
return str.substring(startOfNumber,endOfNumber);
}
}
--- NEW FILE: LongUtils.java ---
package com.javaben.core.lang;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author Benjamin Simpson
* @version 1.0
*/
public class LongUtils {
public static final Long [] NO_LONGS = new Long[0];
public static final long [] no_longs = new long[0];
private LongUtils() {}
public static long [] primitiveValues(Object [] objs) {
int size = objs.length;
long [] longs = new long[size];
for(int i = 0; i < size; i++) longs[i] = ( (Long) objs[i] ).longValue();
return longs;
}
public static void main(String[] args) {
}
}
--- NEW FILE: NumberUtils.java ---
/**
* Created by IntelliJ IDEA.
* User: Benjamin Simpson
* Date: Jan 11, 2003
* Time: 8:44:51 PM
*/
package com.tablelib.core.lang;
public final class NumberUtils {
public static final Long [] NO_LONGS = new Long[0];
public static final long [] no_longs = new long[0];
/**
* Test if the object is an int, if so, return it. else return def
* @param value
* @param def
* @return
*/
public static int parseInt(final Object value, final int def) {
try {
return Integer.parseInt(value.toString());
} catch (java.lang.NumberFormatException nfe) {
return def;
}
}
public static long [] primitiveValues(Object [] objs) {
int size = objs.length;
long [] longs = new long[size];
for(int i = 0; i < size; i++) longs[i] = ( (Long) objs[i] ).longValue();
return longs;
}
}
--- NEW FILE: StringUtils.java ---
/**
* Created by IntelliJ IDEA.
* User: Benjamin Simpson
* Date: Jan 11, 2003
* Time: 8:44:51 PM
*/
package com.tablelib.core.lang;
public final class StringUtils {
public static final CaseInsensitiveStringAndNumberComparator
STRING_NUMBER_CASE_INSENSITIVE = new CaseInsensitiveStringAndNumberComparator();
public static String append(final Object[] objs) {
final StringBuffer buffer = new StringBuffer(objs.length * 10);
for (int i = 0, len = objs.length; i < len; i++) {
buffer.append(objs[i].toString());
}
return buffer.toString();
}
/**
* Test for null and no length
* @param val
* @return
*/
public static final boolean hasNoValue(final String val) {
return val == null || val.length() == 0;
}
/**
* Delimit the objects with the delimitor
* @param strs if null a "" will be swapped in
* @param delim
* @return The appended string
*/
public static String delimit(final Object[] strs, final String delim) {
if(hasNoValue(delim)) return append(strs);
final StringBuffer buff = new StringBuffer();
for (int i = 0, size = strs.length; i < size; i++) {
if(i != 0) buff.append(delim);
if(strs[i] != null) buff.append(strs[i].toString());
}
return buff.toString();
}
/**
* Delimit the objects with the delimitor
* @param strs if null a "" will be swapped in
* @param c
* @return The appended string
*/
public static String delimit(final Object[] strs, final char c) {
final StringBuffer buff = new StringBuffer();
for (int size = strs.length, i = 0; i < size; i++) {
if (i != 0) buff.append(c);
if (strs[i] != null) buff.append(strs[i].toString());
}
return buff.toString();
}
/**
* Replace character at given index with the same character to upper case
* This utility was refactored from the StringUtils class in the
* display taglibs project. The replaced code is commented out below to see the
* changes that were made.
*
* @param oldString old string
* @param index of replacement
* @return String new string
**/
public static String toUpperCaseAt(final String oldString,
final int index) {
final int len = oldString == null ? -1 : oldString.length();
if(len <= index) return "";
final char [] chars = oldString.toCharArray();
chars[index] = Character.toUpperCase(chars[index]);
return String.valueOf(chars);
}
/** former method was pretty bad:
*
*
* Throwing a null pointer was not necessary
*
* Too many strings were declared or created to change a char
* newstring(2x), upper(2x), paddedString, beforeIndex, afterIndex
*
public static String toUpperCaseAt( String oldString, int index )
throws NullPointerException, StringIndexOutOfBoundsException
{
int length = oldString.length();
String newString = "";
if( index >= length || index < 0 ) {
throw new StringIndexOutOfBoundsException(
"Index " + index
+ " is out of bounds for string length " + length );
}
//get upper case replacement
String upper = String.valueOf( oldString.charAt( index ) ).toUpperCase();
//avoid index out of bounds
String paddedString = oldString + " ";
//get reusable parts
String beforeIndex = paddedString.substring( 0, index );
String afterIndex = paddedString.substring( index + 1 );
//generate new String - remove padding spaces
newString = ( beforeIndex + upper + afterIndex ).substring( 0, length );
return newString;
}
*/
}
-------------------------------------------------------
This SF.net email is sponsored by: VM Ware
With VMware you can run multiple operating systems on a single machine.
WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines at the
same time. Free trial click here: http://www.vmware.com/wl/offer/345/0
_______________________________________________
displaytag-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/displaytag-devel