hoot.services.controllers.ingest.CustomScriptResource.java Source code

Java tutorial

Introduction

Here is the source code for hoot.services.controllers.ingest.CustomScriptResource.java

Source

/*
 * This file is part of Hootenanny.
 *
 * Hootenanny is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * --------------------------------------------------------------------
 *
 * The following copyright notices are generated automatically. If you
 * have a new notice to add, please use the format:
 * " * @copyright Copyright ..."
 * This will properly maintain the copyright information. DigitalGlobe
 * copyrights will be updated automatically.
 *
 * @copyright Copyright (C) 2014, 2015 DigitalGlobe (http://www.digitalglobe.com/)
 */
package hoot.services.controllers.ingest;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.FileReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import hoot.services.HootProperties;
import hoot.services.ingest.ModifyScriptsRequest;
import hoot.services.ingest.Script;
import hoot.services.ingest.ScriptsModifiedResponse;
import hoot.services.utils.CaseInsensitiveStringList;
import hoot.services.utils.ResourceErrorHandler;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.mozilla.javascript.Function;

@Path("/customscript")
public class CustomScriptResource {
    private static final Logger log = LoggerFactory.getLogger(CustomScriptResource.class);
    protected String scriptFolder = null;
    protected String homeFolder = null;
    protected String jsHeaderScriptPath = null;
    protected String defaultTranslationsConfig = null;
    private static final String headerStart = "/*<<<";
    private static final String headerEnd = ">>>*/\n";

    /**
     * Returns the directory the scripts are stored in
     *
     * @return a directory
     */
    private File getUploadDir() {
        return new File(scriptFolder);
    }

    private boolean uploadDirExists() {
        return getUploadDir().exists();
    }

    public CustomScriptResource() {
        try {
            jsHeaderScriptPath = HootProperties.getProperty("dummyjsHeaderScriptPath");
            homeFolder = HootProperties.getProperty("homeFolder");
            String homeFolder = HootProperties.getProperty("homeFolder");
            scriptFolder = homeFolder + "/" + HootProperties.getProperty("customScriptPath");
            defaultTranslationsConfig = HootProperties.getProperty("defaultTranslationsConfig");
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
    }

    /**
     * <NAME>Custom Script Service Save</NAME>
     * <DESCRIPTION>Create or update user provided script into file.</DESCRIPTION>
     * <PARAMETERS>
     * <SCRIPT_NAME>
     *    Name of script. If exists then it will be updated
     * </SCRIPT_NAME>
     * <SCRIPT_DESCRIPTION>
     *    Script description.
     * </SCRIPT_DESCRIPTION>
     * </PARAMETERS>
     * <OUTPUT>
     *    JSON Array containing JSON of name and description of created script
     * </OUTPUT>
     * <EXAMPLE>
     *    <URL>http://localhost:8080/hoot-services/ingest/customscript/save?SCRIPT_NAME=MyTest&SCRIPT_DESCRIPTION=my description</URL>
     *    <REQUEST_TYPE>POST</REQUEST_TYPE>
     *    <INPUT>
     *    // A non-standard extension to include additional js files within the same dir
     *    // sub-tree.
     *    require("example")
     *
     *    // an optional initialize function that gets called once before any
     *    // translateAttribute calls.
     *    function initialize()
     *    {
     *        // The print method simply prints the string representation to stdout
     *        //print("Initializing.")
     *    }
     *
     *    // an optional finalize function that gets called once after all
     *    // translateAttribute calls.
     *    function finalize()
     *    {
     *        // the debug method prints to stdout when --debug has been specified on
     *        // the hoot command line. (DEBUG log level)
     *        debug("Finalizing.");
     *    }
     *
     *    // A translateAttributes method that is very similar to the python translate
     *    // attributes
     *    function translateAttributes(attrs, layerName)
     *    {
     *        tags = {};
     *        //print(layerName);
     *        for (var key in attrs)
     *        {
     *            k = key.toLowerCase()
     *            //print(k + ": " + attrs[key]);
     *            tags[k] = attrs[key]
     *        }
     *        return tags;
     *    }
     * </INPUT>
     * <OUTPUT>[{"NAME":"MyTest","DESCRIPTION":"my description"}]</OUTPUT>
     * </EXAMPLE>
    * @param script
    * @param scriptName
    * @param scriptDescription
    * @return
    */
    @POST
    @Path("/save")
    @Consumes(MediaType.TEXT_PLAIN)
    @Produces(MediaType.TEXT_PLAIN)
    public Response processSave(String script, @QueryParam("SCRIPT_NAME") final String scriptName,
            @QueryParam("SCRIPT_DESCRIPTION") final String scriptDescription) {
        JSONArray saveArr = new JSONArray();
        try {
            saveArr.add(saveScript(scriptName, scriptDescription, script));
        } catch (Exception ex) {
            ResourceErrorHandler.handleError(
                    "Error processing script save for: " + scriptName + " Error: " + ex.getMessage(),
                    Status.INTERNAL_SERVER_ERROR, log);
        }
        return Response.ok(saveArr.toString(), MediaType.TEXT_PLAIN).build();
    }

    @POST
    @Path("/saveMultiple")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ScriptsModifiedResponse saveScripts(final ModifyScriptsRequest saveMultipleScriptsRequest) {
        ScriptsModifiedResponse response = null;
        List<String> scriptsModified = new ArrayList<String>();
        try {
            response = new ScriptsModifiedResponse();
            for (Script script : saveMultipleScriptsRequest.getScripts()) {
                if (saveScript(script.getName(), script.getDescription(), script.getContent()) != null) {
                    scriptsModified.add(script.getName());
                }
            }
            response.setScriptsModified(scriptsModified.toArray(new String[] {}));
        } catch (Exception ex) {
            ResourceErrorHandler.handleError("Error processing script save.  Error: " + ex.getMessage(),
                    Status.INTERNAL_SERVER_ERROR, log);
        }
        return response;
    }

    /**
     * <NAME>Custom Script Service Get Scripts List</NAME>
     * <DESCRIPTION>Gets the list of available scripts.</DESCRIPTION>
     * <PARAMETERS>
     * </PARAMETERS>
     * <OUTPUT>
     *    JSON Array containing JSON of name and description of all available scripts
     * </OUTPUT>
     * <EXAMPLE>
     *    <URL>http://localhost:8080/hoot-services/ingest/customscript/getlist</URL>
     *    <REQUEST_TYPE>GET</REQUEST_TYPE>
     *    <INPUT>
     * </INPUT>
     * <OUTPUT>[{"NAME":"MyTest","DESCRIPTION":"my description"}]</OUTPUT>
     * </EXAMPLE>
    * @return
    */
    @GET
    @Path("/getlist")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getScriptsList() {

        JSONArray retList = new JSONArray();
        Map<String, JSONObject> sortedScripts = new TreeMap<String, JSONObject>();
        JSONArray filesList = new JSONArray();

        try {
            File scriptsDir = new File(scriptFolder);
            if (scriptsDir.exists()) {
                String[] exts = new String[1];
                exts[0] = "js";
                List<File> files = (List<File>) FileUtils.listFiles(scriptsDir, exts, false);

                for (int i = 0; i < files.size(); i++) {
                    File f = files.get(i);
                    String content = FileUtils.readFileToString(f, "UTF-8");
                    JSONObject oScript = getScriptObject(content);

                    if (oScript != null) {
                        JSONObject header = (JSONObject) oScript.get("HEADER");
                        if (header.get("CANEXPORT") == null) {
                            boolean canExport = validateExport(oScript.get("BODY").toString());
                            header.put("CANEXPORT", canExport);
                        }
                        filesList.add(header);
                    }
                }
            }
            filesList.addAll(_getDefaultList());

            // sort the list
            for (Object o : filesList) {
                JSONObject cO = (JSONObject) o;
                String sName = cO.get("NAME").toString();
                sortedScripts.put(sName.toUpperCase(), cO);
            }

            retList.addAll(sortedScripts.values());

        } catch (Exception ex) {
            ResourceErrorHandler.handleError("Error getting scripts list: " + ex.getMessage(),
                    Status.INTERNAL_SERVER_ERROR, log);
        }

        return Response.ok(retList.toString(), MediaType.TEXT_PLAIN).build();
    }

    /**
     * _getDefaultList reads the DefaultTranslations.json and passes default translations list.
     * The list is used by UI to distinguish between custom and default translations.
     *
     * @return JSONArray of translation objects
     * @throws Exception
     */
    protected JSONArray _getDefaultList() throws Exception {
        JSONArray filesList = new JSONArray();

        //defaultTranslationsConfig

        File f = new File(defaultTranslationsConfig);
        if (f.exists()) {
            FileReader reader = new FileReader(defaultTranslationsConfig);
            JSONParser jsonParser = new JSONParser();
            JSONArray defTranslations = (JSONArray) jsonParser.parse(reader);
            for (int i = 0; i < defTranslations.size(); i++) {
                JSONObject oTrans = (JSONObject) defTranslations.get(i);
                oTrans.put("DEFAULT", true);
                String desc = oTrans.get("DESCRIPTION").toString();
                if (desc.length() == 0) {
                    desc = oTrans.get("NAME").toString();
                }
                desc += " (Hootenanny Default)";
                oTrans.put("DESCRIPTION", desc);

                Object oCanExport = oTrans.get("CANEXPORT");

                // If the CANEXPORT is not available then try to determine
                if (oCanExport == null) {
                    // Get the script
                    if (oTrans.get("PATH") != null) {
                        File fScript = new File(homeFolder + "/" + oTrans.get("PATH").toString());
                        if (fScript.exists()) {
                            String sScript = FileUtils.readFileToString(fScript);
                            boolean canExport = validateExport(sScript);
                            oTrans.put("CANEXPORT", canExport);
                        }

                    }
                }

            }

            // validate FOUO support
            if (defTranslations.size() > 0) {
                for (Object oTrans : defTranslations) {
                    JSONObject jsTrans = (JSONObject) oTrans;
                    if (jsTrans.get("FOUO_PATH") != null) {
                        // See if FOUO folder exists
                        File fouoPath = new File(homeFolder + "/" + jsTrans.get("FOUO_PATH").toString());
                        if (fouoPath.exists()) {
                            filesList.add(jsTrans);
                        }
                    } else {
                        // If there is no FOUO_PATH then assume it is not FOUO translation
                        filesList.add(jsTrans);
                    }
                }

            }
        }
        return filesList;
    }

    /**
     * <NAME>Custom Script Service Get Script</NAME>
     * <DESCRIPTION>Returns the specified script.</DESCRIPTION>
     * <PARAMETERS>
     * <SCRIPT_NAME>
     * Name of the script to retrieve.
     * </SCRIPT_NAME>
     * </PARAMETERS>
     * <OUTPUT>
     *    Requested translation script
     * </OUTPUT>
     * <EXAMPLE>
     *    <URL>http://localhost:8080/hoot-services/ingest/customscript/getscript?SCRIPT_NAME=MyTest</URL>
     *    <REQUEST_TYPE>GET</REQUEST_TYPE>
     *    <INPUT>
     * </INPUT>
     * <OUTPUT>
     *    // A non-standard extension to include additional js files within the same dir
     *    // sub-tree.
     *    require("example")
     *
     *    // an optional initialize function that gets called once before any
     *    // translateAttribute calls.
     *    function initialize()
     *    {
     *        // The print method simply prints the string representation to stdout
     *        //print("Initializing.")
     *    }
     *
     *    // an optional finalize function that gets called once after all
     *    // translateAttribute calls.
     *    function finalize()
     *    {
     *        // the debug method prints to stdout when --debug has been specified on
     *        // the hoot command line. (DEBUG log level)
     *        debug("Finalizing.");
     *    }
     *
     *    // A translateAttributes method that is very similar to the python translate
     *    // attributes
     *    function translateAttributes(attrs, layerName)
     *    {
     *        tags = {};
     *        //print(layerName);
     *        for (var key in attrs)
     *        {
     *            k = key.toLowerCase()
     *            //print(k + ": " + attrs[key]);
     *            tags[k] = attrs[key]
     *        }
     *        return tags;
     *    }
     * </OUTPUT>
     * </EXAMPLE>
    * @param scriptName
    * @return
    */
    @GET
    @Path("/getscript")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getScript(@QueryParam("SCRIPT_NAME") final String scriptName) {
        String script = "";
        try {
            File scriptsDir = new File(scriptFolder);

            if (scriptsDir.exists()) {
                String[] exts = new String[1];
                exts[0] = "js";
                List<File> files = (List<File>) FileUtils.listFiles(scriptsDir, exts, false);

                for (int i = 0; i < files.size(); i++) {
                    try {
                        File f = files.get(i);
                        String content = FileUtils.readFileToString(f, "UTF-8");
                        JSONObject oScript = getScriptObject(content);

                        if (oScript != null) {
                            JSONObject header = (JSONObject) oScript.get("HEADER");
                            if (header.get("NAME").toString().equalsIgnoreCase(scriptName)) {
                                script = oScript.get("BODY").toString();
                                break;
                            }
                        }
                    } catch (Exception e) {
                        log.error("Failed to read file header: " + e.getMessage());
                    }
                }
            }
        } catch (Exception ex) {
            ResourceErrorHandler.handleError("Error getting script: " + scriptName + " Error: " + ex.getMessage(),
                    Status.INTERNAL_SERVER_ERROR, log);
        }
        return Response.ok(script, MediaType.TEXT_PLAIN).build();
    }

    /**
     * <NAME>Custom Script Service Get Default Script</NAME>
     * <DESCRIPTION>Returns the default script.</DESCRIPTION>
     * <PARAMETERS>
     * <SCRIPT_PATH>
     * Relative path of default translation script. (Relative to hoot home path)
     * </SCRIPT_PATH>
     * </PARAMETERS>
     * <OUTPUT>
     *    Requested translation script
     * </OUTPUT>
     * <EXAMPLE>
     *    <URL>http://localhost:8080/hoot-services/ingest/customscript/getscript?SCRIPT_PATH=customscript/testdefault.js</URL>
     *    <REQUEST_TYPE>GET</REQUEST_TYPE>
     *    <INPUT>
     * </INPUT>
     * <OUTPUT>
     *    // A non-standard extension to include additional js files within the same dir
     *    // sub-tree.
     *    require("example")
     *
     *    // an optional initialize function that gets called once before any
     *    // translateAttribute calls.
     *    function initialize()
     *    {
     *        // The print method simply prints the string representation to stdout
     *        //print("Initializing.")
     *    }
     *
     *    // an optional finalize function that gets called once after all
     *    // translateAttribute calls.
     *    function finalize()
     *    {
     *        // the debug method prints to stdout when --debug has been specified on
     *        // the hoot command line. (DEBUG log level)
     *        debug("Finalizing.");
     *    }
     *
     *    // A translateAttributes method that is very similar to the python translate
     *    // attributes
     *    function translateAttributes(attrs, layerName)
     *    {
     *        tags = {};
     *        //print(layerName);
     *        for (var key in attrs)
     *        {
     *            k = key.toLowerCase()
     *            //print(k + ": " + attrs[key]);
     *            tags[k] = attrs[key]
     *        }
     *        return tags;
     *    }
     * </OUTPUT>
     * </EXAMPLE>
    * @param scriptPath
    * @return
    */
    @GET
    @Path("/getdefaultscript")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getDefaultScript(@QueryParam("SCRIPT_PATH") final String scriptPath) {
        String script = "";
        try {
            File scriptFile = new File(homeFolder + "/" + scriptPath);

            if (scriptFile.exists()) {
                script = FileUtils.readFileToString(scriptFile);
            }
        } catch (Exception ex) {
            ResourceErrorHandler.handleError("Error getting script: " + scriptPath + " Error: " + ex.getMessage(),
                    Status.INTERNAL_SERVER_ERROR, log);
        }
        return Response.ok(script, MediaType.TEXT_PLAIN).build();
    }

    /**
     * <NAME>Custom Script Service Delete Script</NAME>
     * <DESCRIPTION>Deletes the specified script.</DESCRIPTION>
     * <PARAMETERS>
     * <SCRIPT_NAME>
     * Name of the script to delete.
     * </SCRIPT_NAME>
     * </PARAMETERS>
     * <OUTPUT>
     *    JSON Array containing JSON of name and description of deleted scripts
     * </OUTPUT>
     * <EXAMPLE>
     *    <URL>http://localhost:8080/hoot-services/ingest/customscript/deletescript?SCRIPT_NAME=My Test6</URL>
     *    <REQUEST_TYPE>GET</REQUEST_TYPE>
     *    <INPUT>
     * </INPUT>
     * <OUTPUT>
     * [{"NAME":"My Test6","DESCRIPTION":"my description"}]
     * </OUTPUT>
     * </EXAMPLE>
    * @param scriptName
    * @return
    */
    @GET
    @Path("/deletescript")
    @Produces(MediaType.TEXT_PLAIN)
    public Response deleteScript(@QueryParam("SCRIPT_NAME") final String scriptName) {
        JSONArray delArr = new JSONArray();
        try {
            List<File> files = getFilesInScriptDir();
            if (files == null) {
                throw new Exception("Script directory does not exist.");
            }

            for (int i = 0; i < files.size(); i++) {
                try {
                    File f = files.get(i);
                    String content = FileUtils.readFileToString(f, "UTF-8");
                    JSONObject oScript = getScriptObject(content);

                    if (oScript != null) {
                        JSONObject header = (JSONObject) oScript.get("HEADER");
                        if (header.get("NAME").toString().equalsIgnoreCase(scriptName)) {
                            delArr.add(header);
                            f.delete();
                            break;
                        }
                    }
                } catch (Exception e) {
                    log.error("Failed to read file header: " + e.getMessage());
                }
            }
        } catch (Exception ex) {
            ResourceErrorHandler.handleError("Error deleting script: " + scriptName + " Error: " + ex.getMessage(),
                    Status.INTERNAL_SERVER_ERROR, log);
        }

        return Response.ok(delArr.toString(), MediaType.TEXT_PLAIN).build();
    }

    @DELETE
    @Path("/deletescripts")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ScriptsModifiedResponse deleteScripts(final ModifyScriptsRequest deleteScriptsRequest) {
        ScriptsModifiedResponse response = null;
        CaseInsensitiveStringList scriptNames = null;
        try {
            scriptNames = new CaseInsensitiveStringList();
            for (Script script : deleteScriptsRequest.getScripts()) {
                scriptNames.add(script.getName());
            }

            final List<File> files = getFilesInScriptDir();

            response = new ScriptsModifiedResponse();
            List<String> scriptsDeleted = new ArrayList<String>();
            for (int i = 0; i < files.size(); i++) {
                File f = null;
                try {
                    f = files.get(i);
                    String content = FileUtils.readFileToString(f, "UTF-8");
                    JSONObject oScript = getScriptObject(content);
                    if (oScript != null) {
                        JSONObject header = (JSONObject) oScript.get("HEADER");
                        final String foundScriptName = header.get("NAME").toString();
                        if (scriptNames.contains(foundScriptName)) {
                            scriptsDeleted.add(foundScriptName);
                            f.delete();
                            log.debug("Deleted script: " + foundScriptName);
                        }
                    }
                } catch (Exception e) {
                    log.error("Failed to read file header for script: " + f.getName() + e.getMessage());
                }
            }
            response.setScriptsModified(scriptsDeleted.toArray(new String[] {}));
        } catch (Exception ex) {
            ResourceErrorHandler.handleError("Error deleting scripts:  Error: " + ex.getMessage(),
                    Status.INTERNAL_SERVER_ERROR, log);
        }

        return response;
    }

    protected JSONObject getScriptObject(String content) throws Exception {
        JSONObject script = new JSONObject();
        if (content.startsWith(headerStart)) {
            int iHeader = content.indexOf(headerEnd);
            if (iHeader > 0) {
                String header = content.substring(0, iHeader);
                header = header.replace((CharSequence) headerStart, (CharSequence) "");
                header = header.replace((CharSequence) headerEnd, (CharSequence) "");

                String body = content.substring(iHeader + headerEnd.length());

                JSONParser parser = new JSONParser();
                JSONObject jHeader = (JSONObject) parser.parse(header);
                if (jHeader != null) {
                    script.put("HEADER", jHeader);
                    script.put("BODY", body);
                    return script;
                }
            }
        }
        return null;
    }

    private List<File> getFilesInScriptDir() throws IOException {
        if (!uploadDirExists()) {
            FileUtils.forceMkdir(getUploadDir());
        }
        File scriptsDir = new File(scriptFolder);
        String[] exts = new String[1];
        exts[0] = "js";
        return (List<File>) FileUtils.listFiles(scriptsDir, exts, false);
    }

    private JSONObject saveScript(final String name, final String description, final String content)
            throws Exception {
        if (StringUtils.trimToNull(name) == null) {
            log.error("Invalid input script name: " + name);
            return null;
        }
        if (StringUtils.trimToNull(content) == null) {
            log.error("Invalid input script content.");
            return null;
        }

        boolean canExport = validateExport(content);
        if (!uploadDirExists()) {
            FileUtils.forceMkdir(getUploadDir());
        }

        File fScript = new File(scriptFolder + "/" + name + ".js");

        if (!fScript.exists()) {
            fScript.createNewFile();
        }
        String header = headerStart;
        JSONObject oHeader = new JSONObject();
        oHeader.put("NAME", name);
        oHeader.put("DESCRIPTION", description);
        oHeader.put("CANEXPORT", canExport);

        header += oHeader.toString();
        header += headerEnd;

        FileUtils.writeStringToFile(fScript, header + content);

        log.debug("Saved script: " + name);

        return oHeader;
    }

    // This function checks to see if the script has both getDbSchema and translateToOgr which indicates if it can export
    protected boolean validateExport(String script) {

        boolean canExport = false;
        org.mozilla.javascript.Context context = org.mozilla.javascript.Context.enter();
        try {
            // initialize Rhino

            org.mozilla.javascript.ScriptableObject scope = context.initStandardObjects();
            context.setOptimizationLevel(-1);

            scope.put("context", scope, context);
            scope.put("scope", scope, scope);
            scope.put("APP_ROOT", scope, homeFolder);

            FileReader frHeader = new FileReader(jsHeaderScriptPath);
            BufferedReader jsHeader = new BufferedReader(frHeader);
            context.evaluateReader(scope, jsHeader, "jsHeader", 1, null);

            StringReader sr = new StringReader(script);
            BufferedReader translation_script = new BufferedReader(sr);
            context.evaluateReader(scope, translation_script, "translation_script", 1, null);

            // call getDbSchema call any required preloading functions
            Object getSchemaObj = scope.get("getDbSchema", scope);
            Object translateToOgr = scope.get("translateToOgr", scope);

            boolean getDbSchemaExist = false;
            if (getSchemaObj != null) {
                // If not exist then will return Tag instead of function
                if (getSchemaObj instanceof Function) {
                    getDbSchemaExist = true;
                }
            }

            boolean translateToOgrExist = false;
            if (translateToOgr != null) {
                // If not exist then will return Tag instead of function
                if (translateToOgr instanceof Function) {
                    translateToOgrExist = true;
                }
            }

            canExport = getDbSchemaExist && translateToOgrExist;

            frHeader.close();
            jsHeader.close();
            sr.close();
            translation_script.close();

        } catch (Exception ex) {
            log.error(ex.getMessage());
        } finally {
            context.exit();
        }
        return canExport;
    }
}