package com.psddev.cms.db; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import com.psddev.dari.db.Reference; import com.psddev.dari.db.ReferentialText; import com.psddev.dari.db.State; import com.psddev.dari.util.CodeUtils; import com.psddev.dari.util.HtmlGrid; import com.psddev.dari.util.JspUtils; import com.psddev.dari.util.ObjectUtils; import com.psddev.dari.util.PageContextFilter; import com.psddev.dari.util.Settings; import com.psddev.dari.util.StorageItem; import com.psddev.dari.util.StringUtils; import com.psddev.dari.util.UrlBuilder; public final class ElFunctionUtils { private ElFunctionUtils() { } /** * Escapes the given {@code string} so that it's safe to use in HTML. * * @param string If {@code null}, returns an empty string. * @return Never {@code null}. */ public static String html(String string) { return string != null ? StringUtils.escapeHtml(string) : ""; } /** * Returns {@code true} if the current request is in the given * {@code context}. * * @param context If {@code null}, returns {@code false}. * @see ContextTag.Static#isInContext */ public static boolean inContext(String context) { return ContextTag.Static.isInContext(PageContextFilter.Static.getRequest(), context); } /** * Returns {@code true} if the given {@code object} is an instance of the * class represented by the given {@code className}. * * @throws IllegalArgumentException If there isn't a class with the given * {@code className}. */ public static boolean instanceOf(Object object, String className) { Class<?> c = ObjectUtils.getClassByName(className); if (c != null) { return c.isInstance(object); } else { throw new IllegalArgumentException(String.format( "[%s] is not a valid class name!", className)); } } /** * Escapes the given {@code string} so that it's safe to use in * JavaScript. * * @param string If {@code null}, returns an empty string. * @return Never {@code null}. */ public static String js(String string) { return string != null ? StringUtils.escapeJavaScript(string) : ""; } public static List<String> listLayouts(Object object, String field) { return object != null ? State.getInstance(object).as(Renderer.Data.class).getListLayouts().get(field) : null; } /** * Returns the number of markers with the given {@code markerInternalName} * in the given {@code text}. * * @param text If {@code null}, returns {@code 0}. * @param markerInternalName If blank, returns {@code 0}. */ public static int markerCount(ReferentialText text, String markerInternalName) { int count = 0; if (text != null && !ObjectUtils.isBlank(markerInternalName)) { for (Object item : text) { if (item instanceof Reference) { Object referenced = ((Reference) item).getObject(); if (referenced instanceof ReferentialTextMarker && (((ReferentialTextMarker) referenced).getInternalName().equals(markerInternalName))) { ++ count; } } } } return count; } /** * Returns the plain {@linkplain StorageItem CDN} URL associated * with the given {@code servletPath}. */ public static String plainResource(String servletPath) { ServletContext servletContext = null; HttpServletRequest request = null; try { servletContext = PageContextFilter.Static.getServletContext(); request = PageContextFilter.Static.getRequest(); } catch (IllegalStateException ex) { // Checked for nulls right below. } if (servletContext != null && request != null) { HtmlGrid.Static.addStyleSheet(request, servletPath); if (ObjectUtils.coalesce( Settings.get(Boolean.class, "cms/isResourceInStorage"), Settings.isProduction())) { StorageItem item = StorageItem.Static.getPlainResource(null, servletContext, servletPath); if (item != null) { return JspUtils.isSecure(request) ? item.getSecurePublicUrl() : item.getPublicUrl(); } } } return pathWithTimestamp(servletContext, request, servletPath); } private static String pathWithTimestamp(ServletContext context, HttpServletRequest request, String path) { if (context != null) { try { URL resource = CodeUtils.getResource(context, path); if (resource != null) { URLConnection resourceConnection = resource.openConnection(); InputStream resourceInput = resourceConnection.getInputStream(); try { String contextPath = request != null ? request.getContextPath() : ""; return StringUtils.addQueryParameters( contextPath + StringUtils.ensureStart(path, "/"), "_", resourceConnection.getLastModified()); } finally { resourceInput.close(); } } } catch (IOException error) { // Ignore any errors and just return the path as is. } } return path; } /** * Returns the plain or gzipped {@linkplain StorageItem CDN} URL * associated with the given {@code servletPath}. */ public static String resource(String servletPath) { ServletContext servletContext = null; HttpServletRequest request = null; try { servletContext = PageContextFilter.Static.getServletContext(); request = PageContextFilter.Static.getRequest(); } catch (IllegalStateException ex) { // Checked for nulls right below. } if (servletContext != null && request != null) { HtmlGrid.Static.addStyleSheet(request, servletPath); if (ObjectUtils.coalesce( Settings.get(Boolean.class, "cms/isResourceInStorage"), Settings.isProduction())) { String encodings = request.getHeader("Accept-Encoding"); StorageItem item = ObjectUtils.isBlank(encodings) || !encodings.contains("gzip") ? StorageItem.Static.getPlainResource(null, servletContext, servletPath) : StorageItem.Static.getGzippedResource(null, servletContext, servletPath); if (item != null) { return JspUtils.isSecure(request) ? item.getSecurePublicUrl() : item.getPublicUrl(); } } } return pathWithTimestamp(servletContext, request, servletPath); } public static UrlBuilder absolutePath(String path) { return new UrlBuilder(PageContextFilter.Static.getRequest()).absolutePath(path); } public static UrlBuilder currentPath() { return new UrlBuilder(PageContextFilter.Static.getRequest()).currentPath(); } public static UrlBuilder path(String path) { return new UrlBuilder(PageContextFilter.Static.getRequest()).path(path); } }