Package org.joget.apps.app.service

Source Code of org.joget.apps.app.service.AppUtil

package org.joget.apps.app.service;

import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringEscapeUtils;
import org.joget.apps.app.dao.PluginDefaultPropertiesDao;
import org.joget.apps.app.model.AppDefinition;
import org.joget.apps.app.model.HashVariablePlugin;
import org.joget.apps.app.model.PluginDefaultProperties;
import org.joget.apps.userview.model.UserviewTheme;
import org.joget.apps.userview.service.UserviewService;
import org.joget.commons.util.LogUtil;
import org.joget.commons.util.ResourceBundleUtil;
import org.joget.commons.util.SetupManager;
import org.joget.commons.util.StringUtil;
import org.joget.directory.model.User;
import org.joget.directory.model.service.DirectoryManager;
import org.joget.plugin.base.Plugin;
import org.joget.plugin.base.PluginManager;
import org.joget.plugin.property.service.PropertyUtil;
import org.joget.workflow.model.WorkflowAssignment;
import org.joget.workflow.model.WorkflowProcess;
import org.joget.workflow.model.service.WorkflowManager;
import org.joget.workflow.util.WorkflowUtil;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.LocaleResolver;

@Service("appUtil")
public class AppUtil implements ApplicationContextAware {

    public static final String PREFIX_WORKFLOW_VARIABLE = "var_";
    public static final String PROPERTY_WORKFLOW_VARIABLE = "workflowVariable";
    private static final String UI_SESSION_KEY = "UI_SESSION_KEY";
    static ApplicationContext appContext;
    static ThreadLocal currentAppDefinition = new ThreadLocal();
    static ThreadLocal resetAppDefinition = new ThreadLocal();
    static String designerContextPath = "/jwdesigner";

    @Override
    public void setApplicationContext(ApplicationContext ac) throws BeansException {
        appContext = ac;
    }

    public static ApplicationContext getApplicationContext() {
        return appContext;
    }

    public static void setDesignerContextPath(String path) {
        designerContextPath = path;
    }
   
    public static String getDesignerContextPath() {
        return designerContextPath;
    }
   
    /**
     * Ties an AppDefinition to the current thread.
     * @param appDef
     * @throws BeansException
     */
    public static void setCurrentAppDefinition(AppDefinition appDef) throws BeansException {
        currentAppDefinition.set(appDef);
        resetAppDefinition.set(null);
    }

    /**
     * Retrieve the AppDefinition for the current thread.
     * @return null if there is no AppDefinition tied to the current thread.
     */
    public static AppDefinition getCurrentAppDefinition() {
        AppDefinition appDef = (AppDefinition) currentAppDefinition.get();
        return appDef;
    }

    public static void resetAppDefinition() throws BeansException {
        resetAppDefinition.set(Boolean.TRUE);
    }

    public static boolean isAppDefinitionReset() throws BeansException {
        return resetAppDefinition.get() != null;
    }

    /**
     * Converts a String version to its Long equivalent.
     * @param version Null if no specific version is specified, or if there is a number format error.
     * @return
     */
    public static Long convertVersionToLong(String version) {
        Long versionLong = null;
        if (version == null || version.isEmpty() || AppDefinition.VERSION_LATEST.equals(version)) {
        } else {
            // load specific version
            try {
                versionLong = Long.parseLong(version);
            } catch (NumberFormatException e) {
                // TODO: handle exception
            } catch (NullPointerException e) {
                // TODO: handle exception
            }
        }
        return versionLong;
    }

    /**
     * Forms the full process definition ID which includes the package and version.
     * @param appId
     * @param version
     * @param processDefId
     * @return
     */
    public static String getProcessDefIdWithVersion(String appId, String version, String processDefId) {
        String result = null;
        if (processDefId != null && processDefId.indexOf("#") > 0) {
            result = processDefId;
        } else {
            result = appId + "#" + version + "#" + processDefId;
        }
        return result;
    }

    /**
     * Returns the URL to the workflow web designer
     * @param request
     * @return
     */
    public static String getDesignerWebBaseUrl() {
        String defaultContext = getDesignerContextPath();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String serverBaseUrl = (request != null) ? request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() : "";
        String designerWebBaseUrl = WorkflowUtil.getSystemSetupValue("designerwebBaseUrl");
        if (designerWebBaseUrl == null || designerWebBaseUrl.trim().isEmpty() || "/".equals(designerWebBaseUrl)) {
            // use default context
            designerWebBaseUrl = serverBaseUrl + defaultContext;
        } else if (designerWebBaseUrl.startsWith("http")) {
            try {
                // remove trailing slash
                if (designerWebBaseUrl.endsWith("/")) {
                    designerWebBaseUrl = designerWebBaseUrl.substring(0, designerWebBaseUrl.length() - 1);
                }

                // check if context path is specified
                URL url = new URL(designerWebBaseUrl);
                String path = url.getPath();
                if (path == null || path.isEmpty()) {
                    designerWebBaseUrl += defaultContext;
                }
            } catch (Exception ex) {
                // use default context
                designerWebBaseUrl = serverBaseUrl + defaultContext;
            }
        } else {
            // remove preceding slash
            if (designerWebBaseUrl.startsWith("/")) {
                designerWebBaseUrl = designerWebBaseUrl.substring(1);
            }
           
            // prepend base URL
            designerWebBaseUrl = serverBaseUrl + "/" + designerWebBaseUrl;
        }
        return designerWebBaseUrl;
    }

    /**
     * Read workflow variable values from request parameters and populate into a Map
     * @param request
     * @return
     */
    public static Map<String, String> retrieveVariableDataFromRequest(HttpServletRequest request) {
        Map<String, String> variables = new HashMap<String, String>();

        if (request != null) {
            Enumeration<String> enumeration = request.getParameterNames();
            //loop through all parameters to get the workflow variables
            while (enumeration.hasMoreElements()) {
                String paramName = enumeration.nextElement();
                if (paramName.startsWith(PREFIX_WORKFLOW_VARIABLE)) {
                    variables.put(paramName.replace(PREFIX_WORKFLOW_VARIABLE, ""), request.getParameter(paramName));
                }
            }
        }
        return variables;
    }

    /**
     * Read workflow variable values from a Map and populate into another Map
     * @param parameters
     * @return
     */
    public static Map<String, String> retrieveVariableDataFromMap(Map parameters) {
        Map<String, String> variables = new HashMap<String, String>();

        if (parameters != null) {
            for (Iterator i = parameters.keySet().iterator(); i.hasNext();) {
                String paramName = (String) i.next();
                if (paramName.startsWith(PREFIX_WORKFLOW_VARIABLE)) {
                    variables.put(paramName.replace(PREFIX_WORKFLOW_VARIABLE, ""), (String) parameters.get(paramName));
                }
            }
        }
        return variables;
    }

    /**
     * Read locale from Setup
     * @param
     * @return
     */
    public static String getAppLocale() {
        LocaleResolver localeResolver = (LocaleResolver) appContext.getBean("localeResolver");
        return localeResolver.resolveLocale(WorkflowUtil.getHttpServletRequest()).toString();
    }

    public static String getAppDateFormat() {
        SetupManager setupManager = (SetupManager) AppUtil.getApplicationContext().getBean("setupManager");

        if ("true".equalsIgnoreCase(setupManager.getSettingValue("dateFormatFollowLocale"))) {
            Locale locale = new Locale(getAppLocale());
            DateFormat dateInstance = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);
            if (dateInstance instanceof SimpleDateFormat) {
                return ((SimpleDateFormat) dateInstance).toPattern();
            }
        }

        return null;
    }

    /**
     * Convenience method to retrieve the current request context path
     * @return
     */
    public static String getRequestContextPath() {
        HttpServletRequest request = WorkflowUtil.getHttpServletRequest();
        String url = (request != null) ? request.getContextPath() : "";
        return url;
    }

    /**
     * Reads a resource from a plugin
     * @param pluginName
     * @param resourceUrl
     * @return null if the resource is not found or in the case of an exception
     */
    public static String readPluginResource(String pluginName, String resourceUrl) {
        return readPluginResource(pluginName, resourceUrl, null, false, null);
    }

    /**
     * Reads a resource from a plugin. java.util.Formatter text patterns supported.
     * @param pluginName
     * @param resourceUrl
     * @param arguments
     * @param removeNewLines
     * @return null if the resource is not found or in the case of an exception
     * @see java.util.Formatter
     */
    public static String readPluginResource(String pluginName, String resourceUrl, Object[] arguments, boolean removeNewLines) {
        return readPluginResource(pluginName, resourceUrl, arguments, removeNewLines, null);
    }

    /**
     * Reads a resource from a plugin. java.util.Formatter text patterns supported.
     * @param pluginName
     * @param resourceUrl
     * @param arguments
     * @param removeNewLines
     * @param translationFileName
     * @return null if the resource is not found or in the case of an exception
     * @see java.util.Formatter
     */
    public static String readPluginResource(String pluginName, String resourceUrl, Object[] arguments, boolean removeNewLines, String translationFileName) {
        String output = null;
        if (pluginName != null && resourceUrl != null) {
            PluginManager pluginManager = (PluginManager) appContext.getBean("pluginManager");
            output = pluginManager.readPluginResourceAsString(pluginName, resourceUrl, arguments, removeNewLines, translationFileName);
        }
        // replace app path
        if (output != null && !output.isEmpty()) {
            String appPath = "";
            AppDefinition appDef = AppUtil.getCurrentAppDefinition();
            if (appDef != null) {
                appPath = "/" + appDef.getAppId() + "/" + appDef.getVersion();
            }
            output = output.replaceAll("\\[APP_PATH\\]", appPath);
        }
        return output;
    }

    public static String processHashVariable(String content, WorkflowAssignment wfAssignment, String escapeFormat, Map<String, String> replaceMap) {
        return processHashVariable(content, wfAssignment, escapeFormat, replaceMap, null);
    }

    public static String processHashVariable(String content, WorkflowAssignment wfAssignment, String escapeFormat, Map<String, String> replaceMap, AppDefinition appDef) {
        content = StringUtil.decryptContent(content);
       
        // check for hash # to avoid unnecessary processing
        if (!containsHashVariable(content)) {
            return content;
        }

        //parse content
        if (content != null) {
            Pattern pattern = Pattern.compile("\\#([^#^\"^ ])*\\.([^#^\"])*\\#");
            Matcher matcher = pattern.matcher(content);
            Set<String> varList = new HashSet<String>();
            while (matcher.find()) {
                varList.add(matcher.group());
            }

            try {
                if (!varList.isEmpty()) {
                    PluginManager pluginManager = (PluginManager) appContext.getBean("pluginManager");
                    PluginDefaultPropertiesDao pluginDefaultPropertiesDao = (PluginDefaultPropertiesDao) appContext.getBean("pluginDefaultPropertiesDao");
                    Collection<Plugin> pluginList = pluginManager.list(HashVariablePlugin.class);
                    Map <String, HashVariablePlugin> hashVariablePluginCache = new HashMap<String, HashVariablePlugin>();

                    for (String var : varList) {
                        String tempVar = var.replaceAll("#", "");

                        for (Plugin p : pluginList) {
                            HashVariablePlugin hashVariablePlugin = (HashVariablePlugin) p;
                            if (tempVar.startsWith(hashVariablePlugin.getPrefix() + ".")) {
                                tempVar = tempVar.replaceFirst(hashVariablePlugin.getPrefix() + ".", "");

                                HashVariablePlugin cachedPlugin = hashVariablePluginCache.get(hashVariablePlugin.getClassName());
                                if (cachedPlugin == null) {
                                    cachedPlugin = (HashVariablePlugin) pluginManager.getPlugin(hashVariablePlugin.getClassName());
                                    //get default plugin properties

                                    if (appDef == null) {
                                        appDef = AppUtil.getCurrentAppDefinition();
                                    }
                                    PluginDefaultProperties pluginDefaultProperties = pluginDefaultPropertiesDao.loadById(cachedPlugin.getClassName(), appDef);
                                    if (pluginDefaultProperties != null && pluginDefaultProperties.getPluginProperties() != null && pluginDefaultProperties.getPluginProperties().trim().length() > 0) {
                                        cachedPlugin.setProperties(PropertyUtil.getPropertiesValueFromJson(pluginDefaultProperties.getPluginProperties()));
                                    }

                                    //put appDef & wfAssignment to properties
                                    cachedPlugin.setProperty("appDefinition", appDef);
                                    cachedPlugin.setProperty("workflowAssignment", wfAssignment);
                                    hashVariablePluginCache.put(hashVariablePlugin.getClassName(), cachedPlugin);
                                }

                                String nestedHashVar = tempVar;
                                       
                                //process nested hash
                                while (nestedHashVar.contains("{") && nestedHashVar.contains("}")) {
                                    Pattern nestedPattern = Pattern.compile("\\{([^\\{^\\}])*\\}");
                                    Matcher nestedMatcher = nestedPattern.matcher(nestedHashVar);
                                    while (nestedMatcher.find()) {
                                        String nestedHash = nestedMatcher.group();
                                        String nestedHashString = nestedHash.replace("{", "#");
                                        nestedHashString = nestedHashString.replace("}", "#");

                                        String processedNestedHashValue = processHashVariable(nestedHashString, wfAssignment, escapeFormat, replaceMap, appDef);
                                       
                                        //if being process
                                        if (!nestedHashString.equals(processedNestedHashValue)) {
                                            tempVar = tempVar.replaceAll(StringUtil.escapeString(nestedHash, StringUtil.TYPE_REGEX, null), StringUtil.escapeString(processedNestedHashValue, escapeFormat, replaceMap));
                                        }
                                       
                                        //remove nested hash
                                        nestedHashVar = nestedHashVar.replaceAll(StringUtil.escapeString(nestedHash, StringUtil.TYPE_REGEX, null), StringUtil.escapeString(processedNestedHashValue, escapeFormat, replaceMap));
                                    }
                                }

                                //unescape hash variable
                                tempVar = StringEscapeUtils.unescapeJavaScript(tempVar);

                                //get result from plugin
                                String value = cachedPlugin.processHashVariable(tempVar);

                                if (value != null && !StringUtil.TYPE_REGEX.equals(escapeFormat) && !StringUtil.TYPE_JSON.equals(escapeFormat)) {
                                    value = StringUtil.escapeRegex(value);
                                }

                                //escape special char in HashVariable
                                var = cachedPlugin.escapeHashVariable(var);

                                //replace
                                if (value != null) {
                                    // clean to prevent XSS
                                    value = StringUtil.stripHtmlRelaxed(value);

                                    content = content.replaceAll(var, StringUtil.escapeString(value, escapeFormat, replaceMap));
                                }
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                LogUtil.error(AppUtil.class.getName(), ex, "");
            }
        }
        return content;
    }

    public static boolean containsHashVariable(String content) {
        boolean result = (content != null && content.indexOf("#") >= 0);
        return result;
    }

    public static Collection<String> getEmailList(String toParticipantId, String toSpecific, WorkflowAssignment wfAssignment, AppDefinition appDef) {
        Collection<String> addresses = new HashSet<String>();
        Collection<String> users = new HashSet<String>();

        if (toParticipantId != null && !toParticipantId.isEmpty() && wfAssignment != null) {
            WorkflowManager workflowManager = (WorkflowManager) AppUtil.getApplicationContext().getBean("workflowManager");
            WorkflowProcess process = workflowManager.getProcess(wfAssignment.getProcessDefId());
            toParticipantId = toParticipantId.replace(";", ",");
            String pIds[] = toParticipantId.split(",");
            for (String pId : pIds) {
                pId = pId.trim();
                if (pId.length() == 0) {
                    continue;
                }

                Collection<String> userList = null;
                userList = WorkflowUtil.getAssignmentUsers(process.getPackageId(), wfAssignment.getProcessDefId(), wfAssignment.getProcessId(), wfAssignment.getProcessVersion(), wfAssignment.getActivityId(), "", pId.trim());

                if (userList != null && userList.size() > 0) {
                    users.addAll(userList);
                }
            }
        }

        if (toSpecific != null && toSpecific.trim().length() != 0) {
            toSpecific = AppUtil.processHashVariable(toSpecific, wfAssignment, null, null, appDef);
            toSpecific = toSpecific.replace(";", ","); // add support for MS-style semi-colon (;) as a delimiter
            String emailList[] = toSpecific.split(",");
            for (String email : emailList) {
                email = email.trim();
                if (email.length() == 0) {
                    continue;
                }

                //to support retrieve email by putting username
                if (!email.contains("@")) {
                    users.add(email);
                } else {
                    addresses.add(email);
                }
            }
        }

        if (!users.isEmpty()) {
            DirectoryManager directoryManager = (DirectoryManager) AppUtil.getApplicationContext().getBean("directoryManager");
            for (String username : users) {
                try {
                    User user = directoryManager.getUserByUsername(username);
                    if (user != null) {
                        String userEmail = user.getEmail().replace(";", ",");
                        String userEmails[] = userEmail.split(",");
                        for (String email : userEmails) {
                            email = email.trim();
                            if (email.length() == 0) {
                                continue;
                            }
                            addresses.add(email);
                        }
                    }
                } catch (Exception e) {}
            }
        }

        return addresses;
    }

    /**
     * Checks system settings whether front-end quick edit is enabled.
     * @return
     */
    public static boolean isQuickEditEnabled() {
        String settingValue = null;
       
        // lookup cache in request
        HttpServletRequest request = WorkflowUtil.getHttpServletRequest();
        if (request != null) {
            settingValue = (String)request.getAttribute("disableAdminBar");
        }
        if (settingValue == null) {
            // get from SetupManager
            SetupManager setupManager = (SetupManager) AppUtil.getApplicationContext().getBean("setupManager");
            settingValue = setupManager.getSettingValue("disableAdminBar");
            if (settingValue == null) {
                settingValue = "false";
            }
            if (request != null) {
                // cache value in request
                request.setAttribute("disableAdminBar", settingValue);
            }
        }
        boolean enabled = !"true".equals(settingValue);
        return enabled;
    }
   
    /**
     * Returns the current system version.
     * @since 3.2
     * @return
     */
    public static String getSystemVersion() {
        String version = ResourceBundleUtil.getMessage("console.footer.label.revision");
        return version;
    }

    public static void setSystemAlert(String value) {
        HttpServletRequest request = WorkflowUtil.getHttpServletRequest();
        if (request != null) {
            HttpSession session = request.getSession(true);
            if (session != null) {
                String[] values = (String[]) session.getAttribute(UI_SESSION_KEY);
                Collection<String> sessionValues = new ArrayList<String>();
                if (values != null && values.length > 0) {
                    sessionValues.addAll(Arrays.asList(values));
                }
                sessionValues.add(value);
                session.setAttribute(UI_SESSION_KEY, sessionValues.toArray(new String[0]));
            }
        }
    }

    public static String getSystemAlert() {
        String script = "";
        HttpServletRequest request = WorkflowUtil.getHttpServletRequest();
        if (request != null) {
            HttpSession session = request.getSession(true);
            if (session != null) {
                String[] values = (String[]) session.getAttribute(UI_SESSION_KEY);
                if (values != null && values.length > 0) {
                    session.removeAttribute(UI_SESSION_KEY);

                    for (String v : values) {
                        script += v;
                    }
                }
            }
        }
        return script;
    }
   
    public static String getUserviewThemeCss() {
        HttpServletRequest request = WorkflowUtil.getHttpServletRequest();
        if (request != null
                && request.getParameterValues("__a_") != null && request.getParameterValues("__a_").length > 0
                && request.getParameterValues("__u_") != null && request.getParameterValues("__u_").length > 0) {
            try {
                String appId = request.getParameterValues("__a_")[0];
                String uId = request.getParameterValues("__u_")[0];

                if (!appId.isEmpty() && !uId.isEmpty()) {
                    UserviewService userviewService = (UserviewService) appContext.getBean("userviewService");
                    UserviewTheme theme = userviewService.getUserviewTheme(appId, uId);

                    if (theme != null && theme.getCss() != null) {
                        return theme.getCss();
                    }
                }
            } catch (Exception e) {
                LogUtil.error(AppUtil.class.getName(), e, "getUserviewThemeCss Error!");
            }
        }
       
        return "";
    }
}
TOP

Related Classes of org.joget.apps.app.service.AppUtil

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.