diff --git a/poi-3.13.pwc/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/poi-3.13.pwc/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
index c5fc7a9..0bfd6ac 100644
--- a/poi-3.13.pwc/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
+++ b/poi-3.13.pwc/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
@@ -1915,6 +1915,10 @@
}
return linkTable.getNumNames();
}
+
+ public boolean nameExists(NameRecord nr) {
+ return linkTable.nameAlreadyExists(nr);
+ }
/** gets the name record
* @param index name index
@@ -1924,6 +1928,25 @@
return linkTable.getNameRecord(index);
}
+ public NameRecord getNameRecord(String name, int sheetNumber) {
+ if (name != null && name.length() > 0) {
+ return linkTable.getNameRecord(name, sheetNumber);
+ }
+ return null;
+ }
+
+ public void replaceNameRecord(String existingName, NameRecord nameRecord) {
+ linkTable.replaceNameRecord(existingName, nameRecord);
+ }
+
+ public void replaceNameSheet(NameRecord nameRecord, int newSheetNumber) {
+ linkTable.replaceNameSheet(newSheetNumber, nameRecord);
+ }
+
+ public int getNameRecordIndex(NameRecord nr) {
+ return linkTable.getNameRecordIndex(nr);
+ }
+
/** gets the name comment record
* @param nameRecord name record who's comment is required.
* @return name comment record or null
if there isn't one for the given name.
@@ -1950,6 +1973,10 @@
linkTable.addName(name);
return name;
+ }
+
+ public void addToNamesMap(NameRecord nr) {
+ linkTable.addToNamesMap(nr);
}
/**
@@ -1983,7 +2010,7 @@
linkTable.removeName(nameIndex);
}
}
-
+
/**
* If a {@link NameCommentRecord} is added or the name it references
* is renamed, then this will update the lookup cache for it.
diff --git a/poi-3.13.pwc/src/java/org/apache/poi/hssf/model/LinkTable.java b/poi-3.13.pwc/src/java/org/apache/poi/hssf/model/LinkTable.java
index 76a288c..af3684b 100644
--- a/poi-3.13.pwc/src/java/org/apache/poi/hssf/model/LinkTable.java
+++ b/poi-3.13.pwc/src/java/org/apache/poi/hssf/model/LinkTable.java
@@ -18,6 +18,7 @@
package org.apache.poi.hssf.model;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -185,6 +186,7 @@
private final List _definedNames;
private final int _recordCount;
private final WorkbookRecordList _workbookRecordList; // TODO - would be nice to remove this
+ private final Map> _nameRecordMap;
public LinkTable(List inputList, int startIndex, WorkbookRecordList workbookRecordList, Map commentRecords) {
@@ -213,6 +215,7 @@
}
_definedNames = new ArrayList();
+ _nameRecordMap = new HashMap>();
// collect zero or more DEFINEDNAMEs id=0x18,
// with their comments if present
while(true) {
@@ -220,6 +223,7 @@
if (nextClass == NameRecord.class) {
NameRecord nr = (NameRecord)rs.getNext();
_definedNames.add(nr);
+ addToNamesMap(nr);
}
else if (nextClass == NameCommentRecord.class) {
NameCommentRecord ncr = (NameCommentRecord)rs.getNext();
@@ -259,6 +263,7 @@
public LinkTable(int numberOfSheets, WorkbookRecordList workbookRecordList) {
_workbookRecordList = workbookRecordList;
_definedNames = new ArrayList();
+ _nameRecordMap = new HashMap>();
_externalBookBlocks = new ExternalBookBlock[] {
new ExternalBookBlock(numberOfSheets),
};
@@ -309,6 +314,7 @@
NameRecord record = getSpecificBuiltinRecord(name, sheetIndex);
if (record != null) {
_definedNames.remove(record);
+ removeFromNameRecordMap(record);
}
// TODO - do we need "Workbook.records.remove(...);" similar to that in Workbook.removeName(int namenum) {}?
}
@@ -320,9 +326,59 @@
public NameRecord getNameRecord(int index) {
return _definedNames.get(index);
}
+
+ public NameRecord getNameRecord(String name, int sheetNumber) {
+ if (name != null && name.length() > 0) {
+ Map entity = _nameRecordMap.get(sheetNumber);
+ if (entity != null) {
+ return entity.get(name.toLowerCase());
+ }
+ return null;
+ }
+ return null;
+ }
+
+ public int getNameRecordIndex(NameRecord nr) {
+ return _definedNames.indexOf(nr);
+ }
+
+ public void replaceNameRecord(String name, NameRecord nameRecord) {
+ if (name != null && name.length() > 0) {
+ Map record = _nameRecordMap.get(nameRecord.getSheetNumber());
+ if (record != null) {
+ record.remove(name);
+ }
+ }
+ if (nameRecord.getNameText() != null && nameRecord.getNameText().length() > 0) {
+ Map record = _nameRecordMap.get(nameRecord.getSheetNumber());
+ if (record != null) {
+ record.put(nameRecord.getNameText().toLowerCase(), nameRecord);
+ }
+ }
+ }
+
+ public void replaceNameSheet(int newSheetNumber, NameRecord nameRecord) {
+ String name = nameRecord.getNameText();
+ if (name != null && name.length() > 0) {
+ Map record = _nameRecordMap.get(nameRecord.getSheetNumber());
+ if (record != null) {
+ record.remove(name);
+ }
+ nameRecord.setSheetNumber(newSheetNumber);
+ record = _nameRecordMap.get(newSheetNumber);
+ if (record != null) {
+ record.put(nameRecord.getNameText().toLowerCase(), nameRecord);
+ } else {
+ record = new HashMap();
+ record.put(nameRecord.getNameText().toLowerCase(), nameRecord);
+ _nameRecordMap.put(newSheetNumber, record);
+ }
+ }
+ }
public void addName(NameRecord name) {
_definedNames.add(name);
+ addToNamesMap(name);
// TODO - this is messy
// Not the most efficient way but the other way was causing too many bugs
@@ -333,32 +389,52 @@
_workbookRecordList.add(idx+countNames, name);
}
+ public void addToNamesMap(NameRecord name) {
+ if (name != null
+ && name.getNameText() != null
+ && name.getNameText().length() > 0) {
+ if (_nameRecordMap.containsKey(name.getSheetNumber())) {
+ Map entity = _nameRecordMap.get(name.getSheetNumber());
+ entity.put(name.getNameText().toLowerCase(), name);
+ } else {
+ Map entity = new HashMap();
+ entity.put(name.getNameText().toLowerCase(), name);
+ _nameRecordMap.put(name.getSheetNumber(), entity);
+ }
+ }
+ }
+
public void removeName(int namenum) {
- _definedNames.remove(namenum);
+ NameRecord toRemove = _definedNames.get(namenum);
+ if (toRemove != null
+ && toRemove.getNameText() != null
+ && toRemove.getNameText().length() > 0) {
+ removeFromNameRecordMap(toRemove);
+ _definedNames.remove(namenum);
+ }
}
+ public void removeFromNameRecordMap(NameRecord toRemove) {
+ if (toRemove != null) {
+ Map entity = _nameRecordMap.get(toRemove.getSheetNumber());
+ if (entity != null) {
+ entity.remove(toRemove.getNameText().toLowerCase());
+ }
+ }
+ }
+
/**
* checks if the given name is already included in the linkTable
*/
public boolean nameAlreadyExists(NameRecord name)
{
- // Check to ensure no other names have the same case-insensitive name
- for ( int i = getNumNames()-1; i >=0; i-- ) {
- NameRecord rec = getNameRecord(i);
- if (rec != name) {
- if (isDuplicatedNames(name, rec))
- return true;
- }
- }
- return false;
- }
-
- private static boolean isDuplicatedNames(NameRecord firstName, NameRecord lastName) {
- return lastName.getNameText().equalsIgnoreCase(firstName.getNameText())
- && isSameSheetNames(firstName, lastName);
- }
- private static boolean isSameSheetNames(NameRecord firstName, NameRecord lastName) {
- return lastName.getSheetNumber() == firstName.getSheetNumber();
+ if (_nameRecordMap.get(name.getSheetNumber()) != null) {
+ Map entity = _nameRecordMap.get(name.getSheetNumber());
+ if (entity.containsKey(name.getNameText().toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
}
public String[] getExternalBookAndSheetName(int extRefIndex) {
diff --git a/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java b/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
index 79a5962..4f7c51e 100644
--- a/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
+++ b/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
@@ -92,13 +92,12 @@
* The sheet index is required to resolve sheet-level names. -1
means workbook-global names
*/
public EvaluationName getName(String name, int sheetIndex) {
- for(int i=0; i < _iBook.getNumNames(); i++) {
- NameRecord nr = _iBook.getNameRecord(i);
- if (nr.getSheetNumber() == sheetIndex+1 && name.equalsIgnoreCase(nr.getNameText())) {
- return new Name(nr, i);
- }
+ NameRecord found = _iBook.getNameRecord(name, sheetIndex+1);
+ if (found == null) {
+ return sheetIndex == -1 ? null : getName(name, -1);
+ } else {
+ return new Name(found, _iBook.getNameRecordIndex(found));
}
- return sheetIndex == -1 ? null : getName(name, -1);
}
public int getSheetIndex(EvaluationSheet evalSheet) {
diff --git a/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFName.java b/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFName.java
index 6b6ae38..602c747 100644
--- a/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFName.java
+++ b/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFName.java
@@ -129,23 +129,27 @@
validateName(nameName);
InternalWorkbook wb = _book.getWorkbook();
+ String existingName = _definedNameRec.getNameText();
_definedNameRec.setNameText(nameName);
-
int sheetNumber = _definedNameRec.getSheetNumber();
- //Check to ensure no other names have the same case-insensitive name
- for ( int i = wb.getNumNames()-1; i >=0; i-- )
- {
- NameRecord rec = wb.getNameRecord(i);
- if (rec != _definedNameRec) {
- if (rec.getNameText().equalsIgnoreCase(nameName) && sheetNumber == rec.getSheetNumber()){
- String msg = "The "+(sheetNumber == 0 ? "workbook" : "sheet")+" already contains this name: " + nameName;
- _definedNameRec.setNameText(nameName + "(2)");
- throw new IllegalArgumentException(msg);
- }
+ if (wb.nameExists(_definedNameRec)) {
+ String msg = "The "+(sheetNumber == 0 ? "workbook" : "sheet")+" already contains this name: " + nameName;
+ _definedNameRec.setNameText(nameName + "(2)");
+ throw new IllegalArgumentException(msg);
+ }
+ if (_definedNameRec.getNameText() != null && _definedNameRec.getNameText().length() > 0) {
+ NameRecord nr = wb.getNameRecord(existingName, _definedNameRec.getSheetNumber());
+ if (nr != null) {
+ HSSFName newName = new HSSFName(_book, _definedNameRec, wb.getNameCommentRecord(_definedNameRec));
+ _book.replaceNameRecord(existingName, newName);
+ wb.replaceNameRecord(existingName, _definedNameRec);
+ } else {
+ HSSFName newName = new HSSFName(_book, _definedNameRec, wb.getNameCommentRecord(_definedNameRec));
+ _book.addToNamesMap(newName);
+ wb.addToNamesMap(_definedNameRec);
}
}
-
// Update our comment, if there is one
if(_commentRec != null) {
_commentRec.setNameText(nameName);
@@ -245,7 +249,15 @@
(lastSheetIx == -1 ? "" : (" (0.." + lastSheetIx + ")")));
}
- _definedNameRec.setSheetNumber(index + 1);
+ if (_definedNameRec.getNameText() != null &&
+ _definedNameRec.getNameText().length() > 0) {
+ InternalWorkbook wb = _book.getWorkbook();
+ HSSFName newName = new HSSFName(_book, _definedNameRec, wb.getNameCommentRecord(_definedNameRec));
+ _book.replaceNameSheet(newName, index + 1);
+ wb.replaceNameSheet(_definedNameRec, index + 1);
+ } else {
+ _definedNameRec.setSheetNumber(index + 1);
+ }
}
/**
diff --git a/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index 8475ec7..e7bb2fb 100644
--- a/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/poi-3.13.pwc/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -143,6 +143,11 @@
*/
private ArrayList names;
+
+ /**
+ * this holds the HSSFName in a map for fast look-up.
+ */
+ private Map> namesMap;
/**
* this holds the HSSFFont objects attached to this workbook.
@@ -195,6 +200,7 @@
workbook = book;
_sheets = new ArrayList(INITIAL_CAPACITY);
names = new ArrayList(INITIAL_CAPACITY);
+ namesMap = new HashMap>();
}
/**
@@ -335,6 +341,7 @@
_sheets = new ArrayList(INITIAL_CAPACITY);
names = new ArrayList(INITIAL_CAPACITY);
+ namesMap = new HashMap>();
// Grab the data from the workbook stream, however
// it happens to be spelled.
@@ -363,6 +370,60 @@
NameRecord nameRecord = workbook.getNameRecord(i);
HSSFName name = new HSSFName(this, nameRecord, workbook.getNameCommentRecord(nameRecord));
names.add(name);
+ addToNamesMap(name);
+ }
+ }
+
+ /**
+ * This adds the HSSFName to the map.
+ */
+ public void addToNamesMap(HSSFName name) {
+ if (name.getNameName() != null && name.getNameName().length() > 0) {
+ Map entity = namesMap.get(name.getSheetIndex());
+ if (entity == null) {
+ entity = new HashMap();
+ entity.put(name.getNameName(), name);
+ namesMap.put(name.getSheetIndex(), entity);
+ } else {
+ entity.put(name.getNameName(), name);
+ }
+ }
+ }
+
+ /**
+ * Replace existing HSSFName with new name value.
+ */
+ public void replaceNameRecord(String existingName, HSSFName nameRecord) {
+ if (nameRecord != null) {
+ if (existingName != null && existingName.length() > 0) {
+ Map record = namesMap.get(nameRecord.getSheetIndex());
+ if (record != null) {
+ record.remove(existingName);
+ }
+ }
+ Map record = new HashMap();
+ record.put(nameRecord.getNameName(), nameRecord);
+ namesMap.put(nameRecord.getSheetIndex(), record);
+ }
+ }
+
+ /**
+ * Move the HHSFName to a new sheet in the map of names.
+ * Note: this sets the nameRecord to the new sheet index.
+ */
+ public void replaceNameSheet(HSSFName nameRecord, int newSheetNumber) {
+ if (nameRecord != null) {
+ String name = nameRecord.getNameName();
+ if (name != null && name.length() > 0) {
+ Map record = namesMap.get(nameRecord.getSheetIndex());
+ if (record != null) {
+ record.remove(name);
+ }
+ nameRecord.setSheetIndex(newSheetNumber - 1);
+ record = new HashMap();
+ record.put(nameRecord.getNameName(), nameRecord);
+ namesMap.put(nameRecord.getSheetIndex(), record);
+ }
}
}
@@ -815,6 +876,7 @@
NameRecord newNameRecord = workbook.cloneFilter(filterDbNameIndex, newSheetIndex);
HSSFName newName = new HSSFName(this, newNameRecord);
names.add(newName);
+ addToNamesMap(newName);
}
// TODO - maybe same logic required for other/all built-in name records
// workbook.cloneDrawings(clonedSheet.getSheet());
@@ -1522,13 +1584,33 @@
return result;
}
- @Override
public HSSFName getName(String name) {
int nameIndex = getNameIndex(name);
if (nameIndex < 0) {
return null;
}
return names.get(nameIndex);
+ }
+
+ /**
+ * This is zero based, i.e. sheetNumber not sheetIndex
+ *
+ * @param name
+ * @param sheetNumber
+ * @return
+ */
+ public HSSFName getName(String name, int sheetNumber) {
+ HSSFName found = null;
+ if (name != null && name.length() > 0) {
+ Map record = namesMap.get(sheetNumber);
+ found = record.get(name);
+ }
+ //FIXME: this is a failsafe move.
+ if (found == null) {
+ return getName(name);
+ } else {
+ return found;
+ }
}
@Override
@@ -1647,6 +1729,7 @@
HSSFName newName = new HSSFName(this, nameRecord);
names.add(newName);
+ addToNamesMap(newName);
return newName;
}
@@ -1686,9 +1769,18 @@
@Override
public void removeName(int index){
+ HSSFName name = names.get(index);
+ removeFromNamesMap(name);
names.remove(index);
workbook.removeName(index);
}
+
+ private void removeFromNamesMap(HSSFName name) {
+ Map record = namesMap.get(name.getSheetIndex());
+ if (record != null) {
+ record.remove(name.getNameName());
+ }
+ }
/**
* Returns the instance of HSSFDataFormat for this workbook.