Skip to content

Commit 189d813

Browse files
remove pre-jdk1.5 workarounds (#176)
Signed-off-by: Nicola Isotta <[email protected]> Signed-off-by: Jesse Gorzinski <[email protected]> Co-authored-by: Jesse Gorzinski <[email protected]>
1 parent 6000ddc commit 189d813

7 files changed

+81
-273
lines changed

src/main/java/com/ibm/as400/access/AS400DecFloat.java

+9-149
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313

1414
package com.ibm.as400.access;
1515

16-
import java.lang.reflect.Constructor;
17-
import java.lang.reflect.InvocationTargetException;
1816
import java.math.BigDecimal;
1917
import java.math.BigInteger;
18+
import java.math.MathContext;
19+
import java.math.RoundingMode;
20+
2021
//@DFA new class
2122
/**
2223
* The AS400DecFloat class provides a converter between a BigDecimal object and a DecimalFloat type.
@@ -615,7 +616,7 @@ else if ((combination == 0x1eL) && ( sign == -1))
615616

616617

617618
BigInteger bigInt = new java.math.BigInteger (sign, magnitude);
618-
return getNewBigDecimal(bigInt, -exponent);
619+
return new BigDecimal(bigInt, -exponent);
619620

620621
}else
621622
{
@@ -705,7 +706,7 @@ else if ((combination == 0x1eL) && ( sign == -1))
705706

706707

707708
java.math.BigInteger bigInt = new java.math.BigInteger (sign, magnitude);
708-
return getNewBigDecimal(bigInt, -exponent);
709+
return new BigDecimal(bigInt, -exponent);
709710
}
710711
}
711712

@@ -853,103 +854,6 @@ private static final int decFloatBitsToDigits (int bits)
853854
return decimal;
854855
}
855856

856-
/**
857-
* This method rounds the number (unscaled integer value and exponent).
858-
* mcPrecision and mcRoundingMode are what is in jdk 5.0 MathContext.
859-
* What is returned from this method should be the same as what jre 5.0 would
860-
* have rounded to using MathContext and BigDecimal.
861-
*/
862-
private static BigDecimal roundByModePreJDK5(BigInteger intVal, int scale, int mcPrecision, String mcRoundingMode)
863-
{
864-
865-
BigInteger roundingMax = null;
866-
if (mcPrecision == 16)
867-
roundingMax = new BigInteger("10000000000000000"); // 16 0s
868-
else
869-
roundingMax = new BigInteger("10000000000000000000000000000000000"); // 34 0s
870-
871-
BigInteger roundingMin = roundingMax.negate();
872-
873-
if (roundingMax != null && intVal.compareTo(roundingMax) < 0
874-
&& intVal.compareTo(roundingMin) > 0)
875-
return getNewBigDecimal(intVal, scale); //rounding not needed
876-
//get precision from intVal without 0's on right side
877-
int[] values = SQLDataFactory.getPrecisionForTruncation(getNewBigDecimal(intVal, scale), mcPrecision); //=precisionStr.length() - trimCount; //@rnd1
878-
int precisionNormalized = values[0]; //@rnd1
879-
int droppedZeros = values[1]; //@rnd1 decrease scale by number of zeros removed from precision //@rnd1
880-
if(droppedZeros != 0) //@rnd1
881-
{ //@rnd1
882-
//adjust intVal number of zeros removed off end //@rnd1
883-
intVal = intVal.divide( new BigInteger("10").pow(droppedZeros)); //@rnd1
884-
} //@rnd1
885-
886-
//get number of digits to round off
887-
int drop = precisionNormalized - mcPrecision;
888-
//@rnd1 if (drop <= 0)
889-
//@rnd1 return getNewBigDecimal(intVal, scale);
890-
BigDecimal rounded = roundOffDigits(intVal, scale, mcRoundingMode, drop);
891-
892-
if(droppedZeros != 0) //@rnd1
893-
{ //@rnd1
894-
//adjust rounded bigdecimal by dropped zero count //@rnd1
895-
rounded = rounded.movePointRight(droppedZeros); //@rnd1
896-
} //@rnd1
897-
898-
return rounded; //@rnd1
899-
}
900-
901-
/**
902-
* Helper method to round off digits
903-
*/
904-
private static BigDecimal roundOffDigits(BigInteger intVal, int scale,
905-
String mcRoundingMode, int dropCount)
906-
{
907-
908-
BigDecimal divisor = new BigDecimal((new BigInteger("10")).pow(dropCount), 0);
909-
BigDecimal preRoundedBD = getNewBigDecimal(intVal, scale);
910-
int roundingMode = 0;
911-
try
912-
{
913-
//get int value for RoundingMode from BigDecimal
914-
roundingMode = ((Integer) Class.forName("java.math.BigDecimal").getDeclaredField(mcRoundingMode).get(null)).intValue();
915-
} catch (Exception e)
916-
{
917-
throw new InternalErrorException(InternalErrorException.UNKNOWN, e); //should never happen
918-
}
919-
BigDecimal rounded = preRoundedBD.divide(divisor, scale, roundingMode); // do actual rounding here
920-
921-
BigInteger bigIntPart = rounded.unscaledValue();
922-
923-
rounded = getNewBigDecimal(bigIntPart, scale - dropCount);
924-
925-
return rounded;
926-
}
927-
928-
/**
929-
Creates and returns a new BigDecimal based on parameters.
930-
This is a temporary hack due to pre-jre 1.5 not being able to handle negative scales (positive exp)
931-
After we no longer support pre-java 1.5, this method can be replaced with new BigDecimal(bigInt, scale).
932-
@param bigInt BigInteger part.
933-
@param scale scale part.
934-
**/
935-
private static BigDecimal getNewBigDecimal(BigInteger bigInt, int scale)
936-
{
937-
BigDecimal bigDecimal = null;
938-
try{
939-
bigDecimal = new BigDecimal(bigInt, scale);
940-
}catch(NumberFormatException e)
941-
{
942-
//note that creating BigDecimal with negative scale is ok in 5, but not in 1.4
943-
//deal with negative scale in pre jdk 5.0 here
944-
if (scale > 0)
945-
throw e;
946-
bigDecimal = new BigDecimal(bigInt);
947-
bigDecimal = bigDecimal.movePointRight(-scale);
948-
}
949-
950-
return bigDecimal;
951-
}
952-
953857
//Decimal float. //@DFA
954858
/**
955859
Rounds the precision of a BigDecimal by removing least significant digits from
@@ -959,54 +863,10 @@ private static BigDecimal getNewBigDecimal(BigInteger bigInt, int scale)
959863
@param roundingMode to use when truncating
960864
* @return the rounded BigDecimal
961865
**/
962-
public static BigDecimal roundByMode(BigDecimal bd, int precision, String roundingMode)
963-
{
964-
BigDecimal roundedBD = null;
965-
966-
//MathContext is in jdk1.5. So use reflection so code will build under pre-1.5
967-
//later, use this when we move to jdk1.5
968-
//All we are doing below is: bdAbs = inValue.abs(new MathContext(16, roundingMode));
969-
boolean isGEJVM50 = true;
970-
try
971-
{
972-
//in this try block, we do rounding via BigDecimal and MathContext
973-
Class cls = Class.forName("java.math.MathContext"); //thorw ClassNotFoundException if pre 1.5 jvm
974-
Constructor ct = cls.getConstructor(new Class[] { Integer.TYPE, Class.forName("java.math.RoundingMode") });
975-
Object arglist[] = new Object[2];
976-
arglist[0] = Integer.valueOf(precision); //MathContext.DECIMAL64 (16 or 34 char decfloat precision)
977-
arglist[1] = Class.forName("java.math.RoundingMode").getDeclaredField(roundingMode.substring(6)).get(null); //@pdc remove "ROUND_"
978-
979-
Object mathContextRounded = ct.newInstance(arglist); //ie. new MathContext(16or34, RoundingMode.x);
980-
Object[] arglist2 = new Object[]{mathContextRounded};
981-
Class[] c = new Class[] { Class.forName("java.math.MathContext") };
982-
java.lang.reflect.Method method = java.math.BigDecimal.class.getDeclaredMethod("round", c);
983-
984-
roundedBD = (java.math.BigDecimal) method.invoke(bd, arglist2);
985-
}
986-
//Unfortunately, we cannot just catch Exception since we do not want to miss any real exceptions
987-
//from rounding etc. And can't re-throw Exception it since method is not declared with "throws"
988-
catch (ClassNotFoundException e)
989-
{
990-
//got exception due to pre-java 5.0.
991-
isGEJVM50 = false;
992-
}
993-
catch (NoSuchMethodException e)
994-
{ isGEJVM50 = false; }
995-
catch (NoSuchFieldException e)
996-
{ isGEJVM50 = false; }
997-
catch (IllegalAccessException e)
998-
{ isGEJVM50 = false; }
999-
catch (InvocationTargetException e)
1000-
{ isGEJVM50 = false; }
1001-
catch (InstantiationException e)
1002-
{ isGEJVM50 = false; }
1003-
1004-
if(isGEJVM50 == false)
1005-
{
1006-
//use our rounding code to round in pre java 5.0
1007-
roundedBD = roundByModePreJDK5(bd.unscaledValue(), bd.scale(), precision, roundingMode);
1008-
}
1009-
866+
public static BigDecimal roundByMode(BigDecimal bd, int precision, RoundingMode roundingMode)
867+
{
868+
MathContext mathContext = new MathContext(precision, roundingMode);
869+
BigDecimal roundedBD = bd.round(mathContext);
1010870
return roundedBD;
1011871
}
1012872

src/main/java/com/ibm/as400/access/AS400ImplRemote.java

+6-19
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.io.OutputStreamWriter;
2424
import java.io.PrintWriter;
2525
import java.io.UnsupportedEncodingException;
26-
import java.lang.reflect.Method;
2726
import java.net.ConnectException;
2827
import java.net.Socket;
2928
import java.nio.ByteBuffer;
@@ -2010,31 +2009,19 @@ else if (passwordLevel_< 4)
20102009
public static byte[] getAESEncryptionKey(byte[] sharedPrivateKey) throws NoSuchAlgorithmException, AS400SecurityException
20112010
{
20122011
// Verify that the JVM can support this.
2013-
// Check the key length. This method is only is in JDK 1.5 so we use
2014-
// reflection to access it.
2015-
try
2016-
{
2017-
Class cipherClass = Class.forName("javax.crypto.Cipher");
2018-
Class argTypes[] = new Class[1];
2019-
argTypes[0] = Class.forName("java.lang.String");
2020-
Method method = cipherClass.getMethod("getMaxAllowedKeyLength", argTypes);
2021-
Object args[] = new Object[1];
2022-
args[0] = "AES";
2023-
Integer outInteger = (Integer) method.invoke(null, args);
2024-
int keyLength = outInteger.intValue();
2025-
if (keyLength < 256)
2026-
{
2012+
// Check the key length.
2013+
int keyLength = Cipher.getMaxAllowedKeyLength("AES");
2014+
if (keyLength < 256) {
20272015
// If the key length is too small, notify the user
20282016
String message = "THE MAX AES KEY LENGTH IS " + keyLength
20292017
+ " AND MUST BE >= 256. UPDATE THE JVM ("
20302018
+ System.getProperty("java.vm.info") + ") AT "
20312019
+ System.getProperty("java.home") + " WITH JCE";
2032-
throw new AS400SecurityException(AS400SecurityException.UNKNOWN, new Exception(message));
2033-
}
2034-
} catch (Exception e) {
2035-
throw new AS400SecurityException(AS400SecurityException.UNKNOWN, e);
2020+
throw new AS400SecurityException(AS400SecurityException.UNKNOWN,
2021+
new Exception(message));
20362022
}
20372023

2024+
20382025
//
20392026
// The 256 bit encryption key is derived in the following fashion.
20402027
// DRDA AES encryption currently supports the 256-bit encryption key size.

src/main/java/com/ibm/as400/access/JDUtilities.java

-59
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import java.io.InputStream;
1818
import java.io.IOException;
1919
import java.io.Reader;
20-
import java.math.BigDecimal;
2120
import java.sql.*; // @J1c
2221
import java.util.Hashtable;
2322

@@ -648,64 +647,6 @@ static final String upperCaseIfNotQuoted(String name) {
648647
return name.toUpperCase();
649648
}
650649

651-
// @big For 1.4 backlevel support of Decimal and Numeric types
652-
/**
653-
* bigDecimalToPlainString takes a big decimal and converts it into a plain
654-
* string, without an exponent. This was the default behavior of toString
655-
* before JDK 1.5. bigDecimalToPlainString was taken from Native driver for
656-
* java 1.5 support and changed a bit for toolbox Coded so it will compile on
657-
* java 1.4 also
658-
*/
659-
static java.lang.reflect.Method toPlainStringMethod = null;
660-
static Object[] emptyArgs;
661-
662-
public static String bigDecimalToPlainString(BigDecimal bigDecimal) {
663-
if (JVMLevel_ >= 150) {
664-
// We compile using JDK 1.4, so we have to get to the new method via
665-
// reflection
666-
667-
if (toPlainStringMethod == null) {
668-
synchronized (bigDecimalLock_) {
669-
if (toPlainStringMethod == null) {
670-
try {
671-
Class bigDecimalClass = Class.forName("java.math.BigDecimal");
672-
Class[] parameterTypes = new Class[0];
673-
toPlainStringMethod = bigDecimalClass.getMethod("toPlainString",
674-
parameterTypes);
675-
emptyArgs = new Object[0];
676-
} catch (Exception e) {
677-
if (JDTrace.isTraceOn()) {
678-
JDTrace.logException(null,
679-
"Exception while calling BigDecimal.toPlainString.", e);
680-
}
681-
toPlainStringMethod = null;
682-
683-
return bigDecimal.toString();
684-
}
685-
} /* if */
686-
} /* synchronized */
687-
} /* toPlainStringMethod == null */
688-
String returnString;
689-
try {
690-
returnString = (String) toPlainStringMethod.invoke((Object) bigDecimal,
691-
emptyArgs);
692-
} catch (Exception e) {
693-
if (JDTrace.isTraceOn()) {
694-
JDTrace.logException(null,
695-
"Exception while calling BigDecimal.toPlainString.", e);
696-
}
697-
698-
returnString = bigDecimal.toString();
699-
}
700-
701-
return returnString;
702-
703-
} else { /* not JDK15 */
704-
705-
return bigDecimal.toString();
706-
}
707-
}
708-
709650
// @xml3
710651
// removes declaration (header)
711652
// returns input string if there is no xml declaration

0 commit comments

Comments
 (0)