org.eclipse.persistence.internal.helper.Helper Maven / Gradle / Ivy
Show all versions of eclipselink Show documentation
/*
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
// dminsky - added countOccurrencesOf(Object, List) API
// 08/23/2010-2.2 Michael O'Brien
// - 323043: application.xml module ordering may cause weaving not to occur causing an NPE.
// warn if expected "_persistence_//_vh" method not found
// instead of throwing NPE during deploy validation.
// 08/29/2016 Jody Grassel
// - 500441: Eclipselink core has System.getProperty() calls that are not potentially executed under doPriv()
package org.eclipse.persistence.internal.helper;
import org.eclipse.persistence.config.SystemProperties;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.Timestamp;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.Vector;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* INTERNAL:
*
* Purpose: Define any useful methods that are missing from the base Java.
*/
public class Helper implements Serializable {
/** Used to configure JDBC level date optimization. */
public static boolean shouldOptimizeDates = false;
/** Used to store null values in hashtables, is helper because need to be serializable. */
public static final Object NULL_VALUE = new Helper();
/** Used to convert {@code null} value to {@link String}. */
private static final String NULL_STRING = "null";
/** PERF: Used to cache a set of calendars for conversion/printing purposes. */
protected static final Queue calendarCache = initCalendarCache();
/** PERF: Cache default timezone for calendar conversion. */
protected static final TimeZone defaultTimeZone = TimeZone.getDefault();
private static java.time.format.DateTimeFormatter dateTimeFormatter;
// Changed static initialization to lazy initialization for bug 2756643
/** formatting strings for indenting */
public static final String SPACE = " ";
public static final String INDENT = " ";
/** Store newline string */
public static final String NL = "\n";
/** Prime the platform-dependent current working directory */
protected static String CURRENT_WORKING_DIRECTORY = null;
/** Prime the platform-dependent temporary directory */
protected static String TEMP_DIRECTORY = null;
/** Backdoor to allow 0 to be used in primary keys.
* @deprecated
* Instead of setting the flag to true use:
* session.getProject().setDefaultIdValidation(IdValidation.NULL)
**/
@Deprecated
public static boolean isZeroValidPrimaryKey = false;
// settings to allow ascertaining attribute names from method names
public static final String IS_PROPERTY_METHOD_PREFIX = "is";
public static final String GET_PROPERTY_METHOD_PREFIX = "get";
public static final String SET_PROPERTY_METHOD_PREFIX = "set";
public static final String SET_IS_PROPERTY_METHOD_PREFIX = "setIs";
public static final int POSITION_AFTER_IS_PREFIX = IS_PROPERTY_METHOD_PREFIX.length();
public static final int POSITION_AFTER_GET_PREFIX = GET_PROPERTY_METHOD_PREFIX.length();
public static final String DEFAULT_DATABASE_DELIMITER = "\"";
public static final String PERSISTENCE_SET = "_persistence_set_";
public static final String PERSISTENCE_GET = "_persistence_get_";
// 323403: These constants are used to search for missing weaved functions - this is a copy is of the jpa project under ClassWeaver
public static final String PERSISTENCE_FIELDNAME_PREFIX = "_persistence_";
public static final String PERSISTENCE_FIELDNAME_POSTFIX = "_vh";
private static String defaultStartDatabaseDelimiter = null;
private static String defaultEndDatabaseDelimiter = null;
/**
* Return if JDBC date access should be optimized.
*/
public static boolean shouldOptimizeDates() {
return shouldOptimizeDates;
}
/**
* Return if JDBC date access should be optimized.
*/
public static void setShouldOptimizeDates(boolean value) {
shouldOptimizeDates = value;
}
/**
* PERF:
* Return the calendar cache use to avoid calendar creation for processing java.sql/util.Date/Time/Timestamp objects.
*/
public static Queue getCalendarCache() {
return calendarCache;
}
/**
* PERF:
* Init the calendar cache use to avoid calendar creation for processing java.sql/util.Date/Time/Timestamp objects.
*/
public static Queue initCalendarCache() {
Queue calendarCache = new ConcurrentLinkedQueue<>();
for (int index = 0; index < 10; index++) {
calendarCache.add(Calendar.getInstance());
}
return calendarCache;
}
/**
* PERF: This is used to optimize Calendar conversion/printing.
* This should only be used when a calendar is temporarily required,
* when finished it must be released back.
*/
public static Calendar allocateCalendar() {
Calendar calendar = getCalendarCache().poll();
if (calendar == null) {
calendar = Calendar.getInstance();
}
return calendar;
}
/**
* PERF: Return the cached default platform.
* Used for ensuring Calendar are in the local timezone.
* The JDK method clones the timezone, so cache it locally.
*/
public static TimeZone getDefaultTimeZone() {
return defaultTimeZone;
}
public static java.time.format.DateTimeFormatter getDefaultDateTimeFormatter() {
if (dateTimeFormatter == null) {
dateTimeFormatter = new java.time.format.DateTimeFormatterBuilder()
.append(new java.time.format.DateTimeFormatterBuilder()
.parseCaseInsensitive()
.parseLenient()
.optionalStart()
.append(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)
.optionalEnd()
.optionalStart()
.appendLiteral('T')
.optionalEnd()
.optionalStart()
.append(java.time.format.DateTimeFormatter.ISO_LOCAL_TIME)
.optionalEnd()
.toFormatter())
.optionalStart()
.appendOffsetId()
.optionalStart()
.appendLiteral('[')
.parseCaseSensitive()
.appendZoneRegionId()
.appendLiteral(']')
.toFormatter();
}
return dateTimeFormatter;
}
/**
* PERF: This is used to optimize Calendar conversion/printing.
* This should only be used when a calendar is temporarily required,
* when finished it must be released back.
*/
public static void releaseCalendar(Calendar calendar) {
getCalendarCache().offer(calendar);
}
public static void addAllToVector(Vector theVector, Vector extends E> elementsToAdd) {
for (Iterator extends E> iterator = elementsToAdd.iterator(); iterator.hasNext();) {
theVector.add(iterator.next());
}
}
public static Vector addAllUniqueToVector(Vector objects, List objectsToAdd) {
if (objectsToAdd == null) {
return objects;
}
int size = objectsToAdd.size();
for (int index = 0; index < size; index++) {
T element = objectsToAdd.get(index);
if (!objects.contains(element)) {
objects.add(element);
}
}
return objects;
}
public static List addAllUniqueToList(List objects, List objectsToAdd) {
if (objectsToAdd == null) {
return objects;
}
int size = objectsToAdd.size();
for (int index = 0; index < size; index++) {
T element = objectsToAdd.get(index);
if (!objects.contains(element)) {
objects.add(element);
}
}
return objects;
}
/**
* Convert the specified vector into an array.
*/
public static Object[] arrayFromVector(Vector> vector) {
Object[] result = new Object[vector.size()];
for (int i = 0; i < vector.size(); i++) {
result[i] = vector.get(i);
}
return result;
}
/**
* Convert {@link Integer} to hexadecimal {@link String}.
* @param i An {@link Integer} to be converted to a hexadecimal string.
* @return The {@link String} representation of the unsigned integer value represented by the argument
* in hexadecimal or {@code "null"} if provided {@link Integer} argument is {@code null}.
*/
public static String integerToHexString(final Integer i) {
return i != null ? Integer.toHexString(i) : NULL_STRING;
}
/**
* Convert the HEX string to a byte array.
* HEX allows for binary data to be printed.
*/
public static byte[] buildBytesFromHexString(String hex) {
String tmpString = hex;
if ((tmpString.length() % 2) != 0) {
throw ConversionException.couldNotConvertToByteArray(hex);
}
byte[] bytes = new byte[tmpString.length() / 2];
int byteIndex;
int strIndex;
byte digit1;
byte digit2;
for (byteIndex = bytes.length - 1, strIndex = tmpString.length() - 2; byteIndex >= 0;
byteIndex--, strIndex -= 2) {
digit1 = (byte)Character.digit(tmpString.charAt(strIndex), 16);
digit2 = (byte)Character.digit(tmpString.charAt(strIndex + 1), 16);
if ((digit1 == -1) || (digit2 == -1)) {
throw ConversionException.couldNotBeConverted(hex, ClassConstants.APBYTE);
}
bytes[byteIndex] = (byte)((digit1 * 16) + digit2);
}
return bytes;
}
/**
* Convert the byte array to a HEX string.
* HEX allows for binary data to be printed.
*/
public static String buildHexStringFromBytes(byte[] bytes) {
char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
StringBuilder stringBuilder = new StringBuilder();
int tempByte;
for (int byteIndex = 0; byteIndex < (bytes).length; byteIndex++) {
tempByte = (bytes)[byteIndex];
if (tempByte < 0) {
tempByte = tempByte + 256;//compensate for the fact that byte is signed in Java
}
tempByte = (byte)(tempByte / 16);//get the first digit
if (tempByte > 16) {
throw ConversionException.couldNotBeConverted(bytes, ClassConstants.STRING);
}
stringBuilder.append(hexArray[tempByte]);
tempByte = (bytes)[byteIndex];
if (tempByte < 0) {
tempByte = tempByte + 256;
}
tempByte = (byte)(tempByte % 16);//get the second digit
if (tempByte > 16) {
throw ConversionException.couldNotBeConverted(bytes, ClassConstants.STRING);
}
stringBuilder.append(hexArray[tempByte]);
}
return stringBuilder.toString();
}
/**
* Create a new Vector containing all of the map elements.
*/
public static Vector buildVectorFromMapElements(Map, T> map) {
Vector vector = new Vector<>(map.size());
Iterator iterator = map.values().iterator();
while (iterator.hasNext()) {
vector.add(iterator.next());
}
return vector;
}
/**
* Answer a Calendar from a date.
*/
public static Calendar calendarFromUtilDate(java.util.Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
//In jdk1.3, millisecond is missing
if (date instanceof Timestamp) {
calendar.set(Calendar.MILLISECOND, ((Timestamp)date).getNanos() / 1000000);
}
return calendar;
}
/**
* INTERNAL:
* Return whether a Class implements a specific interface, either directly or indirectly
* (through interface or implementation inheritance).
* @return boolean
*/
public static boolean classImplementsInterface(Class aClass, Class> anInterface) {
// quick check
if (aClass == anInterface) {
return true;
}
Class>[] interfaces = aClass.getInterfaces();
// loop through the "directly declared" interfaces
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i] == anInterface) {
return true;
}
}
// recurse through the interfaces
for (int i = 0; i < interfaces.length; i++) {
if (classImplementsInterface(interfaces[i], anInterface)) {
return true;
}
}
// finally, recurse up through the superclasses to Object
Class super T> superClass = aClass.getSuperclass();
if (superClass == null) {
return false;
}
return classImplementsInterface(superClass, anInterface);
}
/**
* INTERNAL:
* Return whether a Class is a subclass of, or the same as, another Class.
* @return boolean
*/
public static boolean classIsSubclass(Class> subClass, Class> superClass) {
Class> temp = subClass;
if (superClass == null) {
return false;
}
while (temp != null) {
if (temp == superClass) {
return true;
}
temp = temp.getSuperclass();
}
return false;
}
/**
* INTERNAL:
* Compares two version in num.num.num.num.num*** format.
* -1, 0, 1 means the version1 is less than, equal, greater than version2.
* Example: compareVersions("11.1.0.6.0-Production", "11.1.0.7") == -1
* Example: compareVersions("WebLogic Server 10.3.4", "10.3.3.0") == 1
*/
public static int compareVersions(String version1, String version2) {
return compareVersions(version(version1), version(version2));
}
/**
* INTERNAL:
* Expects version in ***num.num.num.num.num*** format, converts it to a List of Integers.
* Example: "11.1.0.6.0_Production" -> {11, 1, 0, 6, 0}
* Example: "WebLogic Server 10.3.3.0" -> {10, 3, 3, 0}
*/
static protected List version(String version) {
ArrayList list = new ArrayList<>(5);
// first char - a digit - in the string corresponding to the current list index
int iBegin = -1;
// used to remove a non-digital prefix
boolean isPrefix = true;
for(int i=0; i= 0) {
String strNum = version.substring(iBegin, version.length());
int num = Integer.parseInt(strNum, 10);
list.add(num);
}
return list;
}
/**
* INTERNAL:
* Compares two lists of Integers
* -1, 0, 1 means the first list is less than, equal, greater than the second list.
* Example: {11, 1, 0, 6, 0} < {11, 1, 0, 7}
*/
static protected int compareVersions(List list1, Listlist2) {
int n = Math.max(list1.size(), list2.size());
int res = 0;
for(int i=0; i l2) {
res = 1;
break;
}
}
return res;
}
public static Class getClassFromClasseName(final String className, final ClassLoader classLoader) {
if (className == null) {
return null;
}
return PrivilegedAccessHelper.callDoPrivilegedWithException(
() -> PrivilegedAccessHelper.getClassForName(className, true, classLoader),
(ex) -> ValidationException.classNotFoundWhileConvertingClassNames(className, ex)
);
}
public static String getComponentTypeNameFromArrayString(String aString) {
if (aString == null || aString.isEmpty()) {
return null;
}
// complex array component type case
if (aString.length() > 3 && (aString.startsWith("[L") && aString.endsWith(";"))) {
return aString.substring(2, aString.length() - 1);
} else if (aString.startsWith("[")){
Class> primitiveClass = null;
try {
primitiveClass = Class.forName(aString);
} catch (ClassNotFoundException cnf) {
// invalid name specified - do not rethrow exception
// primitiveClass is still null;
}
if (primitiveClass != null) {
return primitiveClass.getComponentType().getName();
}
}
return null;
}
public static boolean compareArrays(Object[] array1, Object[] array2) {
if (array1.length != array2.length) {
return false;
}
for (int index = 0; index < array1.length; index++) {
//Related to Bug#3128838 fix. ! is added to correct the logic.
if(array1[index] != null) {
if (!array1[index].equals(array2[index])) {
return false;
}
} else {
if(array2[index] != null) {
return false;
}
}
}
return true;
}
/**
* Compare two BigDecimals.
* This is required because the .equals method of java.math.BigDecimal ensures that
* the scale of the two numbers are equal. Therefore 0.0 != 0.00.
* @see java.math.BigDecimal#equals(Object)
*/
public static boolean compareBigDecimals(java.math.BigDecimal one, java.math.BigDecimal two) {
if (one.scale() != two.scale()) {
double doubleOne = (one).doubleValue();
double doubleTwo = (two).doubleValue();
if ((doubleOne != Double.POSITIVE_INFINITY) && (doubleOne != Double.NEGATIVE_INFINITY) && (doubleTwo != Double.POSITIVE_INFINITY) && (doubleTwo != Double.NEGATIVE_INFINITY)) {
return doubleOne == doubleTwo;
}
}
return one.equals(two);
}
public static boolean compareByteArrays(byte[] array1, byte[] array2) {
if (array1.length != array2.length) {
return false;
}
for (int index = 0; index < array1.length; index++) {
if (array1[index] != array2[index]) {
return false;
}
}
return true;
}
public static boolean compareCharArrays(char[] array1, char[] array2) {
if (array1.length != array2.length) {
return false;
}
for (int index = 0; index < array1.length; index++) {
if (array1[index] != array2[index]) {
return false;
}
}
return true;
}
/**
* PUBLIC:
*
* Compare two vectors of types. Return true if the size of the vectors is the
* same and each of the types in the first Vector are assignable from the types
* in the corresponding objects in the second Vector.
*/
public static boolean areTypesAssignable(List> types1, List> types2) {
if ((types1 == null) || (types2 == null)) {
return false;
}
if (types1.size() == types2.size()) {
for (int i = 0; i < types1.size(); i++) {
Class> type1 = types1.get(i);
Class> type2 = types2.get(i);
// if either are null then we assume assignability.
if ((type1 != null) && (type2 != null)) {
if (!type1.isAssignableFrom(type2)) {
return false;
}
}
}
return true;
}
return false;
}
/**
* PUBLIC:
* Compare the elements in 2 hashtables to see if they are equal
*
* Added Nov 9, 2000 JED Patch 2.5.1.8
*/
public static boolean compareHashtables(Hashtable, ?> hashtable1, Hashtable, ?> hashtable2) {
Object element;
if (hashtable1.size() != hashtable2.size()) {
return false;
}
Hashtable, ?> clonedHashtable = (Hashtable, ?>)hashtable2.clone();
Iterator> iterator = hashtable1.values().iterator();
while (iterator.hasNext()) {
element = iterator.next();
if (clonedHashtable.remove(element) == null) {
return false;
}
}
return clonedHashtable.isEmpty();
}
/**
* Compare two potential arrays and return true if they are the same. Will
* check for BigDecimals as well.
*/
public static boolean comparePotentialArrays(Object firstValue, Object secondValue) {
Class> firstClass = firstValue.getClass();
Class> secondClass = secondValue.getClass();
// Arrays must be checked for equality because default does identity
if ((firstClass == ClassConstants.APBYTE) && (secondClass == ClassConstants.APBYTE)) {
return compareByteArrays((byte[])firstValue, (byte[])secondValue);
} else if ((firstClass == ClassConstants.APCHAR) && (secondClass == ClassConstants.APCHAR)) {
return compareCharArrays((char[])firstValue, (char[])secondValue);
} else if ((firstClass.isArray()) && (secondClass.isArray())) {
return compareArrays((Object[])firstValue, (Object[])secondValue);
} else if (firstValue instanceof java.math.BigDecimal && secondValue instanceof java.math.BigDecimal) {
// BigDecimals equals does not consider the precision correctly
return compareBigDecimals((java.math.BigDecimal)firstValue, (java.math.BigDecimal)secondValue);
}
return false;
}
/**
* Merge the two Maps into a new HashMap.
*/
public static Map concatenateMaps(Map extends K, ? extends V> first, Map extends K, ? extends V> second) {
Map concatenation = new HashMap<>(first.size() + second.size() + 4);
concatenation.putAll(first);
concatenation.putAll(second);
return concatenation;
}
/**
* Return a new vector with no duplicated values.
*/
public static Vector concatenateUniqueVectors(Vector extends E> first, Vector extends E> second) {
Vector concatenation;
E element;
concatenation = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
for (Iterator extends E> iterator = first.iterator(); iterator.hasNext();) {
concatenation.add(iterator.next());
}
for (Iterator extends E> iterator = second.iterator(); iterator.hasNext();) {
element = iterator.next();
if (!concatenation.contains(element)) {
concatenation.add(element);
}
}
return concatenation;
}
/**
* Return a new List with no duplicated values.
*/
public static List concatenateUniqueLists(List extends E> first, List extends E> second) {
List concatenation = new ArrayList<>(first.size() + second.size());
concatenation.addAll(first);
for (E element : second) {
if (!concatenation.contains(element)) {
concatenation.add(element);
}
}
return concatenation;
}
public static Vector concatenateVectors(Vector extends E> first, Vector extends E> second) {
Vector concatenation;
concatenation = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
for (Iterator extends E> iterator = first.iterator(); iterator.hasNext();) {
concatenation.add(iterator.next());
}
for (Iterator extends E> iterator = second.iterator(); iterator.hasNext();) {
concatenation.add(iterator.next());
}
return concatenation;
}
public static List concatenateLists(List extends E> first, List extends E> second) {
List concatenation = new ArrayList<>(first);
concatenation.addAll(second);
return concatenation;
}
/** Return a copy of the vector containing a subset starting at startIndex
* and ending at stopIndex.
* @param originalVector - original vector
* @param startIndex - starting position in vector
* @param stopIndex - ending position in vector
*/
public static Vector copyVector(List originalVector, int startIndex, int stopIndex) throws ValidationException {
Vector newVector;
if (stopIndex < startIndex) {
return NonSynchronizedVector.newInstance();
}
newVector = NonSynchronizedVector.newInstance(stopIndex - startIndex);
for (int index = startIndex; index < stopIndex; index++) {
newVector.add(originalVector.get(index));
}
return newVector;
}
/**
* Return the name of the "current working directory".
*/
public static String currentWorkingDirectory() {
// bug 2756643
if (CURRENT_WORKING_DIRECTORY == null) {
CURRENT_WORKING_DIRECTORY = PrivilegedAccessHelper.getSystemProperty("user.dir");
}
return CURRENT_WORKING_DIRECTORY;
}
/**
* Return the name of the "temporary directory".
*/
public static String tempDirectory() {
// Bug 2756643
if (TEMP_DIRECTORY == null) {
TEMP_DIRECTORY = PrivilegedAccessHelper.getSystemProperty("java.io.tmpdir");
}
return TEMP_DIRECTORY;
}
/**
* Answer a Date from a long
*
* This implementation is based on the java.sql.Date class, not java.util.Date.
* @param longObject - milliseconds from the epoch (00:00:00 GMT
* Jan 1, 1970). Negative values represent dates prior to the epoch.
*/
public static java.sql.Date dateFromLong(Long longObject) {
return new java.sql.Date(longObject);
}
/**
* Answer a Date with the year, month, date.
* This builds a date avoiding the deprecated, inefficient and concurrency bottleneck date constructors.
* This implementation is based on the java.sql.Date class, not java.util.Date.
* The year, month, day are the values calendar uses,
* i.e. year is from 0, month is 0-11, date is 1-31.
*/
public static java.sql.Date dateFromYearMonthDate(int year, int month, int day) {
java.sql.Date date = null;
try {
date = java.sql.Date.valueOf(LocalDate.of(year, month + 1, day));
} catch (DateTimeException exception) {
throw ConversionException.incorrectDateValue(year + "-" + (month + 1) + "-" + day);
}
return date;
}
/**
* Answer a Date from a string representation.
* The string MUST be a valid date and in one of the following
* formats: YYYY/MM/DD, YYYY-MM-DD, YY/MM/DD, YY-MM-DD.
*
* This implementation is based on the java.sql.Date class, not java.util.Date.
*
* The Date class contains some minor gotchas that you have to watch out for.
* @param dateString - string representation of date
* @return - date representation of string
*/
public static java.sql.Date dateFromString(String dateString) throws ConversionException {
int year;
int month;
int day;
StringTokenizer dateStringTokenizer;
if (dateString.indexOf('/') != -1) {
dateStringTokenizer = new StringTokenizer(dateString, "/");
} else if (dateString.indexOf('-') != -1) {
dateStringTokenizer = new StringTokenizer(dateString, "- ");
} else {
throw ConversionException.incorrectDateFormat(dateString);
}
try {
year = Integer.parseInt(dateStringTokenizer.nextToken());
month = Integer.parseInt(dateStringTokenizer.nextToken());
day = Integer.parseInt(dateStringTokenizer.nextToken());
} catch (NumberFormatException exception) {
throw ConversionException.incorrectDateFormat(dateString);
}
// Java returns the month in terms of 0 - 11 instead of 1 - 12.
month = month - 1;
return dateFromYearMonthDate(year, month, day);
}
/**
* Answer a Date from a timestamp
*
* This implementation is based on the java.sql.Date class, not java.util.Date.
* @param timestamp - timestamp representation of date
* @return - date representation of timestampObject
*/
public static java.sql.Date dateFromTimestamp(java.sql.Timestamp timestamp) {
return sqlDateFromUtilDate(timestamp);
}
/**
* Returns true if the file of this name does indeed exist
*/
public static boolean doesFileExist(String fileName) {
FileReader reader = null;
try {
reader = new FileReader(fileName);
} catch (FileNotFoundException fnfException) {
return false;
} finally {
Helper.close(reader);
}
return true;
}
/**
* Double up \ to allow printing of directories for source code generation.
*/
public static String doubleSlashes(String path) {
StringBuilder buffer = new StringBuilder(path.length() + 5);
for (int index = 0; index < path.length(); index++) {
char charater = path.charAt(index);
buffer.append(charater);
if (charater == '\\') {
buffer.append('\\');
}
}
return buffer.toString();
}
/**
* Extracts the actual path to the jar file.
*/
public static String extractJarNameFromURL(java.net.URL url) {
String tempName = url.getFile();
int start = tempName.indexOf("file:") + 5;
int end = tempName.indexOf("!/");
return tempName.substring(start, end);
}
/**
* INTERNAL:
* Returns a Field for the specified Class and field name.
* Uses Class.getDeclaredField(String) to find the field.
* If the field is not found on the specified class
* the superclass is checked, and so on, recursively.
* Set accessible to true, so we can access private/package/protected fields.
*/
public static Field getField(final Class> javaClass, final String fieldName) throws NoSuchFieldException {
try {
return PrivilegedAccessHelper.callDoPrivilegedWithException(
() -> PrivilegedAccessHelper.getField(javaClass, fieldName, true)
);
} catch (NoSuchFieldException | RuntimeException ex) {
throw ex;
// This indicates unexpected problem in the code
} catch (Exception ex) {
throw new RuntimeException(String.format("Getting %s field failed", fieldName), ex);
}
}
/**
* INTERNAL:
* Returns a Method for the specified Class, method name, and that has no
* parameters. Uses Class.getDeclaredMethod(String Class[]) to find the
* method. If the method is not found on the specified class the superclass
* is checked, and so on, recursively. Set accessible to true, so we can
* access private/package/protected methods.
*/
public static Method getDeclaredMethod(Class> javaClass, String methodName) throws NoSuchMethodException {
return getDeclaredMethod(javaClass, methodName, null);
}
/**
* INTERNAL:
* Returns a Method for the specified Class, method name, and formal
* parameter types. Uses Class.getDeclaredMethod(String Class[]) to find
* the method. If the method is not found on the specified class the
* superclass is checked, and so on, recursively. Set accessible to true,
* so we can access private/package/protected methods.
*/
public static Method getDeclaredMethod(final Class> javaClass, final String methodName, final Class>[] methodParameterTypes) throws NoSuchMethodException {
try {
return PrivilegedAccessHelper.callDoPrivilegedWithException(
() -> PrivilegedAccessHelper.getMethod(javaClass, methodName, methodParameterTypes, true)
);
} catch (NoSuchMethodException | RuntimeException ex) {
throw ex;
// This indicates unexpected problem in the code
} catch (Exception ex) {
throw new RuntimeException(String.format("Getting %s method failed", methodName), ex);
}
}
/**
* Return the class instance from the class
*/
public static Object getInstanceFromClass(final Class> classFullName) {
if (classFullName == null) {
return null;
}
return PrivilegedAccessHelper.callDoPrivilegedWithException(
() -> PrivilegedAccessHelper.newInstanceFromClass(classFullName),
(ex) -> {
final ValidationException exc = new ValidationException();
exc.setInternalException(ex);
return exc;
}
);
}
/**
* Returns the object class. If a class is primitive return its non primitive class
*/
public static Class> getObjectClass(Class> javaClass) {
return ConversionManager.getObjectClass(javaClass);
}
/**
* Answers the unqualified class name from the specified String.
*/
public static String getShortClassName(String javaClassName) {
return javaClassName.substring(javaClassName.lastIndexOf('.') + 1);
}
/**
* Return a string containing the specified number of tabs.
*/
public static String getTabs(int noOfTabs) {
StringWriter writer = new StringWriter();
for (int index = 0; index < noOfTabs; index++) {
writer.write("\t");
}
return writer.toString();
}
/**
* Returns the index of the the first null
element found in the specified
* Vector
starting the search at the starting index specified.
* Return an int >= 0 and less than size if a null
element was found.
* Return -1 if a null
element was not found.
* This is needed in jdk1.1, where Vector.contains(Object)
* for a null
element will result in a NullPointerException
....
*/
public static int indexOfNullElement(Vector> v, int index) {
int size = v.size();
for (int i = index; i < size; i++) {
if (v.get(i) == null) {
return i;
}
}
return -1;
}
/**
* ADVANCED
* returns true if the class in question is a primitive wrapper
*/
public static boolean isPrimitiveWrapper(Class> classInQuestion) {
return classInQuestion.equals(Character.class) || classInQuestion.equals(Boolean.class) || classInQuestion.equals(Byte.class) || classInQuestion.equals(Short.class) || classInQuestion.equals(Integer.class) || classInQuestion.equals(Long.class) || classInQuestion.equals(Float.class) || classInQuestion.equals(Double.class);
}
/**
* Returns true if the string given is an all upper case string
*/
public static boolean isUpperCaseString(String s) {
char[] c = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
if (Character.isLowerCase(c[i])) {
return false;
}
}
return true;
}
/**
* Returns true if the character given is a vowel. I.e. one of a,e,i,o,u,A,E,I,O,U.
*/
public static boolean isVowel(char c) {
return (c == 'A') || (c == 'a') || (c == 'e') || (c == 'E') || (c == 'i') || (c == 'I') || (c == 'o') || (c == 'O') || (c == 'u') || (c == 'U');
}
/**
* Return an array of the files in the specified directory.
* This allows us to simplify jdk1.1 code a bit.
*/
public static File[] listFilesIn(File directory) {
if (directory.isDirectory()) {
return directory.listFiles();
} else {
return new File[0];
}
}
/**
* Make a Vector from the passed object.
* If it's a Collection, iterate over the collection and add each item to the Vector.
* If it's not a collection create a Vector and add the object to it.
*/
@SuppressWarnings({"unchecked"})
public static Vector makeVectorFromObject(Object theObject) {
if (theObject instanceof Vector) {
return ((Vector)theObject);
}
if (theObject instanceof Collection) {
Collection extends T> col = ((Collection extends T>)theObject);
Vector returnVector = new Vector<>(col.size());
returnVector.addAll(col);
return returnVector;
}
Vector