001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /*
018: * Created on May 15, 2005
019: *
020: */
021: package org.apache.poi.hssf.record.formula.functions;
022:
023: import org.apache.poi.hssf.record.formula.eval.ErrorEval;
024: import org.apache.poi.hssf.record.formula.eval.Eval;
025: import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
026: import org.apache.poi.hssf.record.formula.eval.StringEval;
027: import org.apache.poi.hssf.record.formula.eval.StringValueEval;
028: import org.apache.poi.hssf.record.formula.eval.ValueEval;
029:
030: /**
031: * An implementation of the REPLACE function:
032: * Replaces part of a text string based on the number of characters
033: * you specify, with another text string.
034: * @author Manda Wilson < wilson at c bio dot msk cc dot org >
035: */
036: public class Replace extends TextFunction {
037:
038: /**
039: * Replaces part of a text string based on the number of characters
040: * you specify, with another text string.
041: *
042: * @see org.apache.poi.hssf.record.formula.eval.Eval
043: */
044: public Eval evaluate(Eval[] operands, int srcCellRow,
045: short srcCellCol) {
046: Eval retval = null;
047: String oldStr = null;
048: String newStr = null;
049: int startNum = 0;
050: int numChars = 0;
051:
052: switch (operands.length) {
053: default:
054: retval = ErrorEval.VALUE_INVALID;
055: case 4:
056: // first operand is text string containing characters to replace
057: // second operand is position of first character to replace
058: // third operand is the number of characters in the old string
059: // you want to replace with new string
060: // fourth operand is the new string
061: ValueEval firstveval = singleOperandEvaluate(operands[0],
062: srcCellRow, srcCellCol);
063: ValueEval secondveval = singleOperandEvaluate(operands[1],
064: srcCellRow, srcCellCol);
065: ValueEval thirdveval = singleOperandEvaluate(operands[2],
066: srcCellRow, srcCellCol);
067: ValueEval fourthveval = singleOperandEvaluate(operands[3],
068: srcCellRow, srcCellCol);
069: if (firstveval instanceof StringValueEval
070: && secondveval instanceof NumericValueEval
071: && thirdveval instanceof NumericValueEval
072: && fourthveval instanceof StringValueEval) {
073:
074: StringValueEval oldStrEval = (StringValueEval) firstveval;
075: oldStr = oldStrEval.getStringValue();
076:
077: NumericValueEval startNumEval = (NumericValueEval) secondveval;
078: // NOTE: it is safe to cast to int here
079: // because in Excel =REPLACE("task", 2.7, 3, "est")
080: // returns test
081: // so 2.7 must be truncated to 2
082: // and =REPLACE("task", 1, 1.9, "") returns ask
083: // so 1.9 must be truncated to 1
084: startNum = (int) startNumEval.getNumberValue();
085:
086: NumericValueEval numCharsEval = (NumericValueEval) thirdveval;
087: numChars = (int) numCharsEval.getNumberValue();
088:
089: StringValueEval newStrEval = (StringValueEval) fourthveval;
090: newStr = newStrEval.getStringValue();
091: } else {
092: retval = ErrorEval.VALUE_INVALID;
093: }
094: }
095:
096: if (retval == null) {
097: if (startNum < 1 || numChars < 0) {
098: retval = ErrorEval.VALUE_INVALID;
099: } else {
100: StringBuffer strBuff = new StringBuffer(oldStr);
101: // remove any characters that should be replaced
102: if (startNum <= oldStr.length() && numChars != 0) {
103: strBuff.delete(startNum - 1, startNum - 1
104: + numChars);
105: }
106: // now insert (or append) newStr
107: if (startNum > strBuff.length()) {
108: strBuff.append(newStr);
109: } else {
110: strBuff.insert(startNum - 1, newStr);
111: }
112: retval = new StringEval(strBuff.toString());
113: }
114: }
115: return retval;
116: }
117:
118: }
|