Author: yegor Date: Sun Jun 2 15:13:47 2013 New Revision: 1488729 URL: http://svn.apache.org/r1488729 Log: Bugzilla 55036 - Dec2HEx formula support
Added: poi/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java poi/trunk/src/java/org/apache/poi/util/Configurator.java poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestDec2Hex.java Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java?rev=1488729&r1=1488728&r2=1488729&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java Sun Jun 2 15:13:47 2013 @@ -27,6 +27,7 @@ import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.SpreadsheetVersion; +import org.apache.poi.util.Configurator; /** * High level representation of a row of a spreadsheet. @@ -39,7 +40,7 @@ import org.apache.poi.ss.SpreadsheetVers public final class HSSFRow implements Row { // used for collections - public final static int INITIAL_CAPACITY = 5; + public final static int INITIAL_CAPACITY = Configurator.getIntValue("HSSFRow.ColInitialCapacity", 5); private int rowNum; private HSSFCell[] cells; Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=1488729&r1=1488728&r2=1488729&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Sun Jun 2 15:13:47 2013 @@ -50,6 +50,7 @@ import org.apache.poi.ss.util.CellRangeA import org.apache.poi.ss.util.CellReference; import org.apache.poi.ss.util.SSCellRange; import org.apache.poi.ss.util.SheetUtil; +import org.apache.poi.util.Configurator; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -74,7 +75,7 @@ public final class HSSFSheet implements * rows. It is currently set to 20. If you generate larger sheets you may benefit * by setting this to a higher number and recompiling a custom edition of HSSFSheet. */ - public final static int INITIAL_CAPACITY = 20; + public final static int INITIAL_CAPACITY = Configurator.getIntValue("HSSFSheet.RowInitialCapacity", 20); /** * reference to the low level {@link InternalSheet} object Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=1488729&r1=1488728&r2=1488729&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Sun Jun 2 15:13:47 2013 @@ -29,6 +29,7 @@ import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; +import org.apache.commons.codec.digest.DigestUtils; import org.apache.poi.POIDocument; import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.ddf.EscherBitmapBlip; @@ -54,9 +55,9 @@ import org.apache.poi.ss.formula.udf.UDF import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.WorkbookUtil; +import org.apache.poi.util.Configurator; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.poi.ss.formula.udf.IndexedUDFFinder; @@ -93,7 +94,7 @@ public final class HSSFWorkbook extends * since you're never allowed to have more or less than three sheets! */ - public final static int INITIAL_CAPACITY = 3; + public final static int INITIAL_CAPACITY = Configurator.getIntValue("HSSFWorkbook.SheetInitialCapacity",3); /** * this is the reference to the low level Workbook object Added: poi/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java?rev=1488729&view=auto ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java (added) +++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java Sun Jun 2 15:13:47 2013 @@ -0,0 +1,122 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula.functions; + +import org.apache.poi.ss.formula.eval.*; + +/** + * Implementation for Excel DELTA() function.<p/> + * <p/> + * <b>Syntax</b>:<br/> <b>DEC2HEX </b>(<b>number</b>,<b>places</b> )<br/> + * <p/> + * Converts a decimal number to hexadecimal. + * + * The decimal integer you want to convert. If number is negative, places is ignored + * and this function returns a 10-character (40-bit) hexadecimal number in which the + * most significant bit is the sign bit. The remaining 39 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * + * <ul> + * <li>If number < -549,755,813,888 or if number > 549,755,813,887, this function returns the #NUM! error value.</li> + * <li>If number is nonnumeric, this function returns the #VALUE! error value.</li> + * </ul> + * + * <h2>places</h2> + * + * The number of characters to use. The places argument is useful for padding the + * return value with leading 0s (zeros). + * + * <ul> + * <li>If this argument is omitted, this function uses the minimum number of characters necessary.</li> + * <li>If this function requires more than places characters, it returns the #NUM! error value.</li> + * <li>If this argument is nonnumeric, this function returns the #VALUE! error value.</li> + * <li>If this argument is negative, this function returns the #NUM! error value.</li> + * <li>If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point.</li> + * </ul> + * + * @author cedric dot walter @ gmail dot com + */ +public final class Dec2Hex extends Var1or2ArgFunction { + + private final static long MIN_VALUE = new Long("-549755813888").longValue(); + private final static long MAX_VALUE = new Long("549755813887").longValue(); + private final static int DEFAULT_PLACES_VALUE = 10;; + + @Override + public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval number, ValueEval places) { + ValueEval veText1; + try { + veText1 = OperandResolver.getSingleValue(number, srcRowIndex, srcColumnIndex); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + String strText1 = OperandResolver.coerceValueToString(veText1); + Double number1 = OperandResolver.parseDouble(strText1); + + //If this number argument is non numeric, this function returns the #VALUE! error value. + if (number1 == null) { + return ErrorEval.VALUE_INVALID; + } + + //If number < -549,755,813,888 or if number > 549,755,813,887, this function returns the #NUM! error value. + if (number1.longValue() < MIN_VALUE || number1.longValue() > MAX_VALUE) { + return ErrorEval.NUM_ERROR; + } + + int placesNumber = 0; + if (number1 < 0) { + placesNumber = DEFAULT_PLACES_VALUE; + } else { + ValueEval placesValueEval; + try { + placesValueEval = OperandResolver.getSingleValue(places, srcRowIndex, srcColumnIndex); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + String placesStr = OperandResolver.coerceValueToString(placesValueEval); + Double placesNumberDouble = OperandResolver.parseDouble(placesStr); + + //non numeric value + if (placesNumberDouble == null) { + return ErrorEval.VALUE_INVALID; + } + + //If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point. + placesNumber = placesNumberDouble.intValue(); + + if (placesNumber < 0) { + return ErrorEval.NUM_ERROR; + } + } + + String hex = ""; + if (placesNumber != 0) { + hex = String.format("%0"+placesNumber+"X", number1.intValue() & 0x0FFFFF); + } + else { + hex = Integer.toHexString(number1.intValue()); + } + + return new StringEval(hex.toUpperCase()); + } + + @Override + public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { + return this.evaluate(srcRowIndex, srcColumnIndex, arg0, new StringEval(String.valueOf(DEFAULT_PLACES_VALUE))); + } +} \ No newline at end of file Added: poi/trunk/src/java/org/apache/poi/util/Configurator.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/util/Configurator.java?rev=1488729&view=auto ============================================================================== --- poi/trunk/src/java/org/apache/poi/util/Configurator.java (added) +++ poi/trunk/src/java/org/apache/poi/util/Configurator.java Sun Jun 2 15:13:47 2013 @@ -0,0 +1,40 @@ +package org.apache.poi.util; + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +/** + * + * @author Cedric Walter (cedric.walter at innoveo.com) + */ +public class Configurator { + + private static POILogger logger = POILogFactory.getLogger(Configurator.class); + + public static int getIntValue(String systemProperty, int defaultValue) { + int result = defaultValue; + String property = System.getProperty(systemProperty); + try { + result = Integer.valueOf(property); + } catch (Exception e) { + logger.log(POILogger.ERROR, "System property -D"+systemProperty +" do not contains a valid integer " + property); + } + return result; + } + + +} Modified: poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java?rev=1488729&r1=1488728&r2=1488729&view=diff ============================================================================== --- poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java (original) +++ poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java Sun Jun 2 15:13:47 2013 @@ -226,7 +226,7 @@ public abstract class BaseTestFunctionsF HSSFCell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_RESULT); String rowComment = getRowCommentColumnValue(r); - String msgPrefix = formatTestCaseDetails(sheetName, r.getRowNum(), c, currentGroupComment, rowComment); + String msgPrefix = formatTestCaseDetails(this.getFilename(),sheetName, r.getRowNum(), c, currentGroupComment, rowComment); try { confirmExpectedResult(msgPrefix, expectedValueCell, actualValue); _evaluationSuccessCount ++; @@ -250,10 +250,13 @@ public abstract class BaseTestFunctionsF } - private static String formatTestCaseDetails(String sheetName, int rowIndex, HSSFCell c, String currentGroupComment, + private static String formatTestCaseDetails(String filename, String sheetName, int rowIndex, HSSFCell c, String currentGroupComment, String rowComment) { StringBuffer sb = new StringBuffer(); + + sb.append("In ").append(filename).append(" "); + CellReference cr = new CellReference(sheetName, rowIndex, c.getColumnIndex(), false, false); sb.append(cr.formatAsString()); sb.append(" {=").append(c.getCellFormula()).append("}"); Added: poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestDec2Hex.java URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestDec2Hex.java?rev=1488729&view=auto ============================================================================== --- poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestDec2Hex.java (added) +++ poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestDec2Hex.java Sun Jun 2 15:13:47 2013 @@ -0,0 +1,79 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula.functions; + +import junit.framework.TestCase; +import org.apache.poi.ss.formula.eval.ErrorEval; +import org.apache.poi.ss.formula.eval.StringEval; +import org.apache.poi.ss.formula.eval.ValueEval; + +/** + * Tests for {@link Dec2Hex} + * + * @author cedric dot walter @ gmail dot com + */ +public final class TestDec2Hex extends TestCase { + + private static ValueEval invokeValue(String number1, String number2) { + ValueEval[] args = new ValueEval[] { new StringEval(number1), new StringEval(number2), }; + return new Dec2Hex().evaluate(args, -1, -1); + } + + private static ValueEval invokeValue(String number1) { + ValueEval[] args = new ValueEval[] { new StringEval(number1), }; + return new Dec2Hex().evaluate(args, -1, -1); + } + + private static void confirmValue(String msg, String number1, String number2, String expected) { + ValueEval result = invokeValue(number1, number2); + assertEquals(StringEval.class, result.getClass()); + assertEquals(msg, expected, ((StringEval) result).getStringValue()); + } + + private static void confirmValue(String msg, String number1, String expected) { + ValueEval result = invokeValue(number1); + assertEquals(StringEval.class, result.getClass()); + assertEquals(msg, expected, ((StringEval) result).getStringValue()); + } + + private static void confirmValueError(String msg, String number1, String number2, ErrorEval numError) { + ValueEval result = invokeValue(number1, number2); + assertEquals(ErrorEval.class, result.getClass()); + assertEquals(msg, numError, result); + } + + public void testBasic() { + confirmValue("Converts decimal 100 to hexadecimal with 0 characters (64)", "100","0", "64"); + confirmValue("Converts decimal 100 to hexadecimal with 4 characters (0064)", "100","4", "0064"); + confirmValue("Converts decimal 100 to hexadecimal with 5 characters (0064)", "100","5", "00064"); + confirmValue("Converts decimal 100 to hexadecimal with 10 (default) characters", "100","10", "0000000064"); + confirmValue("If argument places contains a decimal value, dec2hex ignores the numbers to the right side of the decimal point.", "100","10.0", "0000000064"); + + confirmValue("Converts decimal -54 to hexadecimal, 0 is ignored", "-54", "0", "00000FFFCA"); + confirmValue("Converts decimal -54 to hexadecimal, 2 is ignored","-54", "2", "00000FFFCA"); + confirmValue("places is optionnal","-54", "00000FFFCA"); + } + + public void testErrors() { + confirmValueError("Out of range min number","-549755813889","0", ErrorEval.NUM_ERROR); + confirmValueError("Out of range max number","549755813888","0", ErrorEval.NUM_ERROR); + + confirmValueError("negative places not allowed","549755813888","-10", ErrorEval.NUM_ERROR); + confirmValueError("non number places not allowed","ABCDEF","0", ErrorEval.VALUE_INVALID); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org For additional commands, e-mail: commits-h...@poi.apache.org