/*
 * ARX: Powerful Data Anonymization
 * Copyright 2012 - 2016 Fabian Prasser, Florian Kohlmayer and contributors
 * 
 * Licensed 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.deidentifier.arx.examples;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.deidentifier.arx.ARXAnonymizer;
import org.deidentifier.arx.ARXConfiguration;
import org.deidentifier.arx.ARXResult;
import org.deidentifier.arx.AttributeType.Hierarchy;
import org.deidentifier.arx.AttributeType.MicroAggregationFunction;
import org.deidentifier.arx.Data;
import org.deidentifier.arx.DataType;
import org.deidentifier.arx.aggregates.StatisticsQuality;
import org.deidentifier.arx.criteria.KAnonymity;
import org.deidentifier.arx.io.CSVHierarchyInput;
import org.deidentifier.arx.metric.Metric;

/**
 * This class implements an example on how to access quality statistics
 *
 * @author Fabian Prasser
 */
public class Example54 extends Example {
    
    /**
     * Loads a dataset from disk
     * @param dataset
     * @return
     * @throws IOException
     */
    public static Data createData(final String dataset) throws IOException {
        
        // Load data
        Data data = Data.create("data/" + dataset + ".csv", StandardCharsets.UTF_8, ';');
        
        // Read generalization hierarchies
        FilenameFilter hierarchyFilter = new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                if (name.matches(dataset + "_hierarchy_(.)+.csv")) {
                    return true;
                } else {
                    return false;
                }
            }
        };
        
        // Create definition
        File testDir = new File("data/");
        File[] genHierFiles = testDir.listFiles(hierarchyFilter);
        Pattern pattern = Pattern.compile("_hierarchy_(.*?).csv");
        for (File file : genHierFiles) {
            Matcher matcher = pattern.matcher(file.getName());
            if (matcher.find()) {
                CSVHierarchyInput hier = new CSVHierarchyInput(file, StandardCharsets.UTF_8, ';');
                String attributeName = matcher.group(1);
                data.getDefinition().setAttributeType(attributeName, Hierarchy.create(hier.getHierarchy()));
            }
        }
        
        return data;
    }
    
    /**
     * Entry point.
     * 
     * @param args the arguments
     * @throws ParseException
     * @throws IOException
     * @throws NoSuchAlgorithmException 
     */
    public static void main(String[] args) throws ParseException, IOException, NoSuchAlgorithmException {
        
        Data data = createData("adult");
        
        data.getDefinition().setDataType("age", DataType.INTEGER);
        data.getDefinition().setMicroAggregationFunction("age", MicroAggregationFunction.createArithmeticMean());
        
        ARXAnonymizer anonymizer = new ARXAnonymizer();
        ARXConfiguration config = ARXConfiguration.create();
        config.addPrivacyModel(new KAnonymity(5));
        config.setMaxOutliers(1d);
        config.setQualityModel(Metric.createLossMetric());
        
        ARXResult result = anonymizer.anonymize(data, config);
        System.out.println("Done");
        
        // Access statistics
        StatisticsQuality utility = result.getOutput().getStatistics().getQualityStatistics();
        System.out.println(" - Ambiguity: " + utility.getAmbiguity().getValue());
        System.out.println(" - AECS: " + utility.getAverageClassSize().getValue());
        System.out.println(" - Discernibility: " + utility.getDiscernibility().getValue());
        System.out.println(" - Granularity: " + utility.getGranularity().getArithmeticMean(false));
        System.out.println(" - KL-Divergence: " + utility.getKLDivergence().getValue());
        System.out.println(" - Non-Uniform Entropy: " + utility.getNonUniformEntropy().getArithmeticMean(false));
        System.out.println(" - Precision: " + utility.getPrecision().getArithmeticMean(false));
        System.out.println(" - SSE: " + utility.getSSE().getValue());
    }
}
@@ -1294,16 +1294,57 @@
 .Data;%0D%0A
+import org.deidentifier.arx.DataHandle;%0D%0A
 import o
@@ -1479,24 +1479,91 @@
 Anonymity;%0D%0A
+import org.deidentifier.arx.exceptions.RollbackRequiredException;%0D%0A
 import org.d
@@ -3414,16 +3414,59 @@
 ption %0D%0A
+     * @throws RollbackRequiredException %0D%0A
      */%0D
@@ -3561,32 +3561,59 @@
 gorithmException
+, RollbackRequiredException
  %7B%0D%0A        %0D%0A  
@@ -4117,21 +4117,23 @@
 sMetric(
+0d
 ));%0D%0A
-
         
@@ -4194,24 +4194,127 @@
 , config);%0D%0A
+        DataHandle output = result.getOutput();%0D%0A        result.optimizeIterativeFast(output, 0.01d);%0D%0A
         Syst
@@ -4414,34 +4414,22 @@
 ility = 
-result.getO
+o
 utput
-()
 .getStat

Update example