All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jumpmind.symmetric.web.SymmetricServlet Maven / Gradle / Ivy

Go to download

SymmetricDS is an open source database synchronization solution. It is platform-independent, web-enabled, and database-agnostic. SymmetricDS was first built to replicate changes between 'retail store' databases and ad centralized 'corporate' database.

The newest version!
/*
 * Licensed to JumpMind Inc under one or more contributor 
 * license agreements.  See the NOTICE file distributed
 * with this work for additional information regarding 
 * copyright ownership.  JumpMind Inc licenses this file
 * to you under the GNU Lesser General Public License (the
 * "License"); you may not use this file except in compliance
 * with the License. 
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see           
 * .
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License. 
 */


package org.jumpmind.symmetric.web;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.jumpmind.symmetric.common.logging.ILog;
import org.jumpmind.symmetric.common.logging.LogFactory;
import org.springframework.context.ApplicationContext;

/**
 * The SymmetricServlet manages all of the other Servlets. This allows for
 * easier configuration since Spring manages the individual Servlets.
 * 
 * Configured within web.xml
 * 
 * 
 *  <servlet>
 *    <servlet-name>SymmetricServlet</filter-name>
 *    <servlet-class>
 *      org.jumpmind.symmetric.web.SymmetricServlet
 *    </servlet-class>
 *  </servlet>
 * 
 *  <servlet-mapping>
 *    <servlet-name>SymmetricServlet</servlet-name>
 *    <url-pattern>*</url-pattern>
 *  </servlet-mapping>
 * 
* * @since 1.4.0 * * */ public class SymmetricServlet extends AbstractServlet { private static final long serialVersionUID = 1L; private static final ILog log = LogFactory.getLog(SymmetricServlet.class); private List servlets; @Override protected ILog getLog() { return log; } @Override public void init(ServletConfig config) throws ServletException { super.init(config); servlets = new ArrayList(); ApplicationContext ctx = ServletUtils.getApplicationContext(getServletContext()); final Map servletBeans = new LinkedHashMap(); servletBeans.putAll(ctx.getBeansOfType(IServletExtension.class)); if (ctx.getParent() != null) { servletBeans.putAll(ctx.getParent().getBeansOfType(IServletExtension.class)); } // TODO order using initOrder for (final Map.Entry servletEntry : servletBeans.entrySet()) { log.debug("ServletInitializing", servletEntry.getKey()); final IServletExtension extension = servletEntry.getValue(); extension.getServlet().init(config); servlets.add(extension); } if (servlets.size() == 0) { log.error("ServletNoneFound"); } } public void destroy() { for (final IServletExtension extension : servlets) { extension.getServlet().destroy(); } } protected Servlet findMatchingServlet(ServletRequest req, ServletResponse resp) { Servlet retVal = null; for (Iterator iterator = servlets.iterator(); retVal == null && iterator.hasNext();) { IServletExtension extension = iterator.next(); if (!extension.isDisabled() && matches(extension, req)) { retVal = extension.getServlet(); } } return retVal; } public boolean matches(IServletExtension ext, ServletRequest request) { boolean retVal = true; if (request instanceof HttpServletRequest) { final HttpServletRequest httpRequest = (HttpServletRequest) request; final String uri = normalizeRequestUri(httpRequest); if (!ArrayUtils.isEmpty(ext.getUriPatterns())) { retVal = matchesUriPatterns(uri, ext.getUriPatterns()); } } return retVal; } protected boolean matchesUriPatterns(String uri, String[] uriPatterns) { boolean retVal = false; for (int i = 0; !retVal && i < uriPatterns.length; i++) { retVal = matchesUriPattern(uri, uriPatterns[i]); } return retVal; } protected boolean matchesUriPattern(String uri, String uriPattern) { boolean retVal = false; String path = StringUtils.defaultIfEmpty(uri, "/"); final String pattern = StringUtils.defaultIfEmpty(uriPattern, "/"); if ("/".equals(pattern) || "/*".equals(pattern) || pattern.equals(path)) { retVal = true; } else { final String[] patternParts = StringUtils.split(pattern, "/"); final String[] pathParts = StringUtils.split(path, "/"); boolean matches = true; for (int i = 0; i < patternParts.length && i < pathParts.length && matches; i++) { final String patternPart = patternParts[i]; matches = "*".equals(patternPart) || patternPart.equals(pathParts[i]); } retVal = matches; } return retVal; } /** * Returns the part of the path we are interested in when doing pattern * matching. This should work whether or not the servlet or filter is * explicitly mapped inside of the web.xml since it always strips off the * contextPath. * * @param httpRequest * @return */ protected String normalizeRequestUri(HttpServletRequest httpRequest) { String retVal = httpRequest.getRequestURI(); String contextPath = httpRequest.getContextPath(); if (retVal.startsWith(contextPath)) { retVal = retVal.substring(contextPath.length()); } return retVal; } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { Servlet servlet = findMatchingServlet(req, res); if (servlet != null) { try { servlet.service(req, res); } catch (IOException e) { logException(req, e, false); } catch (Exception e) { logException(req, e, true); if (!res.isCommitted()) { if (res instanceof HttpServletResponse) { ((HttpServletResponse) res).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } } } else { if (req instanceof HttpServletRequest) { HttpServletRequest httpRequest = (HttpServletRequest) req; log.error("ServletNotFoundToHandleRequest", normalizeRequestUri(httpRequest)); } } } protected void logException(ServletRequest req, Exception ex, boolean isError) { String nodeId = req.getParameter(WebConstants.NODE_ID); String externalId = req.getParameter(WebConstants.EXTERNAL_ID); String address = req.getRemoteAddr(); String hostName = req.getRemoteHost(); String method = req instanceof HttpServletRequest ? ((HttpServletRequest) req).getMethod() : ""; if (getLog().isErrorEnabled() && isError) { getLog().error("ServletProcessingFailedError", ex, method, externalId, nodeId, address, hostName); } else if (getLog().isWarnEnabled()) { getLog().warn("ServletProcessingFailedWarning", method, externalId, nodeId, address, hostName, ex.getMessage()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy