com.flexive.war.beans.admin.main.ScriptBean.java Source code

Java tutorial

Introduction

Here is the source code for com.flexive.war.beans.admin.main.ScriptBean.java

Source

/***************************************************************
 *  This file is part of the [fleXive](R) backend application.
 *
 *  Copyright (c) 1999-2014
 *  UCS - unique computing solutions gmbh (http://www.ucs.at)
 *  All rights reserved
 *
 *  The [fleXive](R) backend application 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 2 of the License, or (at your option) any
 *  later version.
 *
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/licenses/gpl.html.
 *  A copy is found in the textfile GPL.txt and important notices to the
 *  license from the author are found in LICENSE.txt distributed with
 *  these libraries.
 *
 *  This library 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.
 *
 *  For further information about UCS - unique computing solutions gmbh,
 *  please see the company website: http://www.ucs.at
 *
 *  For further information about [fleXive](R), please see the
 *  project website: http://www.flexive.org
 *
 *
 *  This copyright notice MUST APPEAR in all copies of the file!
 ***************************************************************/
package com.flexive.war.beans.admin.main;

import com.flexive.faces.FxJsfUtils;
import com.flexive.faces.beans.MessageBean;
import com.flexive.faces.messages.FxFacesMsgErr;
import com.flexive.faces.messages.FxFacesMsgInfo;
import com.flexive.shared.CacheAdmin;
import com.flexive.shared.EJBLookup;
import com.flexive.shared.FxContext;
import com.flexive.shared.FxSharedUtils;
import com.flexive.shared.exceptions.FxApplicationException;
import com.flexive.shared.scripting.*;
import com.flexive.shared.security.Role;
import com.flexive.shared.security.UserTicket;
import groovy.lang.GroovyShell;
import org.apache.commons.lang.StringUtils;

import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.sql.SQLException;
import java.util.*;

import static com.flexive.shared.EJBLookup.getScriptingEngine;

/**
 * JSF scripting bean
 *
 * @author Johannes Wernig-Pichler (johannes.wernig-pichler@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
 * @version $Rev$
 */
public class ScriptBean implements Serializable {
    private static final long serialVersionUID = -3764559730042052584L;

    private ScriptHolder currentData = new ScriptHolder();
    private static final String SCRIPT_EDIT = "scriptEdit";
    private static final String SCRIPT_OVERVIEW = "scriptOverview";

    /**
     * A holder class for a Script object
     * @since 3.1.4
     */
    private static class ScriptHolder implements Serializable {
        private long id = -1;
        private String name;
        private String desc;
        private String code;
        private boolean active;
        private FxScriptInfoEdit sinfo;
        private FxScriptMapping mapping;
        private Map<Long, String> typeMappingNames;
        private Map<Long, String> assignmentMappingNames;
        private FxScriptScope selectedScope = null;
        private long selectedScriptEventId = -1;
        private FxScriptRunInfo currentRunInfo;
        private String nameErrorMsg;
        private boolean inputFieldEnabled = false;
        private boolean verifyButtonEnabled = false;
        private boolean executeButtonEnabled = false;
        private long executionTime;
        private String userLang = "en";
        private String language = "groovy";
    }

    private int overviewPageNumber = 1;
    private int overviewRowNumber = 10;
    private String sortColumn;
    private String sortOrder;

    private transient Object result;

    private static final String ID_CACHE_KEY = ScriptBean.class + "_id";

    /**
     * @return true if the edit tab should be opened
     * @since 3.1.4
     */
    public boolean isOpenTab() {
        return currentData != null && currentData.id >= 0;
    }

    /**
     * Opens the edit mandator in a tab
     * @return the name where to navigate
     * @since 3.1.4
     */
    public String openEditTab() {
        if (!isOpenTab())
            return editScript();
        return SCRIPT_EDIT;
    }

    public ScriptHolder getCurrentData() {
        return currentData;
    }

    public void setCurrentData(ScriptHolder currentData) {
        this.currentData = currentData;
    }

    /**
     * Navigate back to the overview and remembers the changes of the mandator
     *
     * @return overview page
     * @since 3.1.4
     */
    public String overview() {
        return SCRIPT_OVERVIEW;
    }

    // constructor
    public ScriptBean() {
        this.currentData.sinfo = new FxScriptInfo().asEditable();
    }

    public FxScriptScope getSelectedScope() {
        if (currentData.selectedScope == null)
            currentData.selectedScope = FxScriptScope.All;
        return currentData.selectedScope;
    }

    public List<SelectItem> getEventsForScope() {
        //if the selected event is not in the list of events for the currently selected scope
        //reset the selected event id to default -1==all events
        boolean selectedEventFound = false;
        FxScriptScope scope = getSelectedScope();
        List<SelectItem> eventsForScope = new ArrayList<SelectItem>();
        eventsForScope.add(new SelectItem(-1, MessageBean.getInstance().getMessage("Script.selectItem.allEvents")));
        for (FxScriptEvent e : FxScriptEvent.values()) {
            if (e.getScope().compareTo(scope) == 0 || scope.compareTo(FxScriptScope.All) == 0) {
                eventsForScope.add(new SelectItem(e.getId(), e.getName()));
                if (getSelectedScriptEventId() == e.getId())
                    selectedEventFound = true;
            }
        }

        if (!selectedEventFound)
            this.currentData.selectedScriptEventId = -1;

        return eventsForScope;
    }

    public String getSortColumn() {
        return sortColumn;
    }

    public void setSortColumn(String sortColumn) {
        this.sortColumn = sortColumn;
    }

    public String getSortOrder() {
        return sortOrder;
    }

    public void setSortOrder(String sortOrder) {
        this.sortOrder = sortOrder;
    }

    public void setSelectedScope(FxScriptScope selectedScope) {
        this.currentData.selectedScope = selectedScope;
    }

    public long getSelectedScriptEventId() {
        return currentData.selectedScriptEventId;
    }

    public void setSelectedScriptEventId(long selectedScriptEventId) {
        this.currentData.selectedScriptEventId = selectedScriptEventId;
    }

    /**
     * Retrieves the list of all scripts for the given event
     *
     * @return returns the List<FxScriptInfo> for the given event
     */
    public List<FxScriptInfo> getScriptsForEvent() {
        long eventId = getSelectedScriptEventId();
        List<FxScriptInfo> scriptsForEvent = new ArrayList<FxScriptInfo>();
        for (FxScriptInfo s : CacheAdmin.getFilteredEnvironment().getScripts())
            if ((eventId == -1 && getSelectedScope().compareTo(FxScriptScope.All) == 0)
                    || (eventId == -1 && s.getEvent().getScope().compareTo(getSelectedScope()) == 0)
                    || (s.getEvent().getId() == eventId && getSelectedScope().compareTo(FxScriptScope.All) == 0)
                    || (s.getEvent().getId() == eventId
                            && s.getEvent().getScope().compareTo(getSelectedScope()) == 0))
                scriptsForEvent.add(s);
        return scriptsForEvent;
    }

    public long getId() {
        return currentData.id;
    }

    public void setId(long id) {
        this.currentData.id = id;
    }

    public boolean isActive() {
        return currentData.active;
    }

    public void setActive(boolean active) {
        this.currentData.active = active;
    }

    public void setLanguage(String language) {
        this.currentData.language = language;
    }

    public String getLanguage() {
        return currentData.language;
    }

    /**
     * Loads the script specified by the parameter id.
     *
     * @return the next page to render
     */
    public String editScript() {
        ensureScriptIdSet();
        setSinfo(CacheAdmin.getEnvironment().getScript(currentData.id).asEditable());
        try {
            this.currentData.mapping = getScriptingEngine().loadScriptMapping(currentData.id);
            HashMap<Long, String> typeMappingNames = new HashMap<Long, String>();
            currentData.typeMappingNames = typeMappingNames;
            // we need the type names for the user interface and the type ids for the links
            for (FxScriptMappingEntry entry : this.currentData.mapping.getMappedTypes()) {
                typeMappingNames.put(entry.getId(), CacheAdmin.getEnvironment().getType(entry.getId()).getName());
                for (long id : entry.getDerivedIds())
                    typeMappingNames.put(id, CacheAdmin.getEnvironment().getType(id).getName());
            }
            HashMap<Long, String> assignmentMappingNames = new HashMap<Long, String>();
            currentData.assignmentMappingNames = assignmentMappingNames;
            for (FxScriptMappingEntry entry : this.currentData.mapping.getMappedAssignments()) {
                assignmentMappingNames.put(entry.getId(),
                        CacheAdmin.getEnvironment().getAssignment(entry.getId()).getXPath());
                for (long id : entry.getDerivedIds())
                    assignmentMappingNames.put(id, CacheAdmin.getEnvironment().getAssignment(id).getXPath());
            }
        } catch (FxApplicationException e) {
            new FxFacesMsgErr(e).addToContext();
        } catch (SQLException e) {
            new FxFacesMsgErr("Script.err.loadMap").addToContext();
        }
        FxScriptInfoEdit sinfo = currentData.sinfo;
        setName(sinfo.getName());
        setDesc(sinfo.getDescription());
        setCode(sinfo.getCode());
        setActive(sinfo.isActive());
        verifyScriptName();
        return SCRIPT_EDIT;
    }

    public FxScriptInfo getSinfo() {
        return currentData.sinfo;
    }

    public void setSinfo(FxScriptInfoEdit sinfo) {
        this.currentData.sinfo = sinfo;
    }

    public String getName() {
        return currentData.name;
    }

    public void setName(String name) {
        this.currentData.name = name;
    }

    public String getDesc() {
        return currentData.desc;
    }

    public void setDesc(String desc) {
        this.currentData.desc = desc;
    }

    public String getCode() {
        return currentData.code;
    }

    public void setCode(String code) {
        this.currentData.code = code;
    }

    private void ensureScriptIdSet() {
        if (this.currentData.id <= 0) {
            this.currentData.id = (Long) FxJsfUtils.getSessionAttribute(ID_CACHE_KEY);
        }
    }

    public int getOverviewPageNumber() {
        return overviewPageNumber;
    }

    public void setOverviewPageNumber(int overviewPageNumber) {
        this.overviewPageNumber = overviewPageNumber;
    }

    public int getOverviewRowNumber() {
        return overviewRowNumber;
    }

    public void setOverviewRowNumber(int overviewRowNumber) {
        this.overviewRowNumber = overviewRowNumber;
    }

    /**
     * Deletes a script, with the id specified by id.
     *
     * @return the next pageto render
     */
    public String deleteScript() {

        final UserTicket ticket = FxContext.getUserTicket();
        if (!ticket.isInRole(Role.ScriptManagement)) {
            new FxFacesMsgErr("Script.err.deletePerm").addToContext();
            return SCRIPT_OVERVIEW;
        }

        ensureScriptIdSet();
        try {
            getScriptingEngine().remove(currentData.id);
            // display updated script list  -->handled via a4j now
            //updateScriptList();  -->handled via a4j now
            new FxFacesMsgInfo("Script.nfo.deleted").addToContext();
        } catch (FxApplicationException e) {
            new FxFacesMsgErr(e).addToContext();
        }
        return SCRIPT_OVERVIEW;
    }

    /**
     * Executes a script, with the id specified by id.
     *
     * @return the next page to render
     */
    public String runScript() {

        final UserTicket ticket = FxContext.getUserTicket();
        if (!ticket.isInRole(Role.ScriptExecution)) {
            new FxFacesMsgErr("Script.err.runPerm").addToContext();
            return SCRIPT_OVERVIEW;
        }

        ensureScriptIdSet();
        try {
            getScriptingEngine().runScript(currentData.id);
            new FxFacesMsgInfo("Script.nfo.executed",
                    CacheAdmin.getEnvironment().getScript(currentData.id).getName()).addToContext();
        } catch (FxApplicationException e) {
            new FxFacesMsgErr(e).addToContext();
        } catch (Throwable t) {
            new FxFacesMsgErr("Script.err.run").addToContext();
        }
        return SCRIPT_OVERVIEW;
    }

    /**
     * Runs the given script code in the console
     */
    public void runScriptInConsole() {
        FxScriptInfoEdit sinfo = currentData.sinfo;
        if (StringUtils.isBlank(sinfo.getCode())) {
            new FxFacesMsgErr("Script.err.noCodeProvided").addToContext();
        } else {
            long start = System.currentTimeMillis();
            try {
                result = ScriptConsoleBean.runScript(sinfo.getCode(), sinfo.getName(), false);
            } catch (Exception e) {
                final StringWriter writer = new StringWriter();
                e.printStackTrace(new PrintWriter(writer));
                final String msg = e.getCause() != null ? e.getCause().getMessage() : e.getMessage();
                result = new Formatter().format("Exception caught: %s%n%s", msg, writer.getBuffer());
            } finally {
                currentData.executionTime = System.currentTimeMillis() - start;
            }
        }
    }

    /**
     * Returns the result object
     *
     * @return Object result
     */
    public Object getResult() {
        return result;
    }

    /**
     * Returns the time (ms) it took to execute the script
     *
     * @return long executionTime
     */
    public long getExecutionTime() {
        return currentData.executionTime;
    }

    /**
     * Creates a new script from the beans data.
     *
     * @return the next jsf page to render
     */
    public String createScript() {
        final UserTicket ticket = FxContext.getUserTicket();
        if (!ticket.isInRole(Role.ScriptManagement)) {
            new FxFacesMsgErr("Script.err.createPerm").addToContext();
            return SCRIPT_OVERVIEW;
        }

        FxScriptInfoEdit sinfo = currentData.sinfo;
        if (StringUtils.isBlank(sinfo.getName()) || sinfo.getEvent() == null) {
            new FxFacesMsgErr("Script.err.createMiss").addToContext();
            return "scriptCreate";
        }

        try {
            if (!isRenderCachedSelect())
                sinfo.setCached(false);
            setId(getScriptingEngine().createScript(sinfo).getId());
            setSinfo(CacheAdmin.getEnvironment().getScript(currentData.id).asEditable());
            // display updated script list
            //updateScriptList();
            new FxFacesMsgInfo("Script.nfo.created", sinfo.getName()).addToContext();
        } catch (FxApplicationException e) {
            new FxFacesMsgErr(e).addToContext();
            return "scriptCreate";
        }
        return SCRIPT_OVERVIEW;
    }

    /**
     * Saves the edited script
     *
     * @return the next page to render
     */
    public String saveScript() {
        final UserTicket ticket = FxContext.getUserTicket();
        if (!ticket.isInRole(Role.ScriptManagement)) {
            new FxFacesMsgErr("Script.err.editPerm").addToContext();
            return null;
        }

        ensureScriptIdSet();

        try {
            FxScriptInfoEdit sinfo = currentData.sinfo;
            getScriptingEngine().updateScriptInfo(
                    new FxScriptInfoEdit(currentData.id, sinfo.getEvent(), sinfo.getName(), sinfo.getDescription(),
                            sinfo.getCode(), sinfo.isActive(), isRenderCachedSelect() && sinfo.isCached()));
            //updateScriptList(); needed (see mandators) ???
            new FxFacesMsgInfo("Script.nfo.updated").addToContext();
            return null;
        } catch (FxApplicationException e) {
            new FxFacesMsgErr(e).addToContext();
            return null;
        }
    }

    /**
     * Returns the list of types which the script is mapped to
     *
     * @return returns the List<Map.Entry<Long, String>> of type mapping names
     */
    public List<Map.Entry<Long, String>> getTypeMappingNames() {
        if (this.currentData.typeMappingNames == null)
            this.currentData.typeMappingNames = new HashMap<Long, String>();
        ArrayList<Map.Entry<Long, String>> list = new ArrayList<Map.Entry<Long, String>>(
                this.currentData.typeMappingNames.entrySet().size());
        for (Map.Entry<Long, String> entry : this.currentData.typeMappingNames.entrySet()) {
            list.add(entry);
        }
        return list;
    }

    /**
     * Returns the list of assignments which the script is mapped to
     *
     * @return returns the List<Map.Entry<Long, String>> of assignment mapping names
     */
    public List<Map.Entry<Long, String>> getAssignmentMappingNames() {
        if (this.currentData.assignmentMappingNames == null)
            this.currentData.assignmentMappingNames = new HashMap<Long, String>();
        ArrayList<Map.Entry<Long, String>> list = new ArrayList<Map.Entry<Long, String>>(
                this.currentData.assignmentMappingNames.entrySet().size());
        for (Map.Entry<Long, String> entry : this.currentData.assignmentMappingNames.entrySet()) {
            list.add(entry);
        }
        return list;
    }

    public FxScriptMapping getMapping() {
        return currentData.mapping;
    }

    public List<WrappedRunOnceInfo> getRunOnceInformation() {
        List<WrappedRunOnceInfo> runInfo = new ArrayList<WrappedRunOnceInfo>();
        try {
            for (FxScriptRunInfo ri : getScriptingEngine().getRunOnceInformation())
                runInfo.add(new WrappedRunOnceInfo(ri));
        } catch (Throwable t) {
            new FxFacesMsgErr(t.getMessage()).addToContext();
        }
        return runInfo;
    }

    public FxScriptRunInfo getCurrentRunInfo() {
        return currentData.currentRunInfo;
    }

    public void setCurrentRunInfo(FxScriptRunInfo currentRunInfo) {
        this.currentData.currentRunInfo = currentRunInfo;
    }

    /**
     * called from the structure editor -> get the oid of the script to show from the request parameters
     *
     * @param e event
     */
    @SuppressWarnings({ "UnusedDeclaration" })
    public void structureListen(ActionEvent e) {
        FacesContext context = FacesContext.getCurrentInstance();
        Map requestParams = context.getExternalContext().getRequestParameterMap();
        long oid = -1;
        if (requestParams.get("oid") != null) {
            oid = Long.parseLong(requestParams.get("oid").toString());
        }
        if (oid != -1) {
            // this specifies the script to work on...
            this.currentData.id = oid;
        }
    }

    public static class WrappedRunOnceInfo {
        private FxScriptRunInfo runInfo;

        public WrappedRunOnceInfo(FxScriptRunInfo runInfo) {
            this.runInfo = runInfo;
        }

        public FxScriptRunInfo getRunInfo() {
            return runInfo;
        }

        public void setRunInfo(FxScriptRunInfo runInfo) {
            this.runInfo = runInfo;
        }

        public String getShortErrorMessage() {
            if (runInfo.getErrorMessage() != null && runInfo.getErrorMessage().length() > 25) {
                return runInfo.getErrorMessage().substring(0, 25) + "..";
            } else
                return runInfo.getErrorMessage();
        }
    }

    /**
     * Sets the error message
     *
     * @param nameErrorMsg String containing the error message
     */
    public void setNameErrorMsg(String nameErrorMsg) {
        this.currentData.nameErrorMsg = nameErrorMsg;
    }

    /**
     * Returns the error message after script name verification
     *
     * @return Returns the error message
     */
    public String getNameErrorMsg() {
        return this.currentData.nameErrorMsg;
    }

    /**
     * Sets the boolean inputFieldDisabled
     *
     * @param inputFieldEnabled boolean value enabling or disabling the input fields
     */
    public void setInputFieldEnabled(boolean inputFieldEnabled) {
        this.currentData.inputFieldEnabled = inputFieldEnabled;
    }

    /**
     * @return boolean inputFieldDisabled
     */
    public boolean isInputFieldEnabled() {
        return this.currentData.inputFieldEnabled;
    }

    /**
     * @param verifyButtonEnabled Sets the verifyButtonEnabled
     */
    public void setVerifyButtonEnabled(boolean verifyButtonEnabled) {
        this.currentData.verifyButtonEnabled = verifyButtonEnabled;
    }

    /**
     * @return Returns true to enable the syntax check button
     */
    public boolean isVerifyButtonEnabled() {
        return this.currentData.verifyButtonEnabled;
    }

    /**
     * @param executeButtonEnabled sets the execute/ run script button
     */
    public void setExecuteButtonEnabled(boolean executeButtonEnabled) {
        this.currentData.executeButtonEnabled = executeButtonEnabled;
    }

    /**
     * @return returns true if the script event is set to FxScriptEvent.Manual
     */
    public boolean isExecuteButtonEnabled() {
        return currentData.executeButtonEnabled;
    }

    /**
     * Check the current script event and set a default if necessary
     */
    public void checkScriptEvent() {
        FxScriptInfoEdit sinfo = currentData.sinfo;
        if (sinfo.getEvent() == null)
            sinfo.setEvent(FxScriptEvent.Manual); // set a default
        currentData.executeButtonEnabled = sinfo.getEvent() == FxScriptEvent.Manual;
    }

    /**
     * Action method to verify the script name (i.e. the file extension) against the available script engines
     * - sets the various boolean field / button enablers
     */
    public void verifyScriptName() {
        final String name = currentData.sinfo.getName();
        if (StringUtils.isBlank(name)) {
            currentData.nameErrorMsg = null;
            currentData.inputFieldEnabled = false;
            currentData.verifyButtonEnabled = false;
            currentData.executeButtonEnabled = false;
        } else if (!FxSharedUtils.isGroovyScript(name) && !checkScriptEngineExtensions(name)) {
            currentData.nameErrorMsg = (MessageBean.getInstance().getMessage("Script.err.name"));
            currentData.inputFieldEnabled = false;
            currentData.verifyButtonEnabled = false;
            currentData.executeButtonEnabled = false;
        } else {
            currentData.nameErrorMsg = null;
            currentData.inputFieldEnabled = true;
            checkScriptEvent();
            // separately enable the Groovy syntax verification button
            if (FxSharedUtils.isGroovyScript(name)) {
                currentData.verifyButtonEnabled = true;
                currentData.language = "gy";
            } else // set language = extension
                currentData.language = name.substring(name.lastIndexOf(".") + 1, name.length());

        }
    }

    /**
     * Checks all available extensions from the ScriptEngineFactory and sets the current language
     *
     * @param scriptName Name of the script
     * @return true if the given script name contains a valid extension found in the scripting engine
     */
    private boolean checkScriptEngineExtensions(String scriptName) {
        try {
            // use scripting engine and avoid JDK6 dependency
            for (String[] engine : EJBLookup.getScriptingEngine().getAvailableScriptEngines()) {
                // check if extension (first element) matches scriptName
                if (scriptName.toLowerCase().endsWith(engine[0])) {
                    return true;
                }
            }
            return false;
        } catch (FxApplicationException e) {
            throw e.asRuntimeException();
        }
    }

    /**
     * Verifies the syntax of a given groovy script
     */
    public void checkScriptSyntax() {
        FxScriptInfoEdit sinfo = currentData.sinfo;
        checkScriptSyntax(sinfo.getName(), sinfo.getCode());
    }

    /**
     * Static method to verify the syntax of a given Groovy script
     *
     * @param name The script name
     * @param code The script code
     */
    static void checkScriptSyntax(String name, String code) {
        if (!FxSharedUtils.isGroovyScript(name) || StringUtils.isBlank(code)) {
            new FxFacesMsgErr("Script.err.verifyFailed", name).addToContext();
        } else {
            try {
                new GroovyShell().parse(code);
                new FxFacesMsgInfo("Script.nfo.scriptVerified").addToContext();
            } catch (Exception e) {
                new FxFacesMsgErr("Script.err.syntaxError").addToContext();
                new FxFacesMsgErr(e).addToContext();
            }
        }
    }

    /**
     * This method adds the default [fleXive] imports for a given script
     * (Configured in Script.properties and Script_de.properties: Script.defaultImports.[script extension],
     * e.g. "Script.defaultImports.groovy")
     * @throws FxApplicationException if the code could not be loaded
     */
    public void addDefaultImports() throws FxApplicationException {
        FxScriptInfoEdit sinfo = currentData.sinfo;
        String code = sinfo.getCode();
        final String name = sinfo.getName();
        if (StringUtils.isNotBlank(name)) {
            sinfo.setCode(getClassImports(name.substring(name.lastIndexOf(".") + 1, name.length())) + code);
        }
    }

    /**
     * This method retrieves the default imports for a given scripttype
     *
     * @param scriptType The type of the script by extension, e.g.: "groovy" or "js"
     * @return Returns the default imports for a scripting engine known by [fleXive]
     */
    static String getClassImports(String scriptType) {
        scriptType = scriptType.replaceAll("gy", "groovy");
        String importProperty = "Script.defaultImports." + scriptType;
        String defImports = "";
        if (!scriptType.equals("")) {
            defImports = MessageBean.getInstance().getMessage(importProperty);
            if (defImports.equals("??" + importProperty + "??")) {
                defImports = "";
                new FxFacesMsgErr("Script.err.noImports", scriptType).addToContext();
            }
        }
        return defImports;
    }

    /**
     * @param userLang set the current user's language
     */
    public void setUserLang(String userLang) {
        this.currentData.userLang = userLang;
    }

    /**
     * @return returns the current user's language
     */
    public String getUserLang() {
        currentData.userLang = FxContext.getUserTicket().getLanguage().getIso2digit();
        return currentData.userLang;
    }

    public boolean isRenderCachedSelect() {
        FxScriptInfoEdit sinfo = currentData.sinfo;
        return sinfo != null && StringUtils.isNotBlank(sinfo.getName())
                && FxSharedUtils.isGroovyScript(sinfo.getName());
    }
}