static public boolean hasDocumentBeenModified ( JSONObject targetDoc ) { JSONObject targetManifest = targetDoc . optJSONObject ( MANIFEST_KEY ) ; if ( null == targetManifest ) { // Can not verify digest on target document. Let's assume it has // been modified return true ; } String targetDigest = targetManifest . optString ( "digest" ) ; if ( null == targetDigest ) { // Can not verify digest on target document, let's assume it // has changed return true ; } // Check type DigestComputer digestComputer = null ; { String type = targetManifest . optString ( "type" ) ; if ( null == type ) { // Has been modified sine type is missing return true ; } else if ( DigestComputerSha1 . DIGEST_COMPUTER_TYPE . equals ( type ) ) { digestComputer = sha1DigestComputer ; } else { // Unrecognized type. Assume it was changed return true ; } } try { String computedDigest = digestComputer . computeDigestFromJsonObject ( targetDoc ) ; if ( false == computedDigest . equals ( targetDigest ) ) { // Digests are different. It was changed return true ; } } catch ( Exception e ) { // Error computing digest, let's assume it was changed return true ; } // Verify attachments by checking each attachment in manifest and verifying // each attachment has not changed Set < String > attachmentNamesInManifest = new HashSet < String > ( ) ; JSONObject targetAttachmentManifests = targetManifest . optJSONObject ( "attachments" ) ; if ( null != targetAttachmentManifests ) { Iterator < ? > it = targetAttachmentManifests . keys ( ) ; while ( it . hasNext ( ) ) { Object keyObj = it . next ( ) ; if ( keyObj instanceof String ) { String attachmentName = ( String ) keyObj ; attachmentNamesInManifest . add ( attachmentName ) ; JSONObject attachmentManifest = targetAttachmentManifests . optJSONObject ( attachmentName ) ; if ( null == attachmentManifest ) { // Error. Must have been changed return true ; } else if ( false == JSONSupport . containsKey ( attachmentManifest , "revpos" ) ) { // revpos is gone, document must have been modified return true ; } else { int revpos = attachmentManifest . optInt ( "revpos" , 0 ) ; Integer actualRevPos = getAttachmentPosition ( targetDoc , attachmentName ) ; if ( null == actualRevPos ) { // Attachment is gone return true ; } else if ( revpos != actualRevPos . intValue ( ) ) { // Attachment has changed return true ; } } } } } // Verify that each attachment has a manifest declared for it JSONObject targetAttachments = targetDoc . optJSONObject ( "_attachments" ) ; if ( null != targetAttachments ) { Iterator < ? > it = targetAttachments . keys ( ) ; while ( it . hasNext ( ) ) { Object keyObj = it . next ( ) ; if ( keyObj instanceof String ) { String attachmentName = ( String ) keyObj ; if ( false == attachmentNamesInManifest . contains ( attachmentName ) ) { // This attachment was added since manifest was computed return true ; } } } } // If we make it here, the document has not changed according to the manifest return false ; }
Analyzes a document and determines if the document has been modified since the time the manifest was computed .