Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * 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.apache.sling.engine.impl;
 
 import java.util.List;
 import java.util.Map;
 
 
 import  org.osgi.service.http.HttpService;
The SlingMainServlet TODO
 
 @SuppressWarnings("serial")
 @Component(immediate = true, metatype = true, label = "%sling.name", description = "%sling.description")
     @Property(name = ., value = "The Apache Software Foundation"),
     @Property(name = ., value = "Sling Servlet")
 })
     @Reference(name = "ErrorHandler", referenceInterface = ErrorHandler.class, cardinality = ., policy = ., bind = "setErrorHandler", unbind = "unsetErrorHandler"),
     @Reference(name = "ServletResolver", referenceInterface = ServletResolver.class, cardinality = ., policy = ., bind = "setServletResolver", unbind = "unsetServletResolver"),
     @Reference(name = "MimeTypeService", referenceInterface = MimeTypeService.class, cardinality = ., policy = ., bind = "setMimeTypeService", unbind = "unsetMimeTypeService"),
     @Reference(name = "AuthenticationSupport", referenceInterface = AuthenticationSupport.class, cardinality = ., policy = ., bind = "setAuthenticationSupport", unbind = "unsetAuthenticationSupport") })
 public class SlingMainServlet extends GenericServlet {
 
     public static final String PROP_MAX_CALL_COUNTER = "sling.max.calls";
 
     public static final String PROP_MAX_INCLUSION_COUNTER = "sling.max.inclusions";
 
     public static final boolean DEFAULT_ALLOW_TRACE = false;
 
     @Property(boolValue=)
     public static final String PROP_ALLOW_TRACE = "sling.trace.allow";
 
     public static final boolean DEFAULT_FILTER_COMPAT_MODE = false;
 
    public static final String PROP_FILTER_COMPAT_MODE = "sling.filter.compat.mode";
    private static final String PROP_MAX_RECORD_REQUESTS = "sling.max.record.requests";
    @Property(unbounded=.)
    private static final String PROP_TRACK_PATTERNS_REQUESTS = "sling.store.pattern.requests";
    private static final String PROP_DEFAULT_PARAMETER_ENCODING = "sling.default.parameter.encoding";
    @Property
    private static final String PROP_SERVER_INFO = "sling.serverinfo";
    @Reference
    private HttpService httpService;
    private AdapterManager adapterManager;

    
default log
    private final Logger log = LoggerFactory.getLogger(SlingMainServlet.class);

    
The registration path for the SlingMainServlet is hard wired to always be the root, aka "/" (value is "/").
    private static final String SLING_ROOT = "/";

    
The name of the product to report in the getServerInfo() method (value is "ApacheSling").
    static String PRODUCT_NAME = "ApacheSling";
    private SlingServletContext slingServletContext;

    
The product information part of the serverInfo returns from the ServletContext.getServerInfo() method. This field defaults to PRODUCT_NAME and is amended with the major and minor version of the Sling Engine bundle while this component is being activate(BundleContext, Map) activated}.
    private String productInfo = ;

    
The server information to report in the getServerInfo() method. By default this is just the PRODUCT_NAME (same as productInfo. During activate(BundleContext, Map) activation} the field is updated with the full productInfo value as well as the operating system and java version it is running on. Finally during servlet initialization the product information from the servlet container's server info is added to the comment section.
    private String serverInfo = ;
    private boolean allowTrace = ;
    private Object printerRegistration;
    // new properties
    private String configuredServerInfo;
    // ---------- Servlet API -------------------------------------------------
    @Override
    public void service(ServletRequest reqServletResponse res)
            throws ServletException {
        if (req instanceof HttpServletRequest
            && res instanceof HttpServletResponse) {
            HttpServletRequest request = (HttpServletRequestreq;
            // set the thread name according to the request
            String threadName = setThreadName(request);
            ResourceResolver resolver = null;
            try {
                if (! && "TRACE".equals(request.getMethod())) {
                    HttpServletResponse response = (HttpServletResponseres;
                    response.setStatus(405);
                    response.setHeader("Allow""GET, HEAD, POST, PUT, DELETE, OPTIONS");
                    return;
                }
                // get ResourceResolver (set by AuthenticationSupport)
                Object resolverObject = request.getAttribute(.);
                resolver = (resolverObject instanceof ResourceResolver)
                        ? (ResourceResolverresolverObject
                        : null;
                // real request handling for HTTP requests
                .doProcessRequest(request, (HttpServletResponseres,
                    resolver);
            } catch (IOException ioe) {
                // SLING-3498: Jetty with NIO does not have a wrapped
                // SocketException any longer but a plain IOException
                // from the NIO Socket channel. Hence we don't care for
                // unwrapping and just log at DEBUG level
                .debug("service: Probably client aborted request or any other network problem"ioe);
            } catch (Throwable t) {
                // some failure while handling the request, log the issue
                // and terminate. We do not call error handling here, because
                // we assume the real request handling would have done this.
                // So here we just log
                .error("service: Uncaught Problem handling the request"t);
            } finally {
                // close the resource resolver (not relying on servlet request
                // listener to do this for now; see SLING-1270)
                if (resolver != null) {
                    resolver.close();
                }
                .sendEventrequest.. );
                // reset the thread name
                if (threadName != null) {
                    Thread.currentThread().setName(threadName);
                }
            }
        } else {
            throw new ServletException(
                "Apache Sling must be run in an HTTP servlet environment.");
        }
    }
    // ---------- Internal helper ----------------------------------------------

    
Sets the productInfo field from the providing bundle's version and the PRODUCT_NAME.

Also updates the serverInfo based on the product info calculated.

Parameters:
bundleContext Provides access to the "Bundle-Version" manifest header of the containing bundle.
    private void setProductInfo(final BundleContext bundleContext) {
        final Dictionary<?, ?> props = bundleContext.getBundle().getHeaders();
        final Version bundleVersion = Version.parseVersion((Stringprops.get(.));
        final String productVersion = bundleVersion.getMajor() + "."
            + bundleVersion.getMinor();
        this. =  + "/" + productVersion;
        // update the server info
        this.setServerInfo();
    }
    public String getServerInfo() {
        return ;
    }

    
Sets up the server info to be returned for the ServletContext.getServerInfo() method for servlets and filters deployed inside Sling. The SlingRequestProcessor instance is also updated with the server information.

This server info is either configured through an OSGi configuration or it is made up of the following components:

  1. The productInfo field as the primary product information
  2. The primary product information of the servlet container into which the Sling Main Servlet is deployed. If the servlet has not yet been deployed this will show as unregistered. If the servlet container does not provide a server info this will show as unknown.
  3. The name and version of the Java VM as reported by the java.vm.name and java.vm.version system properties
  4. The name, version, and architecture of the OS platform as reported by the os.name, os.version, and os.arch system properties
    private void setServerInfo() {
        if ( this. != null ) {
            this. = this.;
        } else {
            final String containerProductInfo;
            if (getServletConfig() == null || getServletContext() == null) {
                containerProductInfo = "unregistered";
            } else {
                final String containerInfo = getServletContext().getServerInfo();
                if (containerInfo != null && containerInfo.length() > 0) {
                    int lbrace = containerInfo.indexOf('(');
                    if (lbrace < 0) {
                        lbrace = containerInfo.length();
                    }
                    containerProductInfo = containerInfo.substring(0, lbrace).trim();
                } else {
                    containerProductInfo = "unknown";
                }
            }
            this. = String.format("%s (%s, %s %s, %s %s %s)",
                this.containerProductInfo,
                System.getProperty("java.vm.name"),
                System.getProperty("java.version"), System.getProperty("os.name"),
                System.getProperty("os.version"), System.getProperty("os.arch"));
        }
        if (this. != null) {
            this..setServerInfo();
        }
    }
    // ---------- Property Setter for SCR --------------------------------------
    @Activate
    protected void activate(final BundleContext bundleContext,
            final Map<StringObjectcomponentConfig) {
         = PropertiesUtil.toString(componentConfig.get(), null);
        // setup server info
        setProductInfo(bundleContext);
        // prepare the servlet configuration from the component config
        final Hashtable<StringObjectconfiguration = new Hashtable<StringObject>(
            componentConfig);
        // ensure the servlet name
        if (!(configuration.get("servlet-name"instanceof String)) {
            configuration.put("servlet-name"this.);
        }
        // configure method filter
         = PropertiesUtil.toBoolean(componentConfig.get(),
                );
        // configure the request limits
        RequestData.setMaxIncludeCounter(PropertiesUtil.toInteger(
            componentConfig.get(),
        RequestData.setMaxCallCounter(PropertiesUtil.toInteger(
            componentConfig.get(),
            .));
        RequestData.setSlingMainServlet(this);
        // configure default request parameter encoding
        // log a message if such configuration exists ....
        if (componentConfig.get() != null) {
            .warn("Configure default request parameter encoding with 'org.apache.sling.parameters.config' configuration; the property "
                + 
                + "="
                + componentConfig.get()
                + " is ignored");
        }
        // register the servlet and resources
        try {
            Dictionary<StringStringservletConfig = toStringConfig(configuration);
            this..registerServlet(thisservletConfig,
                );
            .info("{} ready to serve requests"this.getServerInfo());
        } catch (Exception e) {
            .error("Cannot register " + this.getServerInfo(), e);
        }
        // now that the sling main servlet is registered with the HttpService
        // and initialized we can register the servlet context
        if (getServletContext() == null || getServletContext().getMajorVersion() < 3) {
             = new SlingServletContext(bundleContextthis);
        } else {
             = new SlingServletContext3(bundleContextthis);
        }
        // register render filters already registered after registration with
        // the HttpService as filter initialization may cause the servlet
        // context to be required (see SLING-42)
         = new ServletFilterManager(bundleContext,
            ,
            PropertiesUtil.toBoolean(componentConfig.get(), ));
        .open();
        // initialize requestListenerManager
         = new RequestListenerManagerbundleContext );
        // Setup configuration printer
        this. = WebConsoleConfigPrinter.register(bundleContext);
        // setup the request info recorder
        try {
            int maxRequests = PropertiesUtil.toInteger(
                componentConfig.get(),
                .);
            String[] patterns = PropertiesUtil.toStringArray(componentConfig.get(), new String[0]);
            List<PatterncompiledPatterns = new ArrayList<Pattern>(patterns.length);
            for (String pattern : patterns) {
                if(pattern != null && pattern.trim().length() > 0) {
                    compiledPatterns.add(Pattern.compile(pattern));
                }
            }
            RequestHistoryConsolePlugin.initPlugin(bundleContextmaxRequestscompiledPatterns);
        } catch (Throwable t) {
            .debug(
                "Unable to register web console request recorder plugin."t);
        }
        try {
            Dictionary<StringStringmbeanProps = new Hashtable<StringString>();
            mbeanProps.put("jmx.objectname""org.apache.sling:type=engine,service=RequestProcessor");
            RequestProcessorMBeanImpl mbean = new RequestProcessorMBeanImpl();
             = bundleContext.registerService(RequestProcessorMBean.class.getName(), mbeanmbeanProps);
            .setMBean(mbean);
        } catch (Throwable t) {
            .debug("Unable to register mbean");
        }
        // provide the SlingRequestProcessor service
        Hashtable<StringStringsrpProps = new Hashtable<StringString>();
        srpProps.put(."The Apache Software Foundation");
        srpProps.put(."Sling Request Processor");
         = bundleContext.registerService(
            .srpProps);
    }
    @Override
    public void init() {
        setServerInfo();
    }
    @Deactivate
    protected void deactivate() {
        // unregister the sling request processor
        if ( != null) {
            .unregister();
             = null;
        }
        if ( != null) {
             = null;
        }
        // unregister request recorder plugin
        try {
            RequestHistoryConsolePlugin.destroyPlugin();
        } catch (Throwable t) {
            .debug(
                "Problem unregistering web console request recorder plugin."t);
        }
        // this reverses the activation setup
        if ( this. != null ) {
            WebConsoleConfigPrinter.unregister(this.);
            this. = null;
        }
        // destroy servlet filters before destroying the sling servlet
        // context because the filters depend on that context
        if ( != null) {
            .setFilterManager(null);
            .close();
        }
        // second unregister the servlet context *before* unregistering
        // and destroying the the sling main servlet
        if ( != null) {
            .dispose();
             = null;
        }
        // third unregister and destroy the sling main servlet
        .unregister();
        // dispose of request listener manager after unregistering the servlet
        // to prevent a potential NPE in the service method
        if ( this. != null ) {
            this..dispose();
            this. = null;
        }
        // reset the sling main servlet reference (help GC and be nice)
        RequestData.setSlingMainServlet(null);
        .info(this.getServerInfo() + " shut down");
    }
    void setErrorHandler(final ErrorHandler errorHandler) {
        .setErrorHandler(errorHandler);
    }
    void unsetErrorHandler(final ErrorHandler errorHandler) {
        .unsetErrorHandler(errorHandler);
    }
    public void setServletResolver(final ServletResolver servletResolver) {
        .setServletResolver(servletResolver);
    }
    public void unsetServletResolver(final ServletResolver servletResolver) {
        .unsetServletResolver(servletResolver);
    }
    public void setMimeTypeService(final MimeTypeService mimeTypeService) {
        .setMimeTypeService(mimeTypeService);
    }
    public void unsetMimeTypeService(final MimeTypeService mimeTypeService) {
        .unsetMimeTypeService(mimeTypeService);
    }
    public void setAuthenticationSupport(
            final AuthenticationSupport authenticationSupport) {
        .setAuthenticationSupport(authenticationSupport);
    }
    public void unsetAuthenticationSupport(
            final AuthenticationSupport authenticationSupport) {
        .unsetAuthenticationSupport(authenticationSupport);
    }
    private Dictionary<StringStringtoStringConfig(Dictionary<?, ?> config) {
        Dictionary<StringStringstringConfig = new Hashtable<StringString>();
        for (Enumeration<?> ke = config.keys(); ke.hasMoreElements();) {
            Object key = ke.nextElement();
            stringConfig.put(key.toString(), String.valueOf(config.get(key)));
        }
        return stringConfig;
    }
    // ---------- HttpContext interface ----------------------------------------
    public String getMimeType(String name) {
        return .getMimeType(name);
    }
    public <Type> Type adaptTo(Object objectClass<Type> type) {
        AdapterManager adapterManager = this.;
        if (adapterManager != null) {
            return adapterManager.getAdapter(objecttype);
        }
        // no adapter manager, nothing to adapt to
        return null;
    }

    
Sets the name of the current thread to the IP address of the remote client with the current system time and the first request line consisting of the method, path and protocol.

Parameters:
request The request to extract the remote IP address, method, request URL and protocol from.
Returns:
The name of the current thread before setting the new name.
    private String setThreadName(HttpServletRequest request) {
        // get the name of the current thread (to be returned)
        Thread thread = Thread.currentThread();
        String oldThreadName = thread.getName();
        // construct and set the new thread name of the form:
        // 127.0.0.1 [1224156108055] GET /system/console/config HTTP/1.1
        final StringBuilder buf = new StringBuilder();
        buf.append(request.getRemoteAddr());
        buf.append(" [").append(System.currentTimeMillis()).append("] ");
        buf.append(request.getMethod()).append(' ');
        buf.append(request.getRequestURI()).append(' ');
        buf.append(request.getProtocol());
        thread.setName(buf.toString());
        // return the previous thread name
        return oldThreadName;
    }
New to GrepCode? Check out our FAQ X