cmsmacroresolver.java

来自「找了很久才找到到源代码」· Java 代码 · 共 827 行 · 第 1/3 页

JAVA
827
字号
     * Resolves the macros in the given input using the provided parameters.<p>
     * 
     * A macro in the form <code>%(key)</code> or <code>${key}</code> in the content is replaced with it's assigned value
     * returned by the <code>{@link I_CmsMacroResolver#getMacroValue(String)}</code> method of the given 
     * <code>{@link I_CmsMacroResolver}</code> instance.<p>
     * 
     * If a macro is found that can not be mapped to a value by the given macro resolver,
     * it is left untouched in the input.<p>
     * 
     * @param input the input in which to resolve the macros
     * @param cms the OpenCms user context to use when resolving macros
     * @param messages the message resource bundle to use when resolving macros
     * 
     * @return the input with the macros resolved
     */
    public static String resolveMacros(String input, CmsObject cms, CmsMessages messages) {

        CmsMacroResolver resolver = new CmsMacroResolver();
        resolver.m_cms = cms;
        resolver.m_messages = messages;
        resolver.m_keepEmptyMacros = true;
        return resolver.resolveMacros(input);
    }

    /**
     * Resolves macros in the provided input String using the given macro resolver.<p>
     * 
     * A macro in the form <code>%(key)</code> or <code>${key}</code> in the content is replaced with it's assigned value
     * returned by the <code>{@link I_CmsMacroResolver#getMacroValue(String)}</code> method of the given 
     * <code>{@link I_CmsMacroResolver}</code> instance.<p>
     * 
     * If a macro is found that can not be mapped to a value by the given macro resolver,
     * <code>{@link I_CmsMacroResolver#isKeepEmptyMacros()}</code> controls if the macro is replaced by
     * an empty String, or is left untoched in the input.<p>
     * 
     * @param input the input in which to resolve the macros
     * @param resolver the macro resolver to use
     * 
     * @return the input with all macros resolved
     */
    public static String resolveMacros(final String input, I_CmsMacroResolver resolver) {

        if ((input == null) || (input.length() < 3)) {
            // macro must have at last 3 chars "${}" or "%()"
            return input;
        }

        int pn = input.indexOf(I_CmsMacroResolver.MACRO_DELIMITER);
        int po = input.indexOf(I_CmsMacroResolver.MACRO_DELIMITER_OLD);

        if ((po == -1) && (pn == -1)) {
            // no macro delimiter found in input
            return input;
        }

        int len = input.length();
        StringBuffer result = new StringBuffer(len << 1);
        int np, pp1, pp2, e;
        String macro, value;
        boolean keep = resolver.isKeepEmptyMacros();
        boolean resolvedNone = true;
        char ds, de;
        int p;

        if ((po == -1) || ((pn > -1) && (pn < po))) {
            p = pn;
            ds = I_CmsMacroResolver.MACRO_START;
            de = I_CmsMacroResolver.MACRO_END;
        } else {
            p = po;
            ds = I_CmsMacroResolver.MACRO_START_OLD;
            de = I_CmsMacroResolver.MACRO_END_OLD;
        }

        // append chars before the first delimiter found
        result.append(input.substring(0, p));
        do {
            pp1 = p + 1;
            pp2 = pp1 + 1;
            if (pp2 >= len) {
                // remaining chars can't be a macro (minumum size is 3)
                result.append(input.substring(p, len));
                break;
            }
            // get the next macro delimiter
            if ((pn > -1) && (pn < pp1)) {
                pn = input.indexOf(I_CmsMacroResolver.MACRO_DELIMITER, pp1);
            }
            if ((po > -1) && (po < pp1)) {
                po = input.indexOf(I_CmsMacroResolver.MACRO_DELIMITER_OLD, pp1);
            }
            if ((po == -1) && (pn == -1)) {
                // none found, make sure remaining chars in this segement are appended
                np = len;
            } else {
                // check if the next delimiter is old or new style
                if ((po == -1) || ((pn > -1) && (pn < po))) {
                    np = pn;
                } else {
                    np = po;
                }
            }
            // check if the next char is a "macro start"
            char st = input.charAt(pp1);
            if (st == ds) {
                // we have a starting macro sequence "${" or "%(", now check if this segment contains a "}" or ")"
                e = input.indexOf(de, p);
                if ((e > 0) && (e < np)) {
                    // this segment contains a closing macro delimiter "}" or "]", so we may have found a macro
                    macro = input.substring(pp2, e);
                    // resolve macro
                    value = resolver.getMacroValue(macro);
                    e++;
                    if (value != null) {
                        // macro was successfully resolved
                        result.append(value);
                        resolvedNone = false;
                    } else if (keep) {
                        // macro was unknown, but should be kept
                        result.append(input.substring(p, e));
                    }
                } else {
                    // no complete macro "${...}" or "%(...)" in this segment
                    e = p;
                }
            } else {
                // no macro start char after the "$" or "%"
                e = p;
            }
            // adpot macro style for next delimiter found
            if (np == pn) {
                ds = I_CmsMacroResolver.MACRO_START;
                de = I_CmsMacroResolver.MACRO_END;
            } else {
                ds = I_CmsMacroResolver.MACRO_START_OLD;
                de = I_CmsMacroResolver.MACRO_END_OLD;
            }
            // append the remaining chars after the macro to the start of the next macro
            result.append(input.substring(e, np));
            // this is a nerdy joke ;-)
            p = np;
        } while (p < len);

        if (resolvedNone && keep) {
            // nothing was resolved and macros should be kept, return original input
            return input;
        }

        // input was changed during resolving of macros
        return result.toString();
    }

    /**
     * Strips the macro delimiters from the given input, 
     * for example <code>%(key)</code> or <code>${key}</code> becomes <code>key</code>.<p>
     * 
     * In case the input is not a macro, <code>null</code> is returned.<p>
     * 
     * @param input the input to strip
     * 
     * @return the macro stripped from the input, or <code>null</code>
     */
    public static String stripMacro(String input) {

        if (isMacro(input)) {
            return input.substring(2, input.length() - 1);
        }
        return null;
    }

    /**
     * Adds a customized macro to this macro resolver.<p>
     * 
     * @param key the macro to add
     * @param value the value to return if the macro is encountered
     */
    public void addMacro(String key, String value) {

        if (m_additionalMacros == null) {
            // use lazy initializing
            m_additionalMacros = new HashMap();
        }
        m_additionalMacros.put(key, value);
    }

    /**
     * @see org.opencms.util.I_CmsMacroResolver#getMacroValue(java.lang.String)
     */
    public String getMacroValue(String macro) {

        if (m_messages != null) {
            if (macro.startsWith(CmsMacroResolver.KEY_LOCALIZED_PREFIX)) {
                String keyName = macro.substring(CmsMacroResolver.KEY_LOCALIZED_PREFIX.length());
                return m_messages.keyWithParams(keyName);
            }
        }

        if (m_jspPageContext != null) {

            if (macro.startsWith(CmsMacroResolver.KEY_REQUEST_PARAM)) {
                // the key is a request parameter  
                macro = macro.substring(CmsMacroResolver.KEY_REQUEST_PARAM.length());
                String result = m_jspPageContext.getRequest().getParameter(macro);
                if (result == null && macro.equals(KEY_PROJECT_ID)) {
                    result = m_cms.getRequestContext().currentProject().getUuid().toString();
                }
                return result;
            }

            if (macro.startsWith(CmsMacroResolver.KEY_PAGE_CONTEXT)) {
                // the key is a page context object
                macro = macro.substring(CmsMacroResolver.KEY_PAGE_CONTEXT.length());
                int scope = m_jspPageContext.getAttributesScope(macro);
                return m_jspPageContext.getAttribute(macro, scope).toString();
            }

            if ((m_cms != null) && macro.startsWith(CmsMacroResolver.KEY_PROPERTY_ELEMENT)) {

                // the key is a cms property to be read on the current element

                macro = macro.substring(CmsMacroResolver.KEY_PROPERTY_ELEMENT.length());
                CmsFlexController controller = CmsFlexController.getController(m_jspPageContext.getRequest());
                try {
                    CmsProperty property = m_cms.readPropertyObject(
                        controller.getCurrentRequest().getElementUri(),
                        macro,
                        false);
                    if (property != CmsProperty.getNullProperty()) {
                        return property.getValue();
                    }
                } catch (CmsException e) {
                    if (LOG.isWarnEnabled()) {
                        LOG.warn(Messages.get().getBundle().key(
                            Messages.LOG_PROPERTY_READING_FAILED_2,
                            macro,
                            controller.getCurrentRequest().getElementUri()), e);
                    }
                }
            }
        }

        if (m_cms != null) {

            if (macro.startsWith(CmsMacroResolver.KEY_PROPERTY)) {
                // the key is a cms property to be read on the current request URI
                macro = macro.substring(CmsMacroResolver.KEY_PROPERTY.length());
                try {
                    CmsProperty property = m_cms.readPropertyObject(m_cms.getRequestContext().getUri(), macro, true);
                    if (property != CmsProperty.getNullProperty()) {
                        return property.getValue();
                    }
                } catch (CmsException e) {
                    if (LOG.isWarnEnabled()) {
                        CmsMessageContainer message = Messages.get().container(
                            Messages.LOG_PROPERTY_READING_FAILED_2,
                            macro,
                            m_cms.getRequestContext().getUri());
                        LOG.warn(message.key(), e);
                    }
                }
                return null;
            }

            if (macro.startsWith(CmsMacroResolver.KEY_ATTRIBUTE)) {
                // the key is an OpenCms runtime attribute
                macro = macro.substring(CmsMacroResolver.KEY_ATTRIBUTE.length());
                Object attribute = m_cms.getRequestContext().getAttribute(macro);
                if (attribute != null) {
                    return attribute.toString();
                }
                return null;
            }

            if (macro.startsWith(CmsMacroResolver.KEY_OPENCMS)) {

                // the key is a shortcut for a cms runtime value

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?