// Copyright 2006 Google Inc.
//
// Licensed 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 com.google.enterprise.connector.servlet;
import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.enterprise.connector.instantiator.EncryptedPropertyPlaceholderConfigurer;
import com.google.enterprise.connector.logging.NDC;
import com.google.enterprise.connector.manager.Context;
import org.springframework.web.context.support.XmlWebApplicationContext;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
/**
* The main purpose of this servlet is to have its "init" method called when the
* container starts up. This is by done by means of the web.xml file.
*/
public class StartUp implements ServletContextListener {
private static final Logger LOGGER =
Logger.getLogger(StartUp.class.getName());
@Override
public void contextInitialized(ServletContextEvent sce) {
NDC.push("Init");
try {
LOGGER.info("init");
ServletContext servletContext = sce.getServletContext();
doStartup(servletContext);
} catch (ServletException ex) {
throw new RuntimeException(ex);
} finally {
LOGGER.info("init done.");
NDC.remove();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
NDC.push("Shutdown");
try {
LOGGER.info("destroy");
Context.getInstance().shutdown(true);
} finally {
LOGGER.info("destroy done.");
NDC.remove();
}
}
private void doStartup(ServletContext servletContext)
throws ServletException {
try {
doConnectorManagerStartup(servletContext);
} catch (IOException ioe) {
LOGGER.log(Level.SEVERE, "Connector Manager Startup failed: ", ioe);
Context.getInstance().setInitFailureCause(ioe);
throw new ServletException("Connector Manager Startup failed", ioe);
} catch (RuntimeException re) {
LOGGER.log(Level.SEVERE, "Connector Manager Startup failed: ", re);
Context.getInstance().setInitFailureCause(re);
throw re;
} catch (Error e) {
LOGGER.log(Level.SEVERE, "Connector Manager Startup failed: ", e);
Context.getInstance().setInitFailureCause(e);
throw e;
}
}
private void doConnectorManagerStartup(ServletContext servletContext)
throws IOException {
LOGGER.info(ServletUtil.getManagerSplash());
// read in and set initialization parameters
String kp = servletContext.getInitParameter("keystore_passwd_file");
if (!Strings.isNullOrEmpty(kp)) {
EncryptedPropertyPlaceholderConfigurer.setKeyStorePasswdPath(
getRealPath(servletContext, kp));
}
String ks = servletContext.getInitParameter("keystore_file");
if (!Strings.isNullOrEmpty(ks)) {
EncryptedPropertyPlaceholderConfigurer.setKeyStorePath(
getRealPath(servletContext, ks));
}
String kt = servletContext.getInitParameter("keystore_type");
if (!Strings.isNullOrEmpty(kt)) {
EncryptedPropertyPlaceholderConfigurer.setKeyStoreType(kt);
}
String ka = servletContext.getInitParameter("keystore_crypto_algo");
if (!Strings.isNullOrEmpty(ka)) {
EncryptedPropertyPlaceholderConfigurer.setKeyStoreCryptoAlgo(ka);
}
// Note: default context location is /WEB-INF/applicationContext.xml
LOGGER.info("Making an XmlWebApplicationContext");
XmlWebApplicationContext ac = new XmlWebApplicationContext();
ac.setServletContext(servletContext);
ac.refresh();
Context context = Context.getInstance();
context.setServletContext(ac, servletContext.getRealPath("/WEB-INF"));
context.start();
LOGGER.info("Connector Manager started.");
}
/**
* Tries to normalize a pathname, as if relative to the context.
* Absolute paths are allowed (unlike traditional web-app behaviour).
* file: URLs are allowed as well and are treated like absolute paths.
* All relative paths are made relative the the web-app WEB-INF directory.
* Attempts are made to recognize paths that are already relative to
* WEB-INF (they begin with WEB-INF or /WEB-INF).
*
* @param servletContext the ServletContext
* @param name the file name
*/
private String getRealPath(final ServletContext servletContext, String name)
throws IOException {
return ServletUtil.getRealPath(name,
new Function<String, String>() {
public String apply(String path) {
// If servlet container cannot translated the virtual path to a
// real path, so use the supplied path.
String realPath = servletContext.getRealPath("/WEB-INF/" + path);
return (realPath == null) ? path : realPath;
}
});
}
}