aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/documentation/content/xdocs/status.xml2
-rw-r--r--src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java307
-rw-r--r--src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java92
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java152
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java2
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java135
-rw-r--r--src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java231
-rw-r--r--src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java109
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/TestDocumentProtection.java153
-rw-r--r--test-data/document/documentProtection_comments_no_password.docxbin0 -> 9868 bytes
-rw-r--r--test-data/document/documentProtection_forms_no_password.docxbin0 -> 9924 bytes
-rw-r--r--test-data/document/documentProtection_no_protection.docxbin0 -> 9884 bytes
-rw-r--r--test-data/document/documentProtection_no_protection_tag_existing.docxbin0 -> 9923 bytes
-rw-r--r--test-data/document/documentProtection_readonly_no_password.docxbin0 -> 9856 bytes
-rw-r--r--test-data/document/documentProtection_trackedChanges_no_password.docxbin0 -> 9940 bytes
-rw-r--r--test-data/document/protected_sample.docxbin0 -> 10082 bytes
-rw-r--r--test-data/spreadsheet/sheetProtection_allLocked.xlsxbin0 -> 7871 bytes
-rw-r--r--test-data/spreadsheet/sheetProtection_not_protected.xlsxbin0 -> 28728 bytes
-rw-r--r--test-data/spreadsheet/workbookProtection_not_protected.xlsxbin0 -> 28728 bytes
-rw-r--r--test-data/spreadsheet/workbookProtection_workbook_revision_protected.xlsxbin0 -> 12468 bytes
-rw-r--r--test-data/spreadsheet/workbookProtection_workbook_structure_protected.xlsxbin0 -> 28727 bytes
-rw-r--r--test-data/spreadsheet/workbookProtection_workbook_windows_protected.xlsxbin0 -> 28739 bytes
-rw-r--r--test-data/spreadsheet/workbookProtection_worksheet_protected.xlsxbin0 -> 28754 bytes
23 files changed, 1179 insertions, 4 deletions
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index 76eafe8e2a..209d8ae8d8 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -28,11 +28,13 @@
<person id="NB" name="Nick Burch" email="nick@torchbox.com"/>
<person id="POI-DEVELOPERS" name="POI Developers" email="dev@poi.apache.org"/>
<person id="RK" name="Rainer Klute" email="klute@apache.org"/>
+ <person id="UC" name="Ugo Cei" email="ugo@apache.org"/>
<person id="YK" name="Yegor Kozlov" email="yegor@apache.org"/>
</developers>
<changes>
<release version="3.6-beta1" date="2009-??-??">
+ <action dev="POI-DEVELOPERS" type="add">47942 - added implementation of protection features to XLSX and DOCX files</action>
<action dev="POI-DEVELOPERS" type="fix">48070 - preserve leading and trailing white spaces in XSSFRichTextString</action>
<action dev="POI-DEVELOPERS" type="add">48044 - added implementation for CountBlank function</action>
<action dev="POI-DEVELOPERS" type="fix">48036 - added IntersectionEval to allow evaluation of the intersection formula operator</action>
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
index b5a70286a2..76dfabc8e8 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
@@ -78,6 +78,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
@@ -857,7 +858,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
* @return true => protection enabled; false => protection disabled
*/
public boolean getProtect() {
- return worksheet.isSetSheetProtection() && worksheet.getSheetProtection().getSheet();
+ return worksheet.isSetSheetProtection() && sheetProtectionEnabled();
}
/**
@@ -2332,4 +2333,308 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
worksheet.save(out, xmlOptions);
}
+
+ /**
+ * @return true when Autofilters are locked and the sheet is protected.
+ */
+ public boolean isAutoFilterLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getAutoFilter();
+ }
+
+ /**
+ * @return true when Deleting columns is locked and the sheet is protected.
+ */
+ public boolean isDeleteColumnsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getDeleteColumns();
+ }
+
+ /**
+ * @return true when Deleting rows is locked and the sheet is protected.
+ */
+ public boolean isDeleteRowsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getDeleteRows();
+ }
+
+ /**
+ * @return true when Formatting cells is locked and the sheet is protected.
+ */
+ public boolean isFormatCellsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getFormatCells();
+ }
+
+ /**
+ * @return true when Formatting columns is locked and the sheet is protected.
+ */
+ public boolean isFormatColumnsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getFormatColumns();
+ }
+
+ /**
+ * @return true when Formatting rows is locked and the sheet is protected.
+ */
+ public boolean isFormatRowsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getFormatRows();
+ }
+
+ /**
+ * @return true when Inserting columns is locked and the sheet is protected.
+ */
+ public boolean isInsertColumnsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getInsertColumns();
+ }
+
+ /**
+ * @return true when Inserting hyperlinks is locked and the sheet is protected.
+ */
+ public boolean isInsertHyperlinksLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getInsertHyperlinks();
+ }
+
+ /**
+ * @return true when Inserting rows is locked and the sheet is protected.
+ */
+ public boolean isInsertRowsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getInsertRows();
+ }
+
+ /**
+ * @return true when Pivot tables are locked and the sheet is protected.
+ */
+ public boolean isPivotTablesLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getPivotTables();
+ }
+
+ /**
+ * @return true when Sorting is locked and the sheet is protected.
+ */
+ public boolean isSortLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getSort();
+ }
+
+ /**
+ * @return true when Objects are locked and the sheet is protected.
+ */
+ public boolean isObjectsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getObjects();
+ }
+
+ /**
+ * @return true when Scenarios are locked and the sheet is protected.
+ */
+ public boolean isScenariosLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getScenarios();
+ }
+
+ /**
+ * @return true when Selection of locked cells is locked and the sheet is protected.
+ */
+ public boolean isSelectLockedCellsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getSelectLockedCells();
+ }
+
+ /**
+ * @return true when Selection of unlocked cells is locked and the sheet is protected.
+ */
+ public boolean isSelectUnlockedCellsLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getSelectUnlockedCells();
+ }
+
+ /**
+ * @return true when Sheet is Protected.
+ */
+ public boolean isSheetLocked() {
+ createProtectionFieldIfNotPresent();
+ return sheetProtectionEnabled() && worksheet.getSheetProtection().getSheet();
+ }
+
+ /**
+ * Enable sheet protection
+ */
+ public void enableLocking() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setSheet(true);
+ }
+
+ /**
+ * Disable sheet protection
+ */
+ public void disableLocking() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setSheet(false);
+ }
+
+ /**
+ * Enable Autofilters locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockAutoFilter() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setAutoFilter(true);
+ }
+
+ /**
+ * Enable Deleting columns locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockDeleteColumns() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setDeleteColumns(true);
+ }
+
+ /**
+ * Enable Deleting rows locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockDeleteRows() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setDeleteRows(true);
+ }
+
+ /**
+ * Enable Formatting cells locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockFormatCells() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setDeleteColumns(true);
+ }
+
+ /**
+ * Enable Formatting columns locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockFormatColumns() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setFormatColumns(true);
+ }
+
+ /**
+ * Enable Formatting rows locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockFormatRows() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setFormatRows(true);
+ }
+
+ /**
+ * Enable Inserting columns locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockInsertColumns() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setInsertColumns(true);
+ }
+
+ /**
+ * Enable Inserting hyperlinks locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockInsertHyperlinks() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setInsertHyperlinks(true);
+ }
+
+ /**
+ * Enable Inserting rows locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockInsertRows() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setInsertRows(true);
+ }
+
+ /**
+ * Enable Pivot Tables locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockPivotTables() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setPivotTables(true);
+ }
+
+ /**
+ * Enable Sort locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockSort() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setSort(true);
+ }
+
+ /**
+ * Enable Objects locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockObjects() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setObjects(true);
+ }
+
+ /**
+ * Enable Scenarios locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockScenarios() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setScenarios(true);
+ }
+
+ /**
+ * Enable Selection of locked cells locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockSelectLockedCells() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setSelectLockedCells(true);
+ }
+
+ /**
+ * Enable Selection of unlocked cells locking.
+ * This does not modify sheet protection status.
+ * To enforce this locking, call {@link #enableLocking()}
+ */
+ public void lockSelectUnlockedCells() {
+ createProtectionFieldIfNotPresent();
+ worksheet.getSheetProtection().setSelectUnlockedCells(true);
+ }
+
+ private void createProtectionFieldIfNotPresent() {
+ if (worksheet.getSheetProtection() == null) {
+ worksheet.setSheetProtection(CTSheetProtection.Factory.newInstance());
+ }
+ }
+
+ private boolean sheetProtectionEnabled() {
+ return worksheet.getSheetProtection().getSheet();
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
index 67d4f69bf0..92eca64245 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
@@ -1345,4 +1345,96 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
public MapInfo getMapInfo(){
return mapInfo;
}
+
+
+ /**
+ * Specifies a boolean value that indicates whether structure of workbook is locked. <br/>
+ * A value true indicates the structure of the workbook is locked. Worksheets in the workbook can't be moved,
+ * deleted, hidden, unhidden, or renamed, and new worksheets can't be inserted.<br/>
+ * A value of false indicates the structure of the workbook is not locked.<br/>
+ *
+ * @return true if structure of workbook is locked
+ */
+ public boolean isStructureLocked() {
+ return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockStructure();
+ }
+
+ /**
+ * Specifies a boolean value that indicates whether the windows that comprise the workbook are locked. <br/>
+ * A value of true indicates the workbook windows are locked. Windows are the same size and position each time the
+ * workbook is opened.<br/>
+ * A value of false indicates the workbook windows are not locked.
+ *
+ * @return true if windows that comprise the workbook are locked
+ */
+ public boolean isWindowsLocked() {
+ return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockWindows();
+ }
+
+ /**
+ * Specifies a boolean value that indicates whether the workbook is locked for revisions.
+ *
+ * @return true if the workbook is locked for revisions.
+ */
+ public boolean isRevisionLocked() {
+ return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockRevision();
+ }
+
+ /**
+ * Locks the structure of workbook.
+ */
+ public void lockStructure() {
+ createProtectionFieldIfNotPresent();
+ workbook.getWorkbookProtection().setLockStructure(true);
+ }
+
+ /**
+ * Unlocks the structure of workbook.
+ */
+ public void unLockStructure() {
+ createProtectionFieldIfNotPresent();
+ workbook.getWorkbookProtection().setLockStructure(false);
+ }
+
+ /**
+ * Locks the windows that comprise the workbook.
+ */
+ public void lockWindows() {
+ createProtectionFieldIfNotPresent();
+ workbook.getWorkbookProtection().setLockWindows(true);
+ }
+
+ /**
+ * Unlocks the windows that comprise the workbook.
+ */
+ public void unLockWindows() {
+ createProtectionFieldIfNotPresent();
+ workbook.getWorkbookProtection().setLockWindows(false);
+ }
+
+ /**
+ * Locks the workbook for revisions.
+ */
+ public void lockRevision() {
+ createProtectionFieldIfNotPresent();
+ workbook.getWorkbookProtection().setLockRevision(true);
+ }
+
+ /**
+ * Unlocks the workbook for revisions.
+ */
+ public void unLockRevision() {
+ createProtectionFieldIfNotPresent();
+ workbook.getWorkbookProtection().setLockRevision(false);
+ }
+
+ private boolean workbookProtectionPresent() {
+ return workbook.getWorkbookProtection() != null;
+ }
+
+ private void createProtectionFieldIfNotPresent() {
+ if (workbook.getWorkbookProtection() == null){
+ workbook.setWorkbookProtection(CTWorkbookProtection.Factory.newInstance());
+ }
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
index 19faaf0085..ae1440b492 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
@@ -33,7 +33,6 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
-
import javax.xml.namespace.QName;
/**
@@ -50,6 +49,7 @@ import javax.xml.namespace.QName;
public class XWPFDocument extends POIXMLDocument {
private CTDocument1 ctDocument;
+ private XWPFSettings settings;
protected List<XWPFComment> comments;
protected List<XWPFHyperlink> hyperlinks;
protected List<XWPFParagraph> paragraphs;
@@ -107,7 +107,8 @@ public class XWPFDocument extends POIXMLDocument {
}
// Sort out headers and footers
- headerFooterPolicy = new XWPFHeaderFooterPolicy(this);
+ if (doc.getDocument().getBody().getSectPr() != null)
+ headerFooterPolicy = new XWPFHeaderFooterPolicy(this);
for(POIXMLDocumentPart p : getRelations()){
String relation = p.getPackageRelationship().getRelationshipType();
@@ -117,6 +118,9 @@ public class XWPFDocument extends POIXMLDocument {
comments.add(new XWPFComment(ctcomment));
}
}
+ else if(relation.equals(XWPFRelation.SETTINGS.getRelation())){
+ settings = (XWPFSettings)p;
+ }
}
initHyperlinks();
@@ -191,6 +195,8 @@ public class XWPFDocument extends POIXMLDocument {
ctDocument = CTDocument1.Factory.newInstance();
ctDocument.addNewBody();
+
+ settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS, XWPFFactory.getInstance());
POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR);
@@ -390,4 +396,146 @@ public class XWPFDocument extends POIXMLDocument {
}
}
}
+
+ /**
+ * Verifies that the documentProtection tag in settings.xml file <br/>
+ * specifies that the protection is enforced (w:enforcement="1") <br/>
+ * and that the kind of protection is readOnly (w:edit="readOnly")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;readOnly&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ *
+ * @return true if documentProtection is enforced with option readOnly
+ */
+ public boolean isEnforcedReadonlyProtection() {
+ return settings.isEnforcedWith(STDocProtect.READ_ONLY);
+ }
+
+ /**
+ * Verifies that the documentProtection tag in settings.xml file <br/>
+ * specifies that the protection is enforced (w:enforcement="1") <br/>
+ * and that the kind of protection is forms (w:edit="forms")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;forms&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ *
+ * @return true if documentProtection is enforced with option forms
+ */
+ public boolean isEnforcedFillingFormsProtection() {
+ return settings.isEnforcedWith(STDocProtect.FORMS);
+ }
+
+ /**
+ * Verifies that the documentProtection tag in settings.xml file <br/>
+ * specifies that the protection is enforced (w:enforcement="1") <br/>
+ * and that the kind of protection is comments (w:edit="comments")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;comments&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ *
+ * @return true if documentProtection is enforced with option comments
+ */
+ public boolean isEnforcedCommentsProtection() {
+ return settings.isEnforcedWith(STDocProtect.COMMENTS);
+ }
+
+ /**
+ * Verifies that the documentProtection tag in settings.xml file <br/>
+ * specifies that the protection is enforced (w:enforcement="1") <br/>
+ * and that the kind of protection is trackedChanges (w:edit="trackedChanges")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;trackedChanges&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ *
+ * @return true if documentProtection is enforced with option trackedChanges
+ */
+ public boolean isEnforcedTrackedChangesProtection() {
+ return settings.isEnforcedWith(STDocProtect.TRACKED_CHANGES);
+ }
+
+ /**
+ * Enforces the readOnly protection.<br/>
+ * In the documentProtection tag inside settings.xml file, <br/>
+ * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
+ * and the value of edit to readOnly (w:edit="readOnly")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;readOnly&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ */
+ public void enforceReadonlyProtection() {
+ settings.setEnforcementEditValue(STDocProtect.READ_ONLY);
+ }
+
+ /**
+ * Enforce the Filling Forms protection.<br/>
+ * In the documentProtection tag inside settings.xml file, <br/>
+ * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
+ * and the value of edit to forms (w:edit="forms")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;forms&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ */
+ public void enforceFillingFormsProtection() {
+ settings.setEnforcementEditValue(STDocProtect.FORMS);
+ }
+
+ /**
+ * Enforce the Comments protection.<br/>
+ * In the documentProtection tag inside settings.xml file,<br/>
+ * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
+ * and the value of edit to comments (w:edit="comments")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;comments&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ */
+ public void enforceCommentsProtection() {
+ settings.setEnforcementEditValue(STDocProtect.COMMENTS);
+ }
+
+ /**
+ * Enforce the Tracked Changes protection.<br/>
+ * In the documentProtection tag inside settings.xml file, <br/>
+ * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
+ * and the value of edit to trackedChanges (w:edit="trackedChanges")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;trackedChanges&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ */
+ public void enforceTrackedChangesProtection() {
+ settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES);
+ }
+
+ /**
+ * Remove protection enforcement.<br/>
+ * In the documentProtection tag inside settings.xml file <br/>
+ * it sets the value of enforcement to "0" (w:enforcement="0") <br/>
+ */
+ public void removeProtectionEnforcement() {
+ settings.removeEnforcement();
+ }
+
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
index 13c12c61be..c5accb89f9 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
@@ -68,7 +68,7 @@ public final class XWPFRelation extends POIXMLRelation {
"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
"/word/settings.xml",
- null
+ XWPFSettings.class
);
public static final XWPFRelation STYLES = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java
new file mode 100644
index 0000000000..e34d6c145c
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java
@@ -0,0 +1,135 @@
+/* ====================================================================
+ 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.xwpf.usermodel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocProtect;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSettings;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.SettingsDocument;
+
+public class XWPFSettings extends POIXMLDocumentPart {
+
+ private CTSettings ctSettings;
+
+ public XWPFSettings(PackagePart part, PackageRelationship rel) throws IOException {
+ super(part, rel);
+ readFrom(part.getInputStream());
+ }
+
+ public XWPFSettings() {
+ super();
+ ctSettings = CTSettings.Factory.newInstance();
+ }
+
+
+ /**
+ * Verifies the documentProtection tag inside settings.xml file <br/>
+ * if the protection is enforced (w:enforcement="1") <br/>
+ * and if the kind of protection equals to passed (STDocProtect.Enum editValue) <br/>
+ *
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;readOnly&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ *
+ * @return true if documentProtection is enforced with option readOnly
+ */
+ public boolean isEnforcedWith(STDocProtect.Enum editValue) {
+ CTDocProtect ctDocProtect = ctSettings.getDocumentProtection();
+
+ if (ctDocProtect == null) {
+ return false;
+ }
+
+ return ctDocProtect.getEnforcement().equals(STOnOff.X_1) && ctDocProtect.getEdit().equals(editValue);
+ }
+
+ /**
+ * Enforces the protection with the option specified by passed editValue.<br/>
+ * <br/>
+ * In the documentProtection tag inside settings.xml file <br/>
+ * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
+ * and the value of edit to the passed editValue (w:edit="[passed editValue]")<br/>
+ * <br/>
+ * sample snippet from settings.xml
+ * <pre>
+ * &lt;w:settings ... &gt;
+ * &lt;w:documentProtection w:edit=&quot;[passed editValue]&quot; w:enforcement=&quot;1&quot;/&gt;
+ * </pre>
+ */
+ public void setEnforcementEditValue(org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect.Enum editValue) {
+ safeGetDocumentProtection().setEnforcement(STOnOff.X_1);
+ safeGetDocumentProtection().setEdit(editValue);
+ }
+
+ /**
+ * Removes protection enforcement.<br/>
+ * In the documentProtection tag inside settings.xml file <br/>
+ * it sets the value of enforcement to "0" (w:enforcement="0") <br/>
+ */
+ public void removeEnforcement() {
+ safeGetDocumentProtection().setEnforcement(STOnOff.X_0);
+ }
+
+ @Override
+ protected void commit() throws IOException {
+
+ XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+ xmlOptions.setSaveSyntheticDocumentElement(new QName(CTSettings.type.getName().getNamespaceURI(), "settings"));
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+ xmlOptions.setSaveSuggestedPrefixes(map);
+
+ PackagePart part = getPackagePart();
+ OutputStream out = part.getOutputStream();
+ ctSettings.save(out, xmlOptions);
+ out.close();
+ }
+
+ private CTDocProtect safeGetDocumentProtection() {
+ CTDocProtect documentProtection = ctSettings.getDocumentProtection();
+ if (documentProtection == null) {
+ documentProtection = CTDocProtect.Factory.newInstance();
+ ctSettings.setDocumentProtection(documentProtection);
+ }
+ return ctSettings.getDocumentProtection();
+ }
+
+ private void readFrom(InputStream inputStream) {
+ try {
+ ctSettings = SettingsDocument.Factory.parse(inputStream).getSettings();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java b/src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java
new file mode 100644
index 0000000000..156c0dec49
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java
@@ -0,0 +1,231 @@
+/* ====================================================================
+ 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.xssf;
+
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import junit.framework.TestCase;
+
+public class TestSheetProtection extends TestCase {
+ private XSSFSheet sheet;
+
+ @Override
+ protected void setUp() throws Exception {
+ XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("sheetProtection_not_protected.xlsx");
+ sheet = workbook.getSheetAt(0);
+ }
+
+ public void testShouldReadWorkbookProtection() throws Exception {
+ assertFalse(sheet.isAutoFilterLocked());
+ assertFalse(sheet.isDeleteColumnsLocked());
+ assertFalse(sheet.isDeleteRowsLocked());
+ assertFalse(sheet.isFormatCellsLocked());
+ assertFalse(sheet.isFormatColumnsLocked());
+ assertFalse(sheet.isFormatRowsLocked());
+ assertFalse(sheet.isInsertColumnsLocked());
+ assertFalse(sheet.isInsertHyperlinksLocked());
+ assertFalse(sheet.isInsertRowsLocked());
+ assertFalse(sheet.isPivotTablesLocked());
+ assertFalse(sheet.isSortLocked());
+ assertFalse(sheet.isObjectsLocked());
+ assertFalse(sheet.isScenariosLocked());
+ assertFalse(sheet.isSelectLockedCellsLocked());
+ assertFalse(sheet.isSelectUnlockedCellsLocked());
+ assertFalse(sheet.isSheetLocked());
+
+ sheet = XSSFTestDataSamples.openSampleWorkbook("sheetProtection_allLocked.xlsx").getSheetAt(0);
+
+ assertTrue(sheet.isAutoFilterLocked());
+ assertTrue(sheet.isDeleteColumnsLocked());
+ assertTrue(sheet.isDeleteRowsLocked());
+ assertTrue(sheet.isFormatCellsLocked());
+ assertTrue(sheet.isFormatColumnsLocked());
+ assertTrue(sheet.isFormatRowsLocked());
+ assertTrue(sheet.isInsertColumnsLocked());
+ assertTrue(sheet.isInsertHyperlinksLocked());
+ assertTrue(sheet.isInsertRowsLocked());
+ assertTrue(sheet.isPivotTablesLocked());
+ assertTrue(sheet.isSortLocked());
+ assertTrue(sheet.isObjectsLocked());
+ assertTrue(sheet.isScenariosLocked());
+ assertTrue(sheet.isSelectLockedCellsLocked());
+ assertTrue(sheet.isSelectUnlockedCellsLocked());
+ assertTrue(sheet.isSheetLocked());
+ }
+
+ public void testWriteAutoFilter() throws Exception {
+ assertFalse(sheet.isAutoFilterLocked());
+ sheet.lockAutoFilter();
+ assertFalse(sheet.isAutoFilterLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isAutoFilterLocked());
+ }
+
+ public void testWriteDeleteColumns() throws Exception {
+ assertFalse(sheet.isDeleteColumnsLocked());
+ sheet.lockDeleteColumns();
+ assertFalse(sheet.isDeleteColumnsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isDeleteColumnsLocked());
+ }
+
+ public void testWriteDeleteRows() throws Exception {
+ assertFalse(sheet.isDeleteRowsLocked());
+ sheet.lockDeleteRows();
+ assertFalse(sheet.isDeleteRowsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isDeleteRowsLocked());
+ }
+
+ public void testWriteFormatCells() throws Exception {
+ assertFalse(sheet.isFormatCellsLocked());
+ sheet.lockFormatCells();
+ assertFalse(sheet.isFormatCellsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isFormatCellsLocked());
+ }
+
+ public void testWriteFormatColumns() throws Exception {
+ assertFalse(sheet.isFormatColumnsLocked());
+ sheet.lockFormatColumns();
+ assertFalse(sheet.isFormatColumnsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isFormatColumnsLocked());
+ }
+
+ public void testWriteFormatRows() throws Exception {
+ assertFalse(sheet.isFormatRowsLocked());
+ sheet.lockFormatRows();
+ assertFalse(sheet.isFormatRowsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isFormatRowsLocked());
+ }
+
+ public void testWriteInsertColumns() throws Exception {
+ assertFalse(sheet.isInsertColumnsLocked());
+ sheet.lockInsertColumns();
+ assertFalse(sheet.isInsertColumnsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isInsertColumnsLocked());
+ }
+
+ public void testWriteInsertHyperlinks() throws Exception {
+ assertFalse(sheet.isInsertHyperlinksLocked());
+ sheet.lockInsertHyperlinks();
+ assertFalse(sheet.isInsertHyperlinksLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isInsertHyperlinksLocked());
+ }
+
+ public void testWriteInsertRows() throws Exception {
+ assertFalse(sheet.isInsertRowsLocked());
+ sheet.lockInsertRows();
+ assertFalse(sheet.isInsertRowsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isInsertRowsLocked());
+ }
+
+ public void testWritePivotTables() throws Exception {
+ assertFalse(sheet.isPivotTablesLocked());
+ sheet.lockPivotTables();
+ assertFalse(sheet.isPivotTablesLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isPivotTablesLocked());
+ }
+
+ public void testWriteSort() throws Exception {
+ assertFalse(sheet.isSortLocked());
+ sheet.lockSort();
+ assertFalse(sheet.isSortLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isSortLocked());
+ }
+
+ public void testWriteObjects() throws Exception {
+ assertFalse(sheet.isObjectsLocked());
+ sheet.lockObjects();
+ assertFalse(sheet.isObjectsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isObjectsLocked());
+ }
+
+ public void testWriteScenarios() throws Exception {
+ assertFalse(sheet.isScenariosLocked());
+ sheet.lockScenarios();
+ assertFalse(sheet.isScenariosLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isScenariosLocked());
+ }
+
+ public void testWriteSelectLockedCells() throws Exception {
+ assertFalse(sheet.isSelectLockedCellsLocked());
+ sheet.lockSelectLockedCells();
+ assertFalse(sheet.isSelectLockedCellsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isSelectLockedCellsLocked());
+ }
+
+ public void testWriteSelectUnlockedCells() throws Exception {
+ assertFalse(sheet.isSelectUnlockedCellsLocked());
+ sheet.lockSelectUnlockedCells();
+ assertFalse(sheet.isSelectUnlockedCellsLocked());
+ sheet.enableLocking();
+ assertTrue(sheet.isSelectUnlockedCellsLocked());
+ }
+
+ public void testWriteSelectEnableLocking() throws Exception {
+ sheet = XSSFTestDataSamples.openSampleWorkbook("sheetProtection_allLocked.xlsx").getSheetAt(0);
+
+ assertTrue(sheet.isAutoFilterLocked());
+ assertTrue(sheet.isDeleteColumnsLocked());
+ assertTrue(sheet.isDeleteRowsLocked());
+ assertTrue(sheet.isFormatCellsLocked());
+ assertTrue(sheet.isFormatColumnsLocked());
+ assertTrue(sheet.isFormatRowsLocked());
+ assertTrue(sheet.isInsertColumnsLocked());
+ assertTrue(sheet.isInsertHyperlinksLocked());
+ assertTrue(sheet.isInsertRowsLocked());
+ assertTrue(sheet.isPivotTablesLocked());
+ assertTrue(sheet.isSortLocked());
+ assertTrue(sheet.isObjectsLocked());
+ assertTrue(sheet.isScenariosLocked());
+ assertTrue(sheet.isSelectLockedCellsLocked());
+ assertTrue(sheet.isSelectUnlockedCellsLocked());
+ assertTrue(sheet.isSheetLocked());
+
+ sheet.disableLocking();
+
+ assertFalse(sheet.isAutoFilterLocked());
+ assertFalse(sheet.isDeleteColumnsLocked());
+ assertFalse(sheet.isDeleteRowsLocked());
+ assertFalse(sheet.isFormatCellsLocked());
+ assertFalse(sheet.isFormatColumnsLocked());
+ assertFalse(sheet.isFormatRowsLocked());
+ assertFalse(sheet.isInsertColumnsLocked());
+ assertFalse(sheet.isInsertHyperlinksLocked());
+ assertFalse(sheet.isInsertRowsLocked());
+ assertFalse(sheet.isPivotTablesLocked());
+ assertFalse(sheet.isSortLocked());
+ assertFalse(sheet.isObjectsLocked());
+ assertFalse(sheet.isScenariosLocked());
+ assertFalse(sheet.isSelectLockedCellsLocked());
+ assertFalse(sheet.isSelectUnlockedCellsLocked());
+ assertFalse(sheet.isSheetLocked());
+ }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java b/src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java
new file mode 100644
index 0000000000..fc8c159e53
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java
@@ -0,0 +1,109 @@
+/* ====================================================================
+ 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.xssf;
+
+import java.io.File;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+public class TestWorkbookProtection extends TestCase {
+
+ public void testShouldReadWorkbookProtection() throws Exception {
+ XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_not_protected.xlsx");
+ assertFalse(workbook.isStructureLocked());
+ assertFalse(workbook.isWindowsLocked());
+ assertFalse(workbook.isRevisionLocked());
+
+ workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_workbook_structure_protected.xlsx");
+ assertTrue(workbook.isStructureLocked());
+ assertFalse(workbook.isWindowsLocked());
+ assertFalse(workbook.isRevisionLocked());
+
+ workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_workbook_windows_protected.xlsx");
+ assertTrue(workbook.isWindowsLocked());
+ assertFalse(workbook.isStructureLocked());
+ assertFalse(workbook.isRevisionLocked());
+
+ workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_workbook_revision_protected.xlsx");
+ assertTrue(workbook.isRevisionLocked());
+ assertFalse(workbook.isWindowsLocked());
+ assertFalse(workbook.isStructureLocked());
+ }
+
+ public void testShouldWriteStructureLock() throws Exception {
+ XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_not_protected.xlsx");
+ assertFalse(workbook.isStructureLocked());
+
+ workbook.lockStructure();
+
+ assertTrue(workbook.isStructureLocked());
+
+ workbook.unLockStructure();
+
+ assertFalse(workbook.isStructureLocked());
+ }
+
+ public void testShouldWriteWindowsLock() throws Exception {
+ XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_not_protected.xlsx");
+ assertFalse(workbook.isWindowsLocked());
+
+ workbook.lockWindows();
+
+ assertTrue(workbook.isWindowsLocked());
+
+ workbook.unLockWindows();
+
+ assertFalse(workbook.isWindowsLocked());
+ }
+
+ public void testShouldWriteRevisionLock() throws Exception {
+ XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_not_protected.xlsx");
+ assertFalse(workbook.isRevisionLocked());
+
+ workbook.lockRevision();
+
+ assertTrue(workbook.isRevisionLocked());
+
+ workbook.unLockRevision();
+
+ assertFalse(workbook.isRevisionLocked());
+ }
+
+ public void testIntegration() throws Exception {
+ XSSFWorkbook wb = new XSSFWorkbook();
+ wb.createSheet("Testing purpose sheet");
+ assertFalse(wb.isRevisionLocked());
+
+ wb.lockRevision();
+
+ File tempFile = File.createTempFile("workbookProtection", ".xlsx");
+ FileOutputStream out = new FileOutputStream(tempFile);
+ wb.write(out);
+ out.close();
+
+ FileInputStream inputStream = new FileInputStream(tempFile);
+ XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
+ inputStream.close();
+
+ assertTrue(workbook.isRevisionLocked());
+ }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/TestDocumentProtection.java b/src/ooxml/testcases/org/apache/poi/xwpf/TestDocumentProtection.java
new file mode 100644
index 0000000000..10f0e4818f
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/TestDocumentProtection.java
@@ -0,0 +1,153 @@
+/* ====================================================================
+ 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.xwpf;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+
+public class TestDocumentProtection extends TestCase {
+
+ public void testShouldReadEnforcementProperties() throws Exception {
+
+ XWPFDocument documentWithoutDocumentProtectionTag = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection.docx");
+ assertFalse(documentWithoutDocumentProtectionTag.isEnforcedReadonlyProtection());
+ assertFalse(documentWithoutDocumentProtectionTag.isEnforcedFillingFormsProtection());
+ assertFalse(documentWithoutDocumentProtectionTag.isEnforcedCommentsProtection());
+ assertFalse(documentWithoutDocumentProtectionTag.isEnforcedTrackedChangesProtection());
+
+ XWPFDocument documentWithoutEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection_tag_existing.docx");
+ assertFalse(documentWithoutEnforcement.isEnforcedReadonlyProtection());
+ assertFalse(documentWithoutEnforcement.isEnforcedFillingFormsProtection());
+ assertFalse(documentWithoutEnforcement.isEnforcedCommentsProtection());
+ assertFalse(documentWithoutEnforcement.isEnforcedTrackedChangesProtection());
+
+ XWPFDocument documentWithReadonlyEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_readonly_no_password.docx");
+ assertTrue(documentWithReadonlyEnforcement.isEnforcedReadonlyProtection());
+ assertFalse(documentWithReadonlyEnforcement.isEnforcedFillingFormsProtection());
+ assertFalse(documentWithReadonlyEnforcement.isEnforcedCommentsProtection());
+ assertFalse(documentWithReadonlyEnforcement.isEnforcedTrackedChangesProtection());
+
+ XWPFDocument documentWithFillingFormsEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_forms_no_password.docx");
+ assertTrue(documentWithFillingFormsEnforcement.isEnforcedFillingFormsProtection());
+ assertFalse(documentWithFillingFormsEnforcement.isEnforcedReadonlyProtection());
+ assertFalse(documentWithFillingFormsEnforcement.isEnforcedCommentsProtection());
+ assertFalse(documentWithFillingFormsEnforcement.isEnforcedTrackedChangesProtection());
+
+ XWPFDocument documentWithCommentsEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_comments_no_password.docx");
+ assertFalse(documentWithCommentsEnforcement.isEnforcedFillingFormsProtection());
+ assertFalse(documentWithCommentsEnforcement.isEnforcedReadonlyProtection());
+ assertTrue(documentWithCommentsEnforcement.isEnforcedCommentsProtection());
+ assertFalse(documentWithCommentsEnforcement.isEnforcedTrackedChangesProtection());
+
+ XWPFDocument documentWithTrackedChangesEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_trackedChanges_no_password.docx");
+ assertFalse(documentWithTrackedChangesEnforcement.isEnforcedFillingFormsProtection());
+ assertFalse(documentWithTrackedChangesEnforcement.isEnforcedReadonlyProtection());
+ assertFalse(documentWithTrackedChangesEnforcement.isEnforcedCommentsProtection());
+ assertTrue(documentWithTrackedChangesEnforcement.isEnforcedTrackedChangesProtection());
+
+ }
+
+ public void testShouldEnforceForReadOnly() throws Exception {
+ // XWPFDocument document = createDocumentFromSampleFile("test-data/document/documentProtection_no_protection.docx");
+ XWPFDocument document = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection.docx");
+ assertFalse(document.isEnforcedReadonlyProtection());
+
+ document.enforceReadonlyProtection();
+
+ assertTrue(document.isEnforcedReadonlyProtection());
+ }
+
+ public void testShouldEnforceForFillingForms() throws Exception {
+ XWPFDocument document = createDocumentFromSampleFile("test-data/document/documentProtection_no_protection.docx");
+ assertFalse(document.isEnforcedFillingFormsProtection());
+
+ document.enforceFillingFormsProtection();
+
+ assertTrue(document.isEnforcedFillingFormsProtection());
+ }
+
+ public void testShouldEnforceForComments() throws Exception {
+ XWPFDocument document = createDocumentFromSampleFile("test-data/document/documentProtection_no_protection.docx");
+ assertFalse(document.isEnforcedCommentsProtection());
+
+ document.enforceCommentsProtection();
+
+ assertTrue(document.isEnforcedCommentsProtection());
+ }
+
+ public void testShouldEnforceForTrackedChanges() throws Exception {
+ XWPFDocument document = createDocumentFromSampleFile("test-data/document/documentProtection_no_protection.docx");
+ assertFalse(document.isEnforcedTrackedChangesProtection());
+
+ document.enforceTrackedChangesProtection();
+
+ assertTrue(document.isEnforcedTrackedChangesProtection());
+ }
+
+ public void testShouldUnsetEnforcement() throws Exception {
+ XWPFDocument document = createDocumentFromSampleFile("test-data/document/documentProtection_readonly_no_password.docx");
+ assertTrue(document.isEnforcedReadonlyProtection());
+
+ document.removeProtectionEnforcement();
+
+ assertFalse(document.isEnforcedReadonlyProtection());
+ }
+
+ public void testIntegration() throws Exception {
+ XWPFDocument doc = new XWPFDocument();
+
+ XWPFParagraph p1 = doc.createParagraph();
+
+ XWPFRun r1 = p1.createRun();
+ r1.setText("Lorem ipsum dolor sit amet.");
+ doc.enforceCommentsProtection();
+
+ File tempFile = File.createTempFile("documentProtectionFile", ".docx");
+ FileOutputStream out = new FileOutputStream(tempFile);
+
+ doc.write(out);
+ out.close();
+
+ FileInputStream inputStream = new FileInputStream(tempFile);
+ XWPFDocument document = new XWPFDocument(inputStream);
+ inputStream.close();
+
+ assertTrue(document.isEnforcedCommentsProtection());
+ }
+
+ private XWPFDocument createDocumentFromSampleFile(String fileName) throws FileNotFoundException, IOException {
+ File file = new File(fileName);
+ FileInputStream in = new FileInputStream(file);
+ byte[] bytes = new byte[(int) file.length()];
+ in.read(bytes);
+
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ XWPFDocument document = new XWPFDocument(inputStream);
+ return document;
+ }
+
+}
diff --git a/test-data/document/documentProtection_comments_no_password.docx b/test-data/document/documentProtection_comments_no_password.docx
new file mode 100644
index 0000000000..5cc800e361
--- /dev/null
+++ b/test-data/document/documentProtection_comments_no_password.docx
Binary files differ
diff --git a/test-data/document/documentProtection_forms_no_password.docx b/test-data/document/documentProtection_forms_no_password.docx
new file mode 100644
index 0000000000..8d31026b40
--- /dev/null
+++ b/test-data/document/documentProtection_forms_no_password.docx
Binary files differ
diff --git a/test-data/document/documentProtection_no_protection.docx b/test-data/document/documentProtection_no_protection.docx
new file mode 100644
index 0000000000..fc1089e396
--- /dev/null
+++ b/test-data/document/documentProtection_no_protection.docx
Binary files differ
diff --git a/test-data/document/documentProtection_no_protection_tag_existing.docx b/test-data/document/documentProtection_no_protection_tag_existing.docx
new file mode 100644
index 0000000000..2c655b6b1b
--- /dev/null
+++ b/test-data/document/documentProtection_no_protection_tag_existing.docx
Binary files differ
diff --git a/test-data/document/documentProtection_readonly_no_password.docx b/test-data/document/documentProtection_readonly_no_password.docx
new file mode 100644
index 0000000000..1ec7063ab5
--- /dev/null
+++ b/test-data/document/documentProtection_readonly_no_password.docx
Binary files differ
diff --git a/test-data/document/documentProtection_trackedChanges_no_password.docx b/test-data/document/documentProtection_trackedChanges_no_password.docx
new file mode 100644
index 0000000000..8531573c07
--- /dev/null
+++ b/test-data/document/documentProtection_trackedChanges_no_password.docx
Binary files differ
diff --git a/test-data/document/protected_sample.docx b/test-data/document/protected_sample.docx
new file mode 100644
index 0000000000..e6b5e0bfce
--- /dev/null
+++ b/test-data/document/protected_sample.docx
Binary files differ
diff --git a/test-data/spreadsheet/sheetProtection_allLocked.xlsx b/test-data/spreadsheet/sheetProtection_allLocked.xlsx
new file mode 100644
index 0000000000..8afd70acaf
--- /dev/null
+++ b/test-data/spreadsheet/sheetProtection_allLocked.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/sheetProtection_not_protected.xlsx b/test-data/spreadsheet/sheetProtection_not_protected.xlsx
new file mode 100644
index 0000000000..81a0b5ea7a
--- /dev/null
+++ b/test-data/spreadsheet/sheetProtection_not_protected.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/workbookProtection_not_protected.xlsx b/test-data/spreadsheet/workbookProtection_not_protected.xlsx
new file mode 100644
index 0000000000..81a0b5ea7a
--- /dev/null
+++ b/test-data/spreadsheet/workbookProtection_not_protected.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/workbookProtection_workbook_revision_protected.xlsx b/test-data/spreadsheet/workbookProtection_workbook_revision_protected.xlsx
new file mode 100644
index 0000000000..d3d5d9e28c
--- /dev/null
+++ b/test-data/spreadsheet/workbookProtection_workbook_revision_protected.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/workbookProtection_workbook_structure_protected.xlsx b/test-data/spreadsheet/workbookProtection_workbook_structure_protected.xlsx
new file mode 100644
index 0000000000..88d8344704
--- /dev/null
+++ b/test-data/spreadsheet/workbookProtection_workbook_structure_protected.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/workbookProtection_workbook_windows_protected.xlsx b/test-data/spreadsheet/workbookProtection_workbook_windows_protected.xlsx
new file mode 100644
index 0000000000..6b3057f221
--- /dev/null
+++ b/test-data/spreadsheet/workbookProtection_workbook_windows_protected.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/workbookProtection_worksheet_protected.xlsx b/test-data/spreadsheet/workbookProtection_worksheet_protected.xlsx
new file mode 100644
index 0000000000..f9339f0ae8
--- /dev/null
+++ b/test-data/spreadsheet/workbookProtection_worksheet_protected.xlsx
Binary files differ