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

org.apache.jackrabbit.j2ee.RepositoryAccessServlet Maven / Gradle / Ivy

There is a newer version: 2.6.10
Show newest version
/*
 * 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.jackrabbit.j2ee;

import org.apache.jackrabbit.rmi.client.ClientRepositoryFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.Properties;

import javax.jcr.Repository;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

/**
 * This Class implements a servlet that is used as unified mechanism to retrieve
 * a jcr repository either through JNDI or RMI.
 */
public class RepositoryAccessServlet extends HttpServlet {

    /**
     * default logger
     */
    private static final Logger log = LoggerFactory.getLogger(RepositoryAccessServlet.class);

    /**
     * initial param name for the bootstrap config location
     */
    public final static String INIT_PARAM_BOOTSTRAP_CONFIG = "bootstrap-config";

    /**
     * Context parameter name for 'this' instance.
     */
    private final static String CTX_PARAM_THIS = "repository.access.servlet";

    /**
     * Ugly hack to override the bootstrap file location in the test cases
     */
    static String bootstrapOverride = null;

    /**
     * the bootstrap config
     */
    private BootstrapConfig config;

    /**
     * the initialized initial context
     */
    private InitialContext jndiContext;

    /**
     * if this is set we try to get a Repository from the ServletContext
     */
    private String repositoryContextAttributeName;

    /**
     * the repository
     */
    private Repository repository;

    /**
     * Initializes the servlet.
* Please note that only one repository startup servlet may exist per * webapp. it registers itself as context attribute and acts as singleton. * * @throws ServletException if a same servlet is already registered or of * another initialization error occurs. */ public void init() throws ServletException { // check if servlet is defined twice if (getServletContext().getAttribute(CTX_PARAM_THIS) != null) { throw new ServletException("Only one repository access servlet allowed per web-app."); } getServletContext().setAttribute(CTX_PARAM_THIS, this); repositoryContextAttributeName = getServletConfig().getInitParameter("repository.context.attribute.name"); log.info("RepositoryAccessServlet initialized."); } /** * Returns the instance of this servlet * @param ctx the servlet context * @return this servlet */ public static RepositoryAccessServlet getInstance(ServletContext ctx) { final RepositoryAccessServlet instance = (RepositoryAccessServlet) ctx.getAttribute(CTX_PARAM_THIS); if(instance==null) { throw new IllegalStateException( "No RepositoryAccessServlet instance in ServletContext, RepositoryAccessServlet servlet not initialized?" ); } return instance; } /** * Returns the bootstrap config * @return the bootstrap config * @throws ServletException if the config is not valid */ private BootstrapConfig getConfig() throws ServletException { if (config == null) { // check if there is a loadable bootstrap config Properties bootstrapProps = new Properties(); String bstrp = bootstrapOverride; if (bstrp == null) { bstrp = getServletConfig().getInitParameter(INIT_PARAM_BOOTSTRAP_CONFIG); } if (bstrp != null) { // check if it's a web-resource InputStream in = getServletContext().getResourceAsStream(bstrp); if (in == null) { // check if it's a file File file = new File(bstrp); if (file.canRead()) { try { in = new FileInputStream(file); } catch (FileNotFoundException e) { throw new ServletExceptionWithCause( "Bootstrap configuration not found: " + bstrp, e); } } } if (in != null) { try { bootstrapProps.load(in); } catch (IOException e) { throw new ServletExceptionWithCause( "Bootstrap configuration failure: " + bstrp, e); } finally { try { in.close(); } catch (IOException e) { // ignore } } } } // read bootstrap config BootstrapConfig tmpConfig = new BootstrapConfig(); tmpConfig.init(getServletConfig()); tmpConfig.init(bootstrapProps); tmpConfig.validate(); if (!tmpConfig.isValid()) { throw new ServletException( "Repository access configuration is not valid."); } tmpConfig.logInfos(); config = tmpConfig; } return config; } /** * Returns the initial jndi context or null if the jndi access * is not configured or erroous. * @return the initial context or null */ private InitialContext getInitialContext() { if (jndiContext == null && config.getJndiConfig().enabled()) { // retrieve JNDI Context environment try { jndiContext = new InitialContext(config.getJndiConfig().getJndiEnv()); } catch (NamingException e) { log.error("Create initial context: " + e.toString()); } } return jndiContext; } /** * Checks if the repository is available via JNDI and returns it. * @return the repository or null * @throws ServletException if this servlet is not properly configured. */ private Repository getRepositoryByJNDI() throws ServletException { BootstrapConfig config = getConfig(); if (!config.getJndiConfig().isValid() || !config.getJndiConfig().enabled()) { return null; } // acquire via JNDI String repositoryName = config.getRepositoryName(); InitialContext ctx = getInitialContext(); if (ctx == null) { return null; } try { Repository r = (Repository) ctx.lookup(repositoryName); log.info("Acquired repository via JNDI."); return r; } catch (NamingException e) { log.error("Error while retrieving repository using JNDI (name={})", repositoryName, e); return null; } } /** * Checks if the repository is available via RMI and returns it. * @return the repository or null * @throws ServletException if this servlet is not properly configured. */ private Repository getRepositoryByRMI() throws ServletException { BootstrapConfig config = getConfig(); if (!config.getRmiConfig().isValid() || !config.getRmiConfig().enabled()) { return null; } // acquire via RMI String rmiURI = config.getRmiConfig().getRmiUri(); if (rmiURI == null) { return null; } log.info(" trying to retrieve repository using rmi. uri={}", rmiURI); ClientFactoryDelegater cfd; try { Class clazz = Class.forName(getServerFactoryDelegaterClass()); cfd = (ClientFactoryDelegater) clazz.newInstance(); } catch (Throwable e) { log.error("Unable to locate RMI ClientRepositoryFactory. Is jcr-rmi.jar missing?", e); return null; } try { Repository r = cfd.getRepository(rmiURI); log.info("Acquired repository via RMI."); return r; } catch (Exception e) { log.error("Error while retrieving repository using RMI: {}", rmiURI, e); return null; } } /** * If our config said so, try to retrieve a Repository from the ServletContext */ protected Repository getRepositoryByContextAttribute() { Repository result = null; if(repositoryContextAttributeName!=null) { result = (Repository)getServletContext().getAttribute(repositoryContextAttributeName); if(log.isDebugEnabled()) { if(result!=null) { log.debug("Got Repository from ServletContext attribute '{}'", repositoryContextAttributeName); } else { log.debug("ServletContext attribute '{}' does not provide a Repository", repositoryContextAttributeName); } } } return result; } /** * Return the fully qualified name of the class providing the client * repository. The class whose name is returned must implement the * {@link ClientFactoryDelegater} interface. * * @return the qfn of the factory class. */ protected String getServerFactoryDelegaterClass() { return getClass().getName() + "$RMIClientFactoryDelegater"; } /** * Returns the JCR repository * * @return a JCR repository * @throws IllegalStateException if the repository is not available in the context. */ public Repository getRepository() { try { if (repository == null) { // try to get via context attribute repository = getRepositoryByContextAttribute(); } if (repository == null) { // try to retrieve via jndi repository = getRepositoryByJNDI(); } if (repository == null) { // try to get via rmi repository = getRepositoryByRMI(); } if (repository == null) { throw new ServletException("N/A"); } return repository; } catch (ServletException e) { throw new IllegalStateException( "The repository is not available. Please check" + " RepositoryAccessServlet configuration in web.xml.", e); } } /** * Returns the JCR repository * * @param ctx the servlet context * @return a JCR repository * @throws IllegalStateException if the repository is not available in the context. */ public static Repository getRepository(ServletContext ctx) { return getInstance(ctx).getRepository(); } /** * Returns the config that was used to bootstrap this servlet. * @return the bootstrap config or null. */ public BootstrapConfig getBootstrapConfig() { return config; } /** * optional class for RMI, will only be used, if RMI client is present */ protected static abstract class ClientFactoryDelegater { public abstract Repository getRepository(String uri) throws RemoteException, MalformedURLException, NotBoundException; } /** * optional class for RMI, will only be used, if RMI server is present */ protected static class RMIClientFactoryDelegater extends ClientFactoryDelegater { // only used to enforce linking upon Class.forName() static String FactoryClassName = ClientRepositoryFactory.class.getName(); public Repository getRepository(String uri) throws MalformedURLException, NotBoundException, RemoteException { System.setProperty("java.rmi.server.useCodebaseOnly", "true"); return new ClientRepositoryFactory().getRepository(uri); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy