Package eu.planets_project.pp.plato.services.characterisation.xcl

Source Code of eu.planets_project.pp.plato.services.characterisation.xcl.XCLComparator

/*******************************************************************************
* Copyright (c) 2006-2010 Vienna University of Technology,
* Department of Software Technology and Interactive Systems
*
* All rights reserved. This program and the accompanying
* materials are made available under the terms of the
* Apache License, Version 2.0 which accompanies
* this distribution, and is available at
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/
package eu.planets_project.pp.plato.services.characterisation.xcl;

import java.io.File;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;

import eu.planets_project.pp.plato.evaluation.MeasurementsDescriptor;
import eu.planets_project.pp.plato.model.scales.Scale;
import eu.planets_project.pp.plato.model.values.Value;
import eu.planets_project.pp.plato.services.PlatoServiceException;
import eu.planets_project.pp.plato.util.CommandExecutor;
import eu.planets_project.pp.plato.util.MeasurementInfoUri;
import eu.planets_project.pp.plato.util.OS;
import eu.planets_project.pp.plato.util.PlatoLogger;

/**
* XCL comparator, for XCLEvaluator
*
* The comparator is used as command line tool and not invoked through the Planets Service interface.
* This way we also get the values, and the compare results for all metrics. 
*
*
* @author Michael Kraxner
*
*/
public class XCLComparator {
   
    private Log log = PlatoLogger.getLogger(this.getClass());

    private String configParam;
    private String comparatorHome;
    private String extractorHome;

    private String name;
   
    /**
     * file = input file to extract
     * NOT NEEDED ANYMORE xcel = absolute path to XCEL
     * xcdl = absolute path to outputFILE
     *
     * It is not sufficient to set the working directory and call via "extract infile ...",
     * as linux requires a preceding "./", and windows does not accept this.
     * therefore we need to expand this command before execution.
     *
     */
    private String extractorCommand = "extractor -o %XCDL% %FILE%";
   
    /**
     * XCDL1 = xcdl of input object
     * XCDL2 = xcdl of result object
     * PCR = pcr config file
     * OUTDIR = output DIRECTORY, not path(!)
     *
     * It is not sufficient to set the working directory and call via "comparator infile ...",
     * as linux requires a preceding "./", and windows does not accept this.
     * therefore we need to expand this command before execution.
     *
     */
    private String comparatorCommand = "comparator %XCDL1% %XCDL2%  -outdir %OUTDIR% -makelog -outdata PROPVAL";
   
    MeasurementsDescriptor descriptor;
   
    public XCLComparator(MeasurementsDescriptor descriptor) {
        this.descriptor = descriptor;
        setConfigParam(System.getenv("XCLTOOLS_HOME"));
    }
   
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
   
    protected String prepareWorkingDirectory(String tempDir,long time) throws Exception {
        String workingDir = makeWorkingDirectoryName(tempDir,time);
        new File(workingDir).mkdir();
        return workingDir;
    }

    /**
     * @param time
     * @return
     */
    private String makeWorkingDirectoryName(String tempDir,long time) {
        return OS.completePathWithSeparator(OS.completePathWithSeparator(tempDir)+"xcl"+time);
    }
   
    /**
     * generates a XCDL description for <param>filename</param>
     * and stores the description in a temp file relative to the given file
     * silent call: if describing with XCDL fails, <code>null</null> is returned.
     *
     * @param filename
     * @return filename of XCDL description: <param>filename</param> + .xcdl
     */
    public String extractXCDL(String filename) {
        String outXCDL = filename+".xcdl";
        CommandExecutor cmdExecutor = new CommandExecutor();    
        try {
            cmdExecutor.setWorkingDirectory(extractorHome);
            /* now we have to expand the command with the working directory! */
            String cmd = extractorHome + extractorCommand.replace("%FILE%", filename)
                                         .replace("%XCDL%", outXCDL);
           
            int exitStatus = cmdExecutor.runCommand(cmd);
            if (exitStatus == 0) {
               // WHAT IS THE OUTPUT FILE??
            } else {
                log.error("Problem calling Extractor on file "+filename+" : "+cmdExecutor.getCommandError());
                outXCDL = null;
            }
        } catch (Exception e) {
          log.error("Problem calling Extractor on file "+filename,e);
          outXCDL = null;
        }       
        return outXCDL;
    }
   
   
    /**
     * compares two XCDL files using the given comparator configuration and writes creates a result file
     * in the given working directory.
     * 
     * @param in
     * @param out
     * @param pcr
     * @param workingDir
     * @return filename of the comparator result (including the path), or an empty string if the call failed
     */
    private String callComparator(String in, String out, String pcr, String workingDir) {
        CommandExecutor cmdExecutor = new CommandExecutor();    
        try {
            cmdExecutor.setWorkingDirectory(comparatorHome);
            /* now we have to expand the command with the working directory! */
            String cmd = comparatorHome + comparatorCommand.replace("%XCDL1%", in)
                                          .replace("%XCDL2%", out)
                                          .replace("%PCR%", pcr)
                                          .replace("%OUTDIR%", workingDir);
           
            int exitStatus = cmdExecutor.runCommand(cmd);
            if (exitStatus != 0) {
                log.error("Problem calling Comparator on files "+in+", "+out+", "+pcr+" : "+cmdExecutor.getCommandError());
                return "";
            }
        } catch (Exception e) {
          log.error("Problem calling Comparator on files "+in+", "+out+", "+pcr,e);
          return "";
        }       
       return workingDir+"copra.xml";
    }
   
    /**
     * evaluates to XCDL files
     *
     * @param tempDir
     * @param inFile
     * @param outFile
     * @return
     */
    public HashMap<MeasurementInfoUri, Value> compare(String tempDir, String inXCDL,String outXCDL, List<MeasurementInfoUri> measurementInfoUris) {
        String pcrFile = ""; // use predefined path(s) configured in the tool-config?
        String cprFile = "";
        long time = System.nanoTime();
        String wDir = makeWorkingDirectoryName(tempDir,time);
        File workingDir = new File(wDir);
        workingDir.mkdir();
       
        try {
            try {
                // extract both XCDLs
                if ((inXCDL == null)||(outXCDL == null)) {
                    log.error("Cannot start evaluation, XCDL files are missing.");
                } else {
                    // generate the configuration for the comparator
                    pcrFile = makePCR(measurementInfoUris);
                    cprFile = callComparator(inXCDL,outXCDL,pcrFile,wDir);  
   
                    if (!"".equals(cprFile)) {
                        // digest output (cf. plato integration)
                        return extractMeasurements(cprFile, measurementInfoUris);
                    }
                }
            } catch (Exception e) {
                log.error("XCLEvaluator failed: "+e.getMessage(), e);
            }
            return null;
        } finally {
            // We have to do the cleanup here, at least atm.
            // When using the working dir we might be able to do it in cleanup(), no ?
            //new File(pcrFile).delete();
            OS.deleteDirectory(workingDir);
        }
    }

    private HashMap<MeasurementInfoUri, Value> extractMeasurements(String cprFile, List<MeasurementInfoUri> measurementInfoUris) {
        HashMap<MeasurementInfoUri, Value> result = new HashMap<MeasurementInfoUri, Value>();
        try {
            ComparatorUtils compUtils = new ComparatorUtils();
            List<CompareResult> compResult = compUtils.parseResponse(cprFile);
            if (compResult.size() == 1) {
                /* we compare two xcdl files, which correspond to one compSet */
                for(MeasurementInfoUri info : measurementInfoUris) {
                    // collect results for the given measurement-info-uris
                    String propertyId = info.getPath().replace("object/xcl/", "");
                   
                    CprProperty resultProperty = compResult.get(0).getProperties().get(propertyId);
                    if (resultProperty != null) {
                        // Note:
                        // 1. there are only derived measurements in XCL
                        // 2. the fragment of an xcl - measurable property always corresponds to a xcl metric
                        String metricId = info.getFragment();
                       
                        Value v = null;
                        Scale s = descriptor.getMeasurementScale(info);
                        if (s != null) {
                            v = s.createValue();
                            v.setScale(null);
                        }
                        if ((metricId != null)&&(v != null)) {
                            CprMetricResult mResult = resultProperty.getResultMetrics().get(metricId);
                            if (mResult != null) {
                                if ("ok".equals(mResult.getState())) {
                                    v.parse(mResult.getResult());
                                    result.put(info, v);
                                    v.setComment("xcdl values(sample::result)=(" + resultProperty.getSource()+"::" + resultProperty.getTarget()+")");
                                } else {
                                    log.debug("evaluation failed: " + mResult.getResult());
                                }
                            }
                        }
                    }
                }
            } else {
                log.error("Comparator should return exactly one compResult, but there were: " + compResult.size());
            }
        } catch (PlatoServiceException e) {
            log.error("Problem extracting cpr values of:"+cprFile,e);
        }
       
       
       
        return result;
    }

    /**
     * generates a comparator configuration file and returns the full path.
     *
     * @param measurementInfoUris
     * @return
     */
    private String makePCR(List<MeasurementInfoUri> measurementInfoUris) {
        // TODO: improve performance by generating a config out of all used measurementInfos (Plato 3.1)       
        // - at the moment we use the default config
        return comparatorHome + "config.xml";
    }
   
    public String getConfigParam() {
        return configParam;
    }

    public void setConfigParam(String param) {
        configParam = param;
        if (configParam != null) {
            configParam = OS.completePathWithSeparator(configParam);
            comparatorHome = OS.completePathWithSeparator(configParam + "comparator");
            extractorHome = OS.completePathWithSeparator(configParam + "extractor");
        } else {
            log.error("XCLTOOLS - HOME not defined.");
            comparatorHome = "";
            extractorHome = "";
        }
    }
}
TOP

Related Classes of eu.planets_project.pp.plato.services.characterisation.xcl.XCLComparator

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.