[SYSTEMDS-2668] Modified Privacy Monitor for Fine-Grained Constraints

Closes #1120.
diff --git a/src/main/java/org/apache/sysds/runtime/privacy/PrivacyMonitor.java b/src/main/java/org/apache/sysds/runtime/privacy/PrivacyMonitor.java
index 97ac22b..56445e4 100644
--- a/src/main/java/org/apache/sysds/runtime/privacy/PrivacyMonitor.java
+++ b/src/main/java/org/apache/sysds/runtime/privacy/PrivacyMonitor.java
@@ -25,10 +25,12 @@
 import org.apache.sysds.runtime.instructions.cp.Data;
 import org.apache.sysds.runtime.privacy.PrivacyConstraint.PrivacyLevel;
 
-public class PrivacyMonitor 
-{ 
+public class PrivacyMonitor
+{
 	private static EnumMap<PrivacyLevel,LongAdder> checkedConstraints;
 
+	private static boolean checkPrivacy = false;
+
 	static {
 		checkedConstraints = new EnumMap<>(PrivacyLevel.class);
 		for ( PrivacyLevel level : PrivacyLevel.values() ){
@@ -36,19 +38,37 @@
 		}
 	}
 
-	private static boolean checkPrivacy = false;
-
-	public static EnumMap<PrivacyLevel,LongAdder> getCheckedConstraints(){
+	public static EnumMap<PrivacyLevel,LongAdder> getCheckedConstraints() {
 		return checkedConstraints;
 	}
 
-	private static void incrementCheckedConstraints(PrivacyLevel privacyLevel){
+	private static void incrementCheckedConstraints(PrivacyLevel privacyLevel) {
+		if ( privacyLevel == null )
+			throw new NullPointerException("Cannot increment checked constraints log: Privacy level is null.");
+		checkedConstraints.get(privacyLevel).increment();
+	}
+
+	/**
+	 * Update checked constraints log if checkPrivacy is activated.
+	 * The checked constraints log is updated with both the general 
+	 * privacy constraint and the fine-grained constraints.
+	 * 
+	 * @param privacyConstraint used for updating log
+	 */
+	private static void updateCheckedConstraintsLog(PrivacyConstraint privacyConstraint) {
 		if ( checkPrivacy ){
-			if ( privacyLevel == null )
-				throw new NullPointerException("Cannot increment checked constraints log: Privacy level is null.");
-			checkedConstraints.get(privacyLevel).increment();
+			if ( privacyConstraint.privacyLevel != PrivacyLevel.None){
+				incrementCheckedConstraints(privacyConstraint.privacyLevel);
+			}
+			if ( PrivacyUtils.privacyConstraintFineGrainedActivated(privacyConstraint) ){
+				int privateNum = privacyConstraint.getFineGrainedPrivacy()
+					.getDataRangesOfPrivacyLevel(PrivacyLevel.Private).length;
+				int aggregateNum = privacyConstraint.getFineGrainedPrivacy()
+					.getDataRangesOfPrivacyLevel(PrivacyLevel.PrivateAggregation).length;
+				checkedConstraints.get(PrivacyLevel.Private).add(privateNum);
+				checkedConstraints.get(PrivacyLevel.PrivateAggregation).add(aggregateNum);
+			}
 		}
-			
 	}
 
 	public static void clearCheckedConstraints(){
@@ -61,58 +81,20 @@
 
 	/**
 	 * Throws DMLPrivacyException if privacy constraint is set to private or private aggregation.
+	 * The checked constraints log will be updated before throwing an exception.
 	 * @param dataObject input data object
-	 * @return data object or data object with privacy constraint removed in case the privacy level was none. 
+	 * @return data object or data object with privacy constraint removed in case the privacy level was none.
 	 */
 	public static Data handlePrivacy(Data dataObject){
 		if(dataObject == null)
 			return null;
 		PrivacyConstraint privacyConstraint = dataObject.getPrivacyConstraint();
-		if (privacyConstraint != null){
-			PrivacyLevel privacyLevel = privacyConstraint.getPrivacyLevel();
-			incrementCheckedConstraints(privacyLevel);
-			switch(privacyLevel){
-				case None:
-					dataObject.setPrivacyConstraints(null);
-					break;
-				case Private:
-				case PrivateAggregation:
-					throw new DMLPrivacyException("Cannot share variable, since the privacy constraint "
-						+ "of the requested variable is set to " + privacyLevel.name());
-				default: {
-					throw new DMLPrivacyException("Privacy level " 
-						+ privacyLevel.name() + " of variable not recognized");
-				}
-			}
-		}
-		return dataObject;
-	}
 
-	/**
-	 * Throws DMLPrivacyException if privacy constraint of data object has level privacy.
-	 * @param dataObject input matrix object
-	 * @return data object or data object with privacy constraint removed in case the privacy level was none.
-	 */
-	public static Data handlePrivacyAllowAggregation(Data dataObject){
-		PrivacyConstraint privacyConstraint = dataObject.getPrivacyConstraint();
-		if (privacyConstraint != null){
-			PrivacyLevel privacyLevel = privacyConstraint.getPrivacyLevel();
-			incrementCheckedConstraints(privacyLevel);
-			switch(privacyLevel){
-				case None:
-					dataObject.setPrivacyConstraints(null);
-					break;
-				case Private:
-					throw new DMLPrivacyException("Cannot share variable, since the privacy constraint "
-						+ "of the requested variable is set to " + privacyLevel.name());
-				case PrivateAggregation:
-					break; 
-				default: {
-					throw new DMLPrivacyException("Privacy level " 
-						+ privacyLevel.name() + " of variable not recognized");
-				}
-			}
-		}
+		if ( PrivacyUtils.someConstraintSetUnary(privacyConstraint) ){
+			updateCheckedConstraintsLog(privacyConstraint);
+			throw new DMLPrivacyException("Cannot share variable, since the privacy constraint "
+				+ "of the requested variable is activated");
+		} else dataObject.setPrivacyConstraints(null);
 		return dataObject;
 	}
 }