git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@986649 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_7_BETA3
@@ -34,6 +34,7 @@ | |||
<changes> | |||
<release version="3.7-beta3" date="2010-??-??"> | |||
<action dev="POI-DEVELOPERS" type="add">48900 - support for protecting a XSSF workbook</action> | |||
<action dev="POI-DEVELOPERS" type="fix">49725 - fixed FormulaParser to correctly process defined names with underscore</action> | |||
<action dev="POI-DEVELOPERS" type="add">48526 - added implementation for RANDBETWEEN()</action> | |||
<action dev="POI-DEVELOPERS" type="fix">49725 - avoid exception in OperandResolver.parseDouble when input is minus ("-")</action> |
@@ -455,7 +455,13 @@ public interface Sheet extends Iterable<Row> { | |||
* @return true => protection enabled; false => protection disabled | |||
*/ | |||
boolean getProtect(); | |||
/** | |||
* Sets the protection enabled as well as the password | |||
* @param password to set for protection. Pass <code>null</code> to remove protection | |||
*/ | |||
public void protectSheet(String password); | |||
/** | |||
* Answer whether scenario protection is enabled or disabled | |||
* |
@@ -32,6 +32,7 @@ import javax.xml.namespace.QName; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.poi.POIXMLException; | |||
import org.apache.poi.hssf.record.PasswordRecord; | |||
import org.apache.poi.hssf.record.formula.FormulaShifter; | |||
import org.apache.poi.hssf.util.PaneInformation; | |||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; | |||
@@ -52,6 +53,7 @@ import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.ss.util.CellRangeAddressList; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.ss.util.SSCellRange; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
@@ -941,7 +943,41 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
public boolean getProtect() { | |||
return worksheet.isSetSheetProtection() && sheetProtectionEnabled(); | |||
} | |||
/** | |||
* Enables sheet protection and sets the password for the sheet. | |||
* Also sets some attributes on the {@link CTSheetProtection} that correspond to | |||
* the default values used by Excel | |||
* | |||
* @param password to set for protection. Pass <code>null</code> to remove protection | |||
*/ | |||
@Override | |||
public void protectSheet(String password) { | |||
if(password != null) { | |||
CTSheetProtection sheetProtection = worksheet.addNewSheetProtection(); | |||
sheetProtection.xsetPassword(stringToExcelPassword(password)); | |||
sheetProtection.setSheet(true); | |||
sheetProtection.setScenarios(true); | |||
sheetProtection.setObjects(true); | |||
} else { | |||
worksheet.unsetSheetProtection(); | |||
} | |||
} | |||
/** | |||
* Converts a String to a {@link STUnsignedShortHex} value that contains the {@link PasswordRecord#hashPassword(String)} | |||
* value in hexadecimal format | |||
* | |||
* @param password the password string you wish convert to an {@link STUnsignedShortHex} | |||
* @return {@link STUnsignedShortHex} that contains Excel hashed password in Hex format | |||
*/ | |||
private STUnsignedShortHex stringToExcelPassword(String password) { | |||
STUnsignedShortHex hexPassword = STUnsignedShortHex.Factory.newInstance(); | |||
hexPassword.setStringValue(String.valueOf(HexDump.shortToHex(PasswordRecord.hashPassword(password))).substring(2)); | |||
return hexPassword; | |||
} | |||
/** | |||
* Returns the logical row ( 0-based). If you ask for a row that is not | |||
* defined you get a null. This is to say row 4 represents the fifth row on a sheet. |
@@ -24,6 +24,8 @@ import org.apache.poi.xssf.XSSFTestDataSamples; | |||
import org.apache.poi.xssf.model.CommentsTable; | |||
import org.apache.poi.xssf.model.StylesTable; | |||
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.hssf.record.PasswordRecord; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; | |||
@@ -979,4 +981,25 @@ public final class TestXSSFSheet extends BaseTestSheet { | |||
assertEquals("A1:D100", sheet.getCTWorksheet().getAutoFilter().getRef()); | |||
} | |||
public void testProtectSheet_lowlevel() { | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
XSSFSheet sheet = wb.createSheet(); | |||
CTSheetProtection pr = sheet.getCTWorksheet().getSheetProtection(); | |||
assertNull("CTSheetProtection should be null by default", pr); | |||
String password = "Test"; | |||
sheet.protectSheet(password); | |||
pr = sheet.getCTWorksheet().getSheetProtection(); | |||
assertNotNull("CTSheetProtection should be not null", pr); | |||
assertTrue("sheet protection should be on", pr.isSetSheet()); | |||
assertTrue("object protection should be on", pr.isSetObjects()); | |||
assertTrue("scenario protection should be on", pr.isSetScenarios()); | |||
String hash = String.valueOf(HexDump.shortToHex(PasswordRecord.hashPassword(password))).substring(2); | |||
assertEquals("well known value for top secret hash should be "+ hash, hash, pr.xgetPassword().getStringValue()); | |||
sheet.protectSheet(null); | |||
assertNull("protectSheet(null) should unset CTSheetProtection", sheet.getCTWorksheet().getSheetProtection()); | |||
} | |||
} |
@@ -640,4 +640,18 @@ public abstract class BaseTestSheet extends TestCase { | |||
sheet.setColumnHidden(2, true); | |||
assertTrue(sheet.isColumnHidden(2)); | |||
} | |||
public void testProtectSheet() { | |||
Workbook wb = _testDataProvider.createWorkbook(); | |||
Sheet sheet = wb.createSheet(); | |||
assertFalse(sheet.getProtect()); | |||
sheet.protectSheet("Test"); | |||
assertTrue(sheet.getProtect()); | |||
sheet.protectSheet(null); | |||
assertFalse(sheet.getProtect()); | |||
} | |||
} |