package org.fenixedu.bennu.portal.servlet; import java.io.InputStream; import java.util.Locale; import java.util.Set; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.fenixedu.bennu.core.api.json.AuthenticatedUserViewer; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.i18n.BundleUtil; import org.fenixedu.bennu.core.rest.BennuRestResource; import org.fenixedu.bennu.core.security.Authenticate; import org.fenixedu.bennu.core.util.CoreConfiguration; import org.fenixedu.bennu.core.util.CoreConfiguration.ConfigurationProperties; import org.fenixedu.bennu.portal.domain.MenuFunctionality; import org.fenixedu.bennu.portal.domain.PortalConfiguration; import org.fenixedu.commons.i18n.I18N; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * The goal of this bean is to allow easy injection of Bennu Portal variables in JSP pages. * * Refer to each individual method for its documentation. * * @author João Carvalho (joao.pedro.carvalho@tecnico.ulisboa.pt) * */ public class PortalBean { private final String ctxPath; private static final Logger LOGGER = LoggerFactory.getLogger(PortalBean.class); public PortalBean(ServletContext servletContext) { this.ctxPath = servletContext.getContextPath(); } /** * Injects a Javascript context with contains the {@code Bennu} variable, which is a subset * of the Bennu Portal Data REST API, containing information about the configured locales, the current * locale, as well as some information regarding the currently logged user. * * If also sets up the {@code contextPath} variable, which contains the configured context path of the * application. * * @return * A {@code <script>} tag containing the {@code Bennu} and {@code contextPath} variables. */ public String bennuPortal() { StringBuilder builder = new StringBuilder(); builder.append("<script>"); { builder.append("window.Bennu = "); builder.append(BennuRestResource.getBuilder().view(null, Void.class, AuthenticatedUserViewer.class)).append(";"); } { builder.append("window.contextPath = '").append(ctxPath).append("';"); } builder.append("</script>"); return builder.toString(); } private static String DEBUG_TOOLKIT_TAG = null; private static String DEBUG_TOOLKIT_ANGULAR_TAG = null; private NodeList getFilesForId(String id) throws Exception { try (InputStream is = this.getClass().getResource("/META-INF/maven/org.fenixedu/bennu-toolkit/pom.xml").openStream()) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder b = factory.newDocumentBuilder(); Document doc = b.parse(is); XPathFactory xPathfactory = XPathFactory.newInstance(); XPath xpath = xPathfactory.newXPath(); XPathExpression expr = xpath.compile("//project/build/plugins/plugin/executions/execution[id = '" + id + "']/configuration/jsSourceFiles/jsSourceFile"); Object result = expr.evaluate(doc, XPathConstants.NODESET); return (NodeList) result; } } private String getDebugToolkit() { if (DEBUG_TOOLKIT_TAG == null) { try { NodeList nodes = getFilesForId("toolkit"); StringBuilder builder = new StringBuilder(); builder.append("<link href=\"").append(ctxPath).append("/bennu-toolkit/css/toolkit.css\" rel=\"stylesheet\"/>"); for (int i = 0; i < nodes.getLength(); i++) { Node currentItem = nodes.item(i); builder.append("<script type=\"text/javascript\" src=\"").append(ctxPath).append("/bennu-toolkit/js/") .append(currentItem.getTextContent()).append("\"></script>"); } DEBUG_TOOLKIT_TAG = builder.toString(); } catch (Exception e) { LOGGER.warn("Error resolving the portal POM, falling back into compiled toolkit"); return getToolkit(); } } return bennuPortal() + DEBUG_TOOLKIT_TAG; } private String getDebugToolkitAngular() { if (DEBUG_TOOLKIT_ANGULAR_TAG == null) { try { NodeList nodes = getFilesForId("toolkit-angular"); StringBuilder builder = new StringBuilder(); builder.append("<link href=\"").append(ctxPath).append("/bennu-toolkit/css/toolkit.css\" rel=\"stylesheet\"/>"); builder.append("<script type=\"text/javascript\" src=\"").append(ctxPath) .append("/bennu-portal/js/angular.min.js\"></script>"); for (int i = 0; i < nodes.getLength(); i++) { Node currentItem = nodes.item(i); builder.append("<script type=\"text/javascript\" src=\"").append(ctxPath).append("/bennu-toolkit/js/") .append(currentItem.getTextContent()).append("\"></script>"); } DEBUG_TOOLKIT_ANGULAR_TAG = builder.toString(); } catch (Exception e) { LOGGER.warn("Error resolving the portal POM, falling back into compiled toolkit"); return getAngularToolkit(); } } return bennuPortal() + DEBUG_TOOLKIT_ANGULAR_TAG; } private String getToolkit() { StringBuilder builder = new StringBuilder(bennuPortal()); builder.append("<link href=\"").append(ctxPath).append("/bennu-toolkit/css/toolkit.css\" rel=\"stylesheet\"/>"); builder.append("<script type=\"text/javascript\" src=\"").append(ctxPath) .append("/bennu-toolkit/js/toolkit.js\"></script>"); return builder.toString(); } private String getAngularToolkit() { StringBuilder builder = new StringBuilder(bennuPortal()); builder.append("<link href=\"").append(ctxPath).append("/bennu-toolkit/css/toolkit.css\" rel=\"stylesheet\"/>"); builder.append("<script type=\"text/javascript\" src=\"").append(ctxPath) .append("/bennu-portal/js/angular.min.js\"></script>"); builder.append("<script type=\"text/javascript\" src=\"").append(ctxPath) .append("/bennu-toolkit/js/toolkit-angular.js\"></script>"); return builder.toString(); } public String toolkit() { if (CoreConfiguration.getConfiguration().developmentMode()) { return getDebugToolkit(); } else { return getToolkit(); } } public String angularToolkit() { if (CoreConfiguration.getConfiguration().developmentMode()) { return getDebugToolkitAngular(); } else { return getAngularToolkit(); } } /** * Returns the current instance of {@link PortalConfiguration}, providing access to application configuration. * * @return * The {@link PortalConfiguration} instance. */ public PortalConfiguration getConfiguration() { return PortalConfiguration.getInstance(); } /** * Returns the current locale, as defined by {@link I18N#getLocale()}. * * @return * The current locale. */ public Locale getLocale() { return I18N.getLocale(); } /** * Returns all the configured locales for this application, as defined by {@link CoreConfiguration#supportedLocales()}. * * @return * All the configured locales for this application. */ public Set<Locale> getSupportedLocales() { return CoreConfiguration.supportedLocales(); } /** * Determines whether the application is in development mode. * * @return * Whether the application is in development mode. */ public boolean getDevMode() { return CoreConfiguration.getConfiguration().developmentMode(); } /** * Returns the current user, as determined by {@link Authenticate#getUser()}. * * @return * The current user. */ public User getCurrentUser() { return Authenticate.getUser(); } /** * Returns the selected functionality for the current request, as determined by * {@link BennuPortalDispatcher#getSelectedFunctionality(HttpServletRequest)}. * * @param request * The request for which to return the functionality. * @return * The selected functionality. */ public MenuFunctionality selectedFunctionality(HttpServletRequest request) { return BennuPortalDispatcher.getSelectedFunctionality(request); } /** * Retrieves the given key from the given bundle, as determined by {@link BundleUtil#getString(String, String, String...)}. * * @param bundle * The bundle for which to retrieve the message. * @param key * The message's key. * @return * The localized message. */ public String message(String bundle, String key) { return BundleUtil.getString(bundle, key); } /** * Returns the application's configured URL, as defined by {@link ConfigurationProperties#applicationUrl()}. * * @return * The application's URL. */ public String getApplicationUrl() { return CoreConfiguration.getConfiguration().applicationUrl(); } }