Package ch.tatool.app.export

Source Code of ch.tatool.app.export.CSVTrialDataExport

/*******************************************************************************
* Copyright (c) 2011 Michael Ruflin, Andr� Locher, Claudia von Bastian.
*
* This file is part of Tatool.
*
* Tatool is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tatool is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Tatool. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package ch.tatool.app.export;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.com.bytecode.opencsv.CSVWriter;
import ch.tatool.app.Constants;
import ch.tatool.data.DataService;
import ch.tatool.data.Module;
import ch.tatool.data.ModuleSession;
import ch.tatool.data.Trial;
import ch.tatool.data.DataContainer.Entry;

/**
* Exports module data into a CSV file.
* This is a helper class used by the various exporters
*
* @author Michael Ruflin
*/
public class CSVTrialDataExport {

    Logger logger = LoggerFactory.getLogger(CSVTrialDataExport.class);
   
    private DataService dataService;
   
    private List<String> baseProperties;
    private int basePropertiesSize;
    private List<String> sessionProperties;
    private List<String> trialProperties;
    private int trialPropertiesSize;
    private boolean useTrialShortNames = false;
    private boolean useSessionShortNames = false;

  private char separator = ';';
   
    public CSVTrialDataExport(DataService dataService) {
        this.dataService = dataService;
    }
   
    /**
     * Exports the module data and stores the results in the provided Writer
     *
     * @param module
     * @param file the file to write the data to
     * @return a file containing the module data or null in case an error occured
     */
    public File exportData(Module module, int fromSessionIndex) {
       // this won't change
        initBaseProperties(module);
        // initialize the trial properties
        initTrialProperties(module);

        // create a writer
        try {
            File tmpFile = File.createTempFile("trialData", "csv");
            FileOutputStream fos = new FileOutputStream(tmpFile, false);
            CSVWriter writer = new CSVWriter(new OutputStreamWriter(fos,"ISO-8859-1"), separator);

            // write the csv file header
            List<String> headers = new ArrayList<String>(baseProperties);
           
            // try to use shorthand headers if unique
            HashSet<String> trialPropertiesShort = new HashSet<String>();
            for (String name : trialProperties) {
              String newName = "trial.";
              String[] nameParts = name.split("\\.");
              if (nameParts.length > 1) {
                newName += nameParts[nameParts.length - 2] + ".";
              }
              newName += nameParts[nameParts.length - 1];
              trialPropertiesShort.add(newName);
            }

            if (trialPropertiesShort.size() == trialProperties.size()) {
              useTrialShortNames = true;
              trialProperties.clear();
              trialProperties.addAll(trialPropertiesShort);
              Collections.sort(trialProperties, String.CASE_INSENSITIVE_ORDER);
              headers.addAll(trialProperties);
            } else {
              Collections.sort(trialProperties, String.CASE_INSENSITIVE_ORDER);
              headers.addAll(trialProperties);
            }

            writer.writeNext(headers.toArray(new String[headers.size()]));

            // fetch each session and trial, write one line for each trial
            List<ModuleSession> sessions = dataService.getSessions(module);
            for (ModuleSession session : sessions) {
                // skip if we only export some of the session
                if (fromSessionIndex >= 0 && session.getIndex() < fromSessionIndex) {
                    continue;
                }
               
                // export all trials for this session
                List<Trial> trials = dataService.getTrials(session);
                for (Trial trial : trials) {
                    List<String[]> trialData = getDataForTrial(session, trial);
                    writer.writeAll(trialData);
                }
            }
           
            // close the writer and return the file
            writer.close();
            return tmpFile;
        } catch (IOException ioe) {
            logger.error("Unable to write csv file", ioe);
            return null;
        }
    }
   
    /** Returns a list with all to be written values for a given trial object. */
    private List<String[]> getDataForTrial(ModuleSession session, Trial trial) {
        List<String[]> data = new ArrayList<String[]>(basePropertiesSize + trialPropertiesSize);

        // add trial properties
        addTrialProperties(session, trial, data);
       
        // done already
        return data;
    }
   
   
    // Base properties management
   
    /** Basic properties which are always written. */
    private void initBaseProperties(Module module) {
        baseProperties = new ArrayList<String>();
       
        // account related
        baseProperties.add("user.name");
        baseProperties.add("user." + Constants.PROPERTY_ACCOUNT_BIRTH);
        baseProperties.add("user." + Constants.PROPERTY_ACCOUNT_SEX);
        baseProperties.add("user." + Constants.PROPERTY_MACHINE_OS_NAME);
       
        // module related
        baseProperties.add("module.name");
        baseProperties.add("module.version");
       
        // tatool online related
        Map<String, String> moduleProperties = module.getModuleProperties();
        if (moduleProperties.containsKey("tatool.online.subject.code")) {
          baseProperties.add("module.online.subject.code");
        }
        if (moduleProperties.containsKey("tatool.online.study.id")) {
          baseProperties.add("module.online.study.id");
        }
        if (moduleProperties.containsKey("tatool.online.module.nr")) {
          baseProperties.add("module.online.module.nr");
        }
        if (moduleProperties.containsKey("tatool.online.group.nr")) {
          baseProperties.add("module.online.group.nr");
        }
       
        // session related
        baseProperties.add("session.id");
        baseProperties.add("session.index");
        baseProperties.add("session.startTime");
        baseProperties.add("session.endTime");
        baseProperties.add("session.completed");
        addSessionBaseProperties(module);
       
        // trial related
        baseProperties.add("trial.id");
        baseProperties.add("trial.index");
        baseProperties.add("trial.name");

        basePropertiesSize = baseProperties.size();       
    }
   
    private void addSessionBaseProperties(Module module) {
      sessionProperties = getAllSessionPropertyNames(module);
     
      // try to use shorthand headers if unique
        HashSet<String> sessionPropertiesShort = new HashSet<String>();
        for (String name : sessionProperties) {
          String newName = "session.";
          String[] nameParts = name.split("\\.");
          if (nameParts.length > 1) {
            newName += nameParts[nameParts.length - 2] + ".";
          }
          newName += nameParts[nameParts.length - 1];
          sessionPropertiesShort.add(newName);
        }

        if (sessionPropertiesShort.size() == sessionProperties.size()) {
          useSessionShortNames = true;
          sessionProperties.clear();
          sessionProperties.addAll(sessionPropertiesShort);
          Collections.sort(sessionProperties, String.CASE_INSENSITIVE_ORDER);
          baseProperties.addAll(sessionProperties)
        } else {
          Collections.sort(sessionProperties, String.CASE_INSENSITIVE_ORDER);
          baseProperties.addAll(sessionProperties)
        }
  }

  private String[] getBaseProperties(ModuleSession session, Trial trial) {

      ArrayList<String> baseProps = new ArrayList<String>();
     
       // account related
      baseProps.add(session.getModule().getUserAccount().getName());
     
      Map<String, String> accountProperties = session.getModule().getUserAccount().getProperties();
      baseProps.add(accountProperties.get(Constants.PROPERTY_ACCOUNT_BIRTH));
      baseProps.add(accountProperties.get(Constants.PROPERTY_ACCOUNT_SEX));
      baseProps.add(accountProperties.get(Constants.PROPERTY_MACHINE_OS_NAME));
       
      Map<String, String> moduleProperties = session.getModule().getModuleProperties();
     
      // module related
      baseProps.add(session.getModule().getName());
      if (!moduleProperties.get(Module.PROPERTY_MODULE_VERSION).equals(null)) {
        baseProps.add(moduleProperties.get(Module.PROPERTY_MODULE_VERSION));
      } else {
        baseProps.add("");
      }
     
     
      // tatool online related
        if (moduleProperties.containsKey("tatool.online.subject.code")) {
          baseProps.add(moduleProperties.get("tatool.online.subject.code"));
        }
        if (moduleProperties.containsKey("tatool.online.study.id")) {
          baseProps.add(moduleProperties.get("tatool.online.study.id"));
        }
        if (moduleProperties.containsKey("tatool.online.module.nr")) {
          baseProps.add(moduleProperties.get("tatool.online.module.nr"));
        }
        if (moduleProperties.containsKey("tatool.online.group.nr")) {
          baseProps.add(moduleProperties.get("tatool.online.group.nr"));
        }
       
        // session related
      baseProps.add(session.getId().toString());
      baseProps.add(session.getIndex() + "");
       
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
       
        StringBuilder sessionStartTime = new StringBuilder("");
        StringBuilder sessionEndTime = new StringBuilder("");
        if (session.getStartTime() != null) {
          sessionStartTime = new StringBuilder(dateformat.format(session.getStartTime()));
        }
        if (session.getEndTime() != null) {
          sessionEndTime = new StringBuilder(dateformat.format(session.getEndTime()));
        }
        baseProps.add(sessionStartTime.toString());
        baseProps.add(sessionEndTime.toString());
       
        baseProps.add(String.valueOf(session.getCompleted()));

      // copy all session properties to a helper map, will greatly simplify chosing the correct value
        Map<String, String> propertyValues = new HashMap<String, String>();
        for (Entry p : session.getEntries()) {
          if (useSessionShortNames) {
            String newName = "session.";
              String[] nameParts = p.getNodeId().split("\\.");
              if (nameParts.length > 0) {
                newName += nameParts[nameParts.length - 1] + ".";
              }
              newName += p.getName();
              propertyValues.put(newName, p.getValue());
          } else {
            propertyValues.put(p.getNodeId() + "." + p.getName(), p.getValue());
          }
        }
       
        // now add all session property values
        for (String name : sessionProperties) {
            // null is handled by addToData
          baseProps.add(propertyValues.get(name));
        }
        // trial data
        baseProps.add(trial.getId().toString()); //id
        baseProps.add(trial.getIndex() + ""); //index
        baseProps.add(trial.getParentId()); //nodeid
   
        return baseProps.toArray(new String[basePropertiesSize]);
    }

  private void addToData(List<String[]> data, String[] values) {
        if (values != null) {
            data.add(values);
        }
    }

    // Trial properties management

    private void initTrialProperties(Module module) {
        // find the names of the additional trial properties to print out
        trialProperties = getAllTrialPropertyNames(module);
        trialPropertiesSize = trialProperties.size();  
    }
   
    /**
     * Returns a list of all existing module property names,
     * with the item name and property name separated by a point.
     */
    private List<String> getAllTrialPropertyNames(Module module) {
        List<Object[]> trialProperties = dataService.findDistinctTrialPropertyNames(module);
        List<String> props = new ArrayList<String>();
        for (Object[] o : trialProperties) {
            StringBuilder sb = new StringBuilder();
            for (int x=0, len=o.length; x < len; x++) {
                if (x > 0) {
                    sb.append('.');
                }
                sb.append(o[x]);
            }
            props.add(sb.toString());
        }
        return props;
    }
   
    /**
     * Returns a list of all existing session property names,
     * with the item name and property name separated by a point.
     */
    private List<String> getAllSessionPropertyNames(Module module) {
        List<Object[]> sessionProperties = dataService.findDistinctSessionPropertyNames(module);
        List<String> props = new ArrayList<String>();
        for (Object[] o : sessionProperties) {
            StringBuilder sb = new StringBuilder();
            for (int x=0, len=o.length; x < len; x++) {
                if (x > 0) {
                    sb.append('.');
                }
                sb.append(o[x]);
            }
            props.add(sb.toString());
        }
        return props;
    }

    /**
     * Adds the trial properties to the data object
     */
    private void addTrialProperties(ModuleSession session, Trial trial, List<String[]> data) {
      List<String> trialProps = null;
      trialProps = new ArrayList<String>();
      trialProps.addAll(Arrays.asList(getBaseProperties(session, trial)));

        // copy all trial properties to a helper map, will greatly simplify chosing the correct value
        Map<String, String> propertyValues = new HashMap<String, String>();
        for (Entry p : trial.getEntries()) {
          if (useTrialShortNames) {
            String newName = "trial.";
              String[] nameParts = p.getNodeId().split("\\.");
              if (nameParts.length > 0) {
                newName += nameParts[nameParts.length - 1] + ".";
              }
              newName += p.getName();
              propertyValues.put(newName, p.getValue());
          } else {
            propertyValues.put(p.getNodeId() + "." + p.getName(), p.getValue());
          }
        }
       
        // now write all properties, using "" where non-existent
        for (String name : trialProperties) {
            // null is handled by addToData
          trialProps.add(propertyValues.get(name));
        }
       
        addToData(data, trialProps.toArray(new String[trialProps.size()]));
    }
   
    public void setCSVParameters(char separator) {
      this.separator = separator;
    }
}
TOP

Related Classes of ch.tatool.app.export.CSVTrialDataExport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.