/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2016 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.server.ngclient; import java.io.IOException; import java.io.PrintWriter; import java.io.Writer; import java.net.URL; import java.util.ArrayList; import java.util.List; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import com.servoy.j2db.persistence.IRepository; import com.servoy.j2db.persistence.RepositoryException; import com.servoy.j2db.persistence.RootObjectMetaData; import com.servoy.j2db.persistence.Solution; import com.servoy.j2db.persistence.SolutionMetaData; import com.servoy.j2db.server.shared.ApplicationServerRegistry; import com.servoy.j2db.server.shared.IApplicationServerSingleton; import com.servoy.j2db.util.Debug; import com.servoy.j2db.util.HTTPUtils; import com.servoy.j2db.util.Settings; import com.servoy.j2db.util.Utils; /** * Provides an entry page that lists all available ng client solutions on the app. server. * I will not work if property 'servoy.allowSolutionBrowsing' is set to false. * * @author acostescu */ @WebFilter(urlPatterns = { "/servoy-ngclient/solutions.js", "/servoy-ngclient" }) @SuppressWarnings("nls") public class SelectNGSolutionFilter implements Filter { private static final String CONTRIBUTIONS = "<!-- contributions -->"; public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { if (Utils.getAsBoolean(Settings.getInstance().getProperty("servoy.allowSolutionBrowsing", "true"))) { HttpServletRequest request = (HttpServletRequest)servletRequest; String uri = request.getServletPath(); if (uri != null) { if (uri.equals("/servoy-ngclient")) { // html contents ((HttpServletResponse)servletResponse).setContentType("text/html"); PrintWriter w = servletResponse.getWriter(); addNeededJSAndCSS(getClass().getResource("solution_list.html"), w); w.flush(); return; } else if (uri.equals("/servoy-ngclient/solutions.js")) { HTTPUtils.setNoCacheHeaders((HttpServletResponse)servletResponse); IApplicationServerSingleton as = ApplicationServerRegistry.get(); // js contents giving the actual solutions list List<Solution> ngCompatibleSolutions = new ArrayList<Solution>(); if (as.isDeveloperStartup()) { Solution active = as.getDebugClientHandler().getDebugSmartClient().getCurrent(); if ((((SolutionMetaData)active.getMetaData()).getSolutionType() & (SolutionMetaData.SOLUTION | SolutionMetaData.NG_CLIENT_ONLY)) != 0) ngCompatibleSolutions.add(active); } else { try { RootObjectMetaData[] smds = as.getLocalRepository().getRootObjectMetaDatasForType(IRepository.SOLUTIONS); int solutionType; for (RootObjectMetaData element : smds) { solutionType = ((SolutionMetaData)element).getSolutionType(); if ((solutionType & (SolutionMetaData.SOLUTION | SolutionMetaData.NG_CLIENT_ONLY)) > 0) { Solution solution = (Solution)as.getLocalRepository().getActiveRootObject(element.getRootObjectId()); if (solution != null) { ngCompatibleSolutions.add(solution); } } } } catch (RepositoryException e) { Debug.error(e); } } // now generate the js containing these solutions ((HttpServletResponse)servletResponse).setContentType("text/javascript"); PrintWriter w = servletResponse.getWriter(); w.println("angular.module('solutionsListModule', []).value('$solutionsList', {"); w.println(" ngSolutions: ["); boolean putComma = false; for (Solution s : ngCompatibleSolutions) { if (putComma) w.println(","); else putComma = true; String titleText = (s.getTitleText() != null ? "'" + s.getTitleText() + "'" : null); if (titleText != null && (titleText.contains("#") || titleText.startsWith("i18n:"))) titleText = null; // it wouldn't look nice in the list of solutions to pick + client can't convert those w.print(" { name : '" + s.getName() + "', titleText : " + titleText + ", requiresAuth : " + s.requireAuthentication() + " }"); } if (putComma) w.println(""); w.println(" ]"); w.println("});"); w.flush(); return; } } } filterChain.doFilter(servletRequest, servletResponse); } protected void addNeededJSAndCSS(URL resource, Writer writer) throws IOException { String htmlAsString = IOUtils.toString(resource); htmlAsString = htmlAsString.replace(CONTRIBUTIONS, getNeededJSAndCSS()); writer.append(htmlAsString); } protected CharSequence getNeededJSAndCSS() { StringBuilder sb = new StringBuilder(); sb.append(String.format("<script src=\"%s\"></script>\n", NGClientEntryFilter.ANGULAR_JS)); sb.append(String.format("<link rel=\"stylesheet\" href=\"%s\"/>\n", NGClientEntryFilter.BOOTSTRAP_CSS)); return sb; } @Override public void init(FilterConfig filterConfig) throws ServletException { // nothing to do there } @Override public void destroy() { // nothing to do there } }