]> source.dussan.org Git - poi.git/commitdiff
[47942] added implementation of protection features to XLSX and DOCX files. Patch...
authorUgo Cei <ugo@apache.org>
Wed, 28 Oct 2009 16:05:39 +0000 (16:05 +0000)
committerUgo Cei <ugo@apache.org>
Wed, 28 Oct 2009 16:05:39 +0000 (16:05 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@830657 13f79535-47bb-0310-9956-ffa450edef68

23 files changed:
src/documentation/content/xdocs/status.xml
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xwpf/TestDocumentProtection.java [new file with mode: 0644]
test-data/document/documentProtection_comments_no_password.docx [new file with mode: 0644]
test-data/document/documentProtection_forms_no_password.docx [new file with mode: 0644]
test-data/document/documentProtection_no_protection.docx [new file with mode: 0644]
test-data/document/documentProtection_no_protection_tag_existing.docx [new file with mode: 0644]
test-data/document/documentProtection_readonly_no_password.docx [new file with mode: 0644]
test-data/document/documentProtection_trackedChanges_no_password.docx [new file with mode: 0644]
test-data/document/protected_sample.docx [new file with mode: 0644]
test-data/spreadsheet/sheetProtection_allLocked.xlsx [new file with mode: 0644]
test-data/spreadsheet/sheetProtection_not_protected.xlsx [new file with mode: 0644]
test-data/spreadsheet/workbookProtection_not_protected.xlsx [new file with mode: 0644]
test-data/spreadsheet/workbookProtection_workbook_revision_protected.xlsx [new file with mode: 0644]
test-data/spreadsheet/workbookProtection_workbook_structure_protected.xlsx [new file with mode: 0644]
test-data/spreadsheet/workbookProtection_workbook_windows_protected.xlsx [new file with mode: 0644]
test-data/spreadsheet/workbookProtection_worksheet_protected.xlsx [new file with mode: 0644]

index 76eafe8e2afca8553e0c0868777e2fd6b1427f39..209d8ae8d8432ec85ce92f570813a48b3ccf6c08 100644 (file)
         <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>
index b5a70286a218d2dffbad41999ec5242b53d28fae..76dfabc8e8b1b8ee9230c0367d01a5fe13b02e7e 100644 (file)
@@ -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();
+       }
 }
index 67d4f69bf02212180ac52bce8fbc92400b226e33..92eca642457283fcc314d6912a5db41712ce27cb 100644 (file)
@@ -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());
+               }
+       }
 }
index 19faaf00856ed177ed79534dc686914e8c236f86..ae1440b492a0576ff8ae015aeac7fc0776d66e8e 100644 (file)
@@ -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();
+    }
+
 }
index 13c12c61becef54226eb75025a341f4540063d89..c5accb89f9e0046274171b5931c8a3345ca9ae9f 100644 (file)
@@ -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 (file)
index 0000000..e34d6c1
--- /dev/null
@@ -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 (file)
index 0000000..156c0de
--- /dev/null
@@ -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 (file)
index 0000000..fc8c159
--- /dev/null
@@ -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 (file)
index 0000000..10f0e48
--- /dev/null
@@ -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 (file)
index 0000000..5cc800e
Binary files /dev/null and b/test-data/document/documentProtection_comments_no_password.docx 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 (file)
index 0000000..8d31026
Binary files /dev/null and b/test-data/document/documentProtection_forms_no_password.docx differ
diff --git a/test-data/document/documentProtection_no_protection.docx b/test-data/document/documentProtection_no_protection.docx
new file mode 100644 (file)
index 0000000..fc1089e
Binary files /dev/null and b/test-data/document/documentProtection_no_protection.docx 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 (file)
index 0000000..2c655b6
Binary files /dev/null and b/test-data/document/documentProtection_no_protection_tag_existing.docx 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 (file)
index 0000000..1ec7063
Binary files /dev/null and b/test-data/document/documentProtection_readonly_no_password.docx 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 (file)
index 0000000..8531573
Binary files /dev/null and b/test-data/document/documentProtection_trackedChanges_no_password.docx differ
diff --git a/test-data/document/protected_sample.docx b/test-data/document/protected_sample.docx
new file mode 100644 (file)
index 0000000..e6b5e0b
Binary files /dev/null and b/test-data/document/protected_sample.docx differ
diff --git a/test-data/spreadsheet/sheetProtection_allLocked.xlsx b/test-data/spreadsheet/sheetProtection_allLocked.xlsx
new file mode 100644 (file)
index 0000000..8afd70a
Binary files /dev/null and b/test-data/spreadsheet/sheetProtection_allLocked.xlsx differ
diff --git a/test-data/spreadsheet/sheetProtection_not_protected.xlsx b/test-data/spreadsheet/sheetProtection_not_protected.xlsx
new file mode 100644 (file)
index 0000000..81a0b5e
Binary files /dev/null and b/test-data/spreadsheet/sheetProtection_not_protected.xlsx differ
diff --git a/test-data/spreadsheet/workbookProtection_not_protected.xlsx b/test-data/spreadsheet/workbookProtection_not_protected.xlsx
new file mode 100644 (file)
index 0000000..81a0b5e
Binary files /dev/null and b/test-data/spreadsheet/workbookProtection_not_protected.xlsx 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 (file)
index 0000000..d3d5d9e
Binary files /dev/null and b/test-data/spreadsheet/workbookProtection_workbook_revision_protected.xlsx 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 (file)
index 0000000..88d8344
Binary files /dev/null and b/test-data/spreadsheet/workbookProtection_workbook_structure_protected.xlsx 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 (file)
index 0000000..6b3057f
Binary files /dev/null and b/test-data/spreadsheet/workbookProtection_workbook_windows_protected.xlsx differ
diff --git a/test-data/spreadsheet/workbookProtection_worksheet_protected.xlsx b/test-data/spreadsheet/workbookProtection_worksheet_protected.xlsx
new file mode 100644 (file)
index 0000000..f9339f0
Binary files /dev/null and b/test-data/spreadsheet/workbookProtection_worksheet_protected.xlsx differ