eionet.gdem.qa.XQueryService.java Source code

Java tutorial

Introduction

Here is the source code for eionet.gdem.qa.XQueryService.java

Source

/**
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * The Original Code is "EINRC-7 / GDEM project".
 *
 * The Initial Developer of the Original Code is TietoEnator.
 * The Original Code code was developed for the European
 * Environment Agency (EEA) under the IDA/EINRC framework contract.
 *
 * Copyright (C) 2000-2004 by European Environment Agency.  All
 * Rights Reserved.
 *
 * Original Code: Kaido Laine (TietoEnator)
 */

package eionet.gdem.qa;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eionet.gdem.Constants;
import eionet.gdem.GDEMException;
import eionet.gdem.Properties;
import eionet.gdem.dcm.business.SchemaManager;
import eionet.gdem.dcm.business.SourceFileManager;
import eionet.gdem.dcm.remote.RemoteService;
import eionet.gdem.services.GDEMServices;
import eionet.gdem.services.db.dao.IConvTypeDao;
import eionet.gdem.services.db.dao.IQueryDao;
import eionet.gdem.services.db.dao.IXQJobDao;
import eionet.gdem.utils.Utils;
import eionet.gdem.utils.xml.FeedbackAnalyzer;

/**
 * QA Service Service Facade. The service is able to execute different QA related methods that are called through XML/RPC and HTTP
 * POST and GET.
 *
 * @author Enriko Ksper
 */
public class XQueryService extends RemoteService {

    private IQueryDao queryDao = GDEMServices.getDaoService().getQueryDao();
    private IXQJobDao xqJobDao = GDEMServices.getDaoService().getXQJobDao();
    private IConvTypeDao convTypeDao = GDEMServices.getDaoService().getConvTypeDao();

    private SchemaManager schManager = new SchemaManager();

    /** */
    private static final Log LOGGER = LogFactory.getLog(XQueryService.class);

    public XQueryService() {
        // for remote clients use trusted mode
        setTrustedMode(true);
    }

    /**
     * List all possible XQueries for this namespace.
     */
    public Vector listQueries(String schema) throws GDEMException {

        ListQueriesMethod method = new ListQueriesMethod();
        Vector v = method.listQueries(schema);
        return v;
    }

    /**
     * List all XQueries and their modification times for this namespace returns also XML Schema validation.
     */
    public Vector listQAScripts(String schema) throws GDEMException {
        ListQueriesMethod method = new ListQueriesMethod();
        Vector v = method.listQAScripts(schema);
        return v;
    }

    /**
     * Request from XML/RPC client Stores the source files and starts a job in the workqueue.
     *
     * @param files - Structure with XMLschemas as a keys and values are list of XML Files
     * @return Hashtable result: Structure with JOB ids as a keys and source files as values
     */
    public Vector analyzeXMLFiles(Hashtable files) throws GDEMException {

        Vector result = new Vector();

        if (files == null) {
            return result;
        }

        Enumeration _schemas = files.keys();
        while (_schemas.hasMoreElements()) {
            String _schema = _schemas.nextElement().toString();
            Vector _files = (Vector) files.get(_schema);
            if (Utils.isNullVector(_files)) {
                continue;
            }

            for (int i = 0; i < _files.size(); i++) {
                String _file = (String) _files.get(i);
                analyzeXMLFiles(_schema, _file, result);
            }
        }
        return result;
    }

    /**
     * Stores one source file and starts a job in the workqueue.
     *
     * @param schema - XML Schema URL
     * @param file - Source file URL
     * @return Hashtable result: Structure with JOB ids as a keys and source files as values
     */
    // public Hashtable analyze(String schema, String file) throws GDEMException{
    // return analyze(schema,file, null);
    // }

    /**
     *
     */
    public Vector analyzeXMLFiles(String schema, String origFile, Vector result) throws GDEMException {

        LOGGER.info("XML/RPC call for analyze xml: " + origFile);

        if (result == null) {
            result = new Vector();
        }
        Vector outputTypes = null;
        // get all possible xqueries from db
        String newId = "-1"; // should not be returned with value -1;
        String file = origFile;

        Vector queries = listQueries(schema);

        try {
            outputTypes = convTypeDao.getConvTypes();
        } catch (SQLException sqe) {
            throw new GDEMException("DB operation failed: " + sqe.toString());
        }

        try {
            // get the trusted URL from source file adapter
            file = SourceFileManager.getSourceFileAdapterURL(getTicket(), file, isTrustedMode());
        } catch (Exception e) {
            String err_mess = "File URL is incorrect";
            LOGGER.error(err_mess + "; " + e.toString());
            throw new GDEMException(err_mess, e);
        }

        if (!Utils.isNullVector(queries)) {

            for (int j = 0; j < queries.size(); j++) {
                Hashtable query = (Hashtable) queries.get(j);
                String query_id = String.valueOf(query.get("query_id"));
                String queryFile = (String) query.get("query");
                String contentType = (String) query.get("content_type_id");
                String fileExtension = getExtension(outputTypes, contentType);
                String resultFile = Properties.tmpFolder + File.separatorChar + "gdem_q" + query_id + "_"
                        + System.currentTimeMillis() + "." + fileExtension;
                try {
                    int queryId = 0;
                    try {
                        queryId = Integer.parseInt(query_id);
                    } catch (NumberFormatException n) {
                        queryId = 0;
                    }
                    // if it is a XQuery script, then append the system folder
                    if (queryId != Constants.JOB_VALIDATION
                            && queryFile.startsWith(Properties.gdemURL + "/" + Constants.QUERIES_FOLDER)) {
                        queryFile = Utils.Replace(queryFile, Properties.gdemURL + "/" + Constants.QUERIES_FOLDER,
                                Properties.queriesFolder + File.separator);
                    }
                    newId = xqJobDao.startXQJob(file, queryFile, resultFile, queryId);
                } catch (SQLException sqe) {
                    throw new GDEMException("DB operation failed: " + sqe.toString());
                }
                Vector queryResult = new Vector();
                queryResult.add(newId);
                queryResult.add(origFile);
                result.add(queryResult);
            }
        }

        LOGGER.info("Analyze xml result: " + result.toString());
        return result;
    }

    private String getExtension(Vector outputTypes, String content_type) {
        String ret = "html";
        if (outputTypes == null) {
            return ret;
        }
        if (content_type == null) {
            return ret;
        }

        for (int i = 0; i < outputTypes.size(); i++) {
            Hashtable outType = (Hashtable) outputTypes.get(i);
            if (outType == null) {
                continue;
            }
            if (!outType.containsKey("conv_type") || !outType.containsKey("file_ext")
                    || outType.get("conv_type") == null || outType.get("file_ext") == null) {
                continue;
            }
            String typeId = (String) outType.get("conv_type");
            if (!content_type.equalsIgnoreCase(typeId)) {
                continue;
            }
            ret = (String) outType.get("file_ext");
        }

        return ret;
    }

    /**
     * Request from XML/RPC client Stores the xqScript and starts a job in the workqueue.
     *
     * @param sourceURL - URL of the source XML
     * @param xqScript - XQueryScript to be processed
     * @param scriptType - xquery, xsl or xgawk
     */
    public String analyze(String sourceURL, String xqScript, String scriptType) throws GDEMException {
        String xqFile = "";

        LOGGER.info("XML/RPC call for analyze xml: " + sourceURL);
        // save XQScript in a text file for the WQ
        try {
            xqFile = Utils.saveStrToFile(xqScript, scriptType);
        } catch (FileNotFoundException fne) {
            throw new GDEMException("Folder does not exist: :" + fne.toString());
        } catch (IOException ioe) {
            throw new GDEMException("Error storing XQScript into file:" + ioe.toString());
        }

        // name for temporary output file where the esult is stored:
        String resultFile = Properties.tmpFolder + File.separatorChar + "gdem_" + System.currentTimeMillis()
                + ".html";
        String newId = "-1"; // should not be returned with value -1;

        // start a job in the Workqueue
        try {
            // get the trusted URL from source file adapter
            sourceURL = SourceFileManager.getSourceFileAdapterURL(getTicket(), sourceURL, isTrustedMode());
            newId = xqJobDao.startXQJob(sourceURL, xqFile, resultFile);

        } catch (SQLException sqe) {
            sqe.printStackTrace();
            LOGGER.error("DB operation failed: " + sqe.toString());
            throw new GDEMException("DB operation failed: " + sqe.toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
            LOGGER.error("Source file URL is wrong: " + e.toString());
            throw new GDEMException("Source file URL is wrong: " + e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            LOGGER.error("Error opening source file: " + e.toString());
            throw new GDEMException("Error opening source file: " + e.toString());
        }
        return newId;
    }

    /**
     * Checks if the job is ready (or error) and returns the result (or error message).
     *
     * @param jobId
     * @return Hash including code and result
     */
    public Hashtable getResult(String jobId) throws GDEMException {

        LOGGER.info("XML/RPC call for getting result with JOB ID: " + jobId);

        String[] jobData = null;
        HashMap scriptData = null;
        int status = 0;
        try {
            jobData = xqJobDao.getXQJobData(jobId);

            if (jobData == null) { // no such job
                // throw new GDEMException("** No such job with ID=" + jobId + " in the queue.");
                status = Constants.XQ_JOBNOTFOUND_ERR;
            } else {
                scriptData = queryDao.getQueryInfo(jobData[5]);

                status = Integer.valueOf(jobData[3]).intValue();
            }
        } catch (SQLException sqle) {
            throw new GDEMException("Error gettign XQJob data from DB: " + sqle.toString());
        }

        LOGGER.info("XQueryService found status for job (" + jobId + "):" + String.valueOf(status));

        Hashtable ret = result(status, jobData, scriptData, jobId);
        if (LOGGER.isInfoEnabled()) {
            String result = ret.toString();
            if (result.length() > 100) {
                result = result.substring(0, 100).concat("....");
            }
            LOGGER.info("result: " + result);
        }
        return ret;
    }

    /**
     * Hashtable to be composed for the getResult() method return value.
     */
    private Hashtable result(int status, String[] jobData, HashMap scriptData, String jobId) throws GDEMException {
        Hashtable<String, String> h = new Hashtable<String, String>();
        int resultCode;
        String resultValue = "";
        String metatype = "";
        String script_title = "";

        String feedbackStatus = Constants.XQ_FEEDBACKSTATUS_UNKNOWN;
        String feedbackMsg = "";

        if (status == Constants.XQ_RECEIVED || status == Constants.XQ_DOWNLOADING_SRC
                || status == Constants.XQ_PROCESSING) {
            resultCode = Constants.JOB_NOT_READY;
            resultValue = "*** Not ready ***";
        } else if (status == Constants.XQ_JOBNOTFOUND_ERR) {
            resultCode = Constants.JOB_LIGHT_ERROR;
            resultValue = "*** No such job or the job result has been already downloaded. ***";
        } else {
            if (status == Constants.XQ_READY) {
                resultCode = Constants.JOB_READY;
            } else if (status == Constants.XQ_LIGHT_ERR) {
                resultCode = Constants.JOB_LIGHT_ERROR;
            } else if (status == Constants.XQ_FATAL_ERR) {
                resultCode = Constants.JOB_FATAL_ERROR;
            } else {
                resultCode = -1; // not expected to reach here
            }

            try {
                int xq_id = 0;
                try {
                    xq_id = Integer.parseInt(jobData[5]);
                } catch (NumberFormatException n) {
                }

                if (xq_id == Constants.JOB_VALIDATION) {
                    metatype = "text/html";
                    script_title = "XML Schema validation";
                } else if (xq_id > 0) {
                    metatype = (String) scriptData.get("meta_type");
                    script_title = (String) scriptData.get("short_name");
                }

                resultValue = Utils.readStrFromFile(jobData[2]);
                HashMap<String, String> feedbackResult = FeedbackAnalyzer.getFeedbackResultFromFile(jobData[2]);

                feedbackStatus = feedbackResult.get(Constants.RESULT_FEEDBACKSTATUS_PRM);
                feedbackMsg = feedbackResult.get(Constants.RESULT_FEEDBACKMESSAGE_PRM);

            } catch (Exception ioe) {
                resultCode = Constants.JOB_FATAL_ERROR;
                resultValue = "<error>Error reading the XQ value from the file:" + jobData[2] + "</error>";
            }

        }
        try {
            h.put(Constants.RESULT_CODE_PRM, Integer.toString(resultCode));
            h.put(Constants.RESULT_VALUE_PRM, resultValue);
            h.put(Constants.RESULT_METATYPE_PRM, metatype);
            h.put(Constants.RESULT_SCRIPTTITLE_PRM, script_title);
            h.put(Constants.RESULT_FEEDBACKSTATUS_PRM, feedbackStatus);
            h.put(Constants.RESULT_FEEDBACKMESSAGE_PRM, feedbackMsg);

        } catch (Exception e) {
            String err_mess = "JobID: " + jobId + "; Creating result Hashtable for getResult method failed result: "
                    + e.toString();
            LOGGER.error(err_mess);
            throw new GDEMException(err_mess, e);
        }

        return h;

    }

    /**
     * Remote method for running the QA script on the fly.
     *
     * @param sourceUrl URL of the source XML
     * @param scriptId XQueryScript ID or -1 (XML Schema validation) to be processed
     * @return Vector of 2 fields: content type and byte array
     * @throws GDEMException in case of business logic error
     */
    public Vector runQAScript(String sourceUrl, String scriptId) throws GDEMException {

        if (!isHTTPRequest() && LOGGER.isDebugEnabled()) {
            LOGGER.debug("ConversionService.convert method called through XML-rpc.");
        }
        RunQAScriptMethod runQaMethod = new RunQAScriptMethod();
        setGlobalParameters(runQaMethod);
        return runQaMethod.runQAScript(sourceUrl, scriptId);

    }
}