blob: 567da53722d485d7a90fdd7ac1ee05a507e6756f [file] [log] [blame]
/*
* Copyright 2004-2005 The Apache Software Foundation or its licensors,
* as applicable.
*
* 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 org.apache.jackrabbit.j2ee;
import org.apache.jackrabbit.rmi.client.ClientRepositoryFactory;
import org.apache.log4j.Logger;
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;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Properties;
/**
* This Class implements a servlet that is used as unified mechanism to retrieve
* a jcr repository either through JNID, RMI or JCRWebdavServer.
*/
public class RepositoryAccessServlet extends HttpServlet {
/**
* default logger
*/
private static final Logger log = Logger.getLogger(RepositoryAccessServlet.class);
/**
* the 'repository-name' init parameter
*/
public final static String INIT_PARAM_REPOSITORY_NAME = "repository-name";
/**
* the 'rmi-uri' init parameter
*/
public final static String INIT_PARAM_RMI_URI = "rmi-uri";
/**
* the 'missing-auth-mapping' init parameter
*/
//public final static String INIT_PARAM_MISSING_AUTH_MAPPING = "missing-auth-mapping";
private static final String CTX_ATTR_REPOSITORY = "jcr.repository";
private static final String CTX_ATTR_REPOSITORY_NAME = "jcr.repository.name";
private static final String CTX_ATTR_REPOSITORY_RMI_URI = "jcr.repository.rmiURI";
private static final String CTX_ATTR_REPOSITORY_JNDI_CONTEXT = "jcr.repository.jndiContext";
/**
* Initializes this servlet
*
* @throws javax.servlet.ServletException
*/
public void init() throws ServletException {
log.info("RepositoryAccessServlet initializing...");
// fetching the name
String repositoryName = getServletConfig().getInitParameter(INIT_PARAM_REPOSITORY_NAME);
if (repositoryName == null) {
repositoryName = "default";
}
getServletContext().setAttribute(CTX_ATTR_REPOSITORY_NAME, repositoryName);
// fetching the rmiuri
getServletContext().setAttribute(CTX_ATTR_REPOSITORY_RMI_URI, getRMIUri());
// setup initial context
getServletContext().setAttribute(CTX_ATTR_REPOSITORY_JNDI_CONTEXT, getInitialContext());
log.info("RepositoryAccessServlet initialized.");
}
private InitialContext getInitialContext() {
// retrieve JNDI Context environment
try {
Properties env = new Properties();
Enumeration names = getServletConfig().getInitParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
if (name.startsWith("java.naming.")) {
String initParam = getServletConfig().getInitParameter(name);
if (initParam.equals("")) {
log.info(" ignoring empty JNDI init param: " + name);
} else {
env.put(name, initParam);
log.info(" adding property to JNDI environment: " + name + "=" + initParam);
}
}
}
return new InitialContext(env);
} catch (NamingException e) {
log.error("Create initial context: " + e.toString());
return null;
}
}
private String getRMIUri() {
// setup repository name
return getServletConfig().getInitParameter(INIT_PARAM_RMI_URI);
}
/**
* tries to retrieve the repository using RMI
*/
private static Repository getRepositoryByJNDI(ServletContext ctx) {
// acquire via JNDI
String repositoryName = (String) ctx.getAttribute(CTX_ATTR_REPOSITORY_NAME);
InitialContext jndiContext = (InitialContext) ctx.getAttribute(CTX_ATTR_REPOSITORY_JNDI_CONTEXT);
if (jndiContext == null) {
return null;
}
try {
Repository r = (Repository) jndiContext.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;
}
}
/**
* tries to retrieve the repository using RMI
*/
private static Repository getRepositoryByRMI(ServletContext ctx) {
// acquire via RMI
String rmiURI = (String) ctx.getAttribute(CTX_ATTR_REPOSITORY_RMI_URI);
if (rmiURI == null) {
return null;
}
log.info(" trying to retrieve repository using rmi. uri=" + rmiURI);
ClientFactoryDelegater cfd;
try {
Class clazz = Class.forName("org.apache.jackrabbit.j2ee.RMIClientFactoryDelegater");
cfd = (ClientFactoryDelegater) clazz.newInstance();
} catch (NoClassDefFoundError e) {
log.error("Unable to locate RMI ClientRepositoryFactory. jcr-rmi.jar missing? " + e.toString());
return null;
} catch (Exception e) {
log.error("Unable to locate RMI ClientRepositoryFactory. jcr-rmi.jar missing?" + e.toString());
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: " + e);
return null;
}
}
/**
* Returns the JSR170 repository
*
* @return a jsr170 repository
* @throws IllegalStateException if the repository is not available in the context.
*/
public static Repository getRepository(ServletContext ctx) {
Repository repository = (Repository) ctx.getAttribute(CTX_ATTR_REPOSITORY);
if (repository != null) {
return repository;
} else {
repository = getRepositoryByRMI(ctx);
}
// try to retrieve via jndi
if (repository == null) {
repository = getRepositoryByJNDI(ctx);
}
// error
if (repository == null) {
log.fatal("The repository is not available. Check config of 'RepositoryAccessServlet'.");
throw new IllegalStateException("The repository is not available.");
} else {
ctx.setAttribute(CTX_ATTR_REPOSITORY, repository);
log.info(repository.getDescriptor(Repository.REP_NAME_DESC) + " v" + repository.getDescriptor(Repository.REP_VERSION_DESC));
return repository;
}
}
}
/**
* optional class for RMI, will only be used, if RMI client is present
*/
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
*/
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);
}
}