/* * 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.rmi.repository; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.util.Hashtable; import java.util.Map; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.RepositoryFactory; import javax.naming.InitialContext; import javax.naming.NamingException; import org.apache.jackrabbit.rmi.client.ClientAdapterFactory; import org.apache.jackrabbit.rmi.client.LocalAdapterFactory; import org.apache.jackrabbit.rmi.client.SafeClientRepository; import org.apache.jackrabbit.rmi.remote.RemoteRepository; public class RmiRepositoryFactory implements RepositoryFactory { private static final String REPOSITORY_URI = "org.apache.jackrabbit.repository.uri"; @SuppressWarnings({"unchecked", "rawtypes"}) public Repository getRepository(Map parameters) throws RepositoryException { if (parameters != null && parameters.containsKey(REPOSITORY_URI)) { URI uri; try { uri = new URI(parameters.get(REPOSITORY_URI).toString().trim()); } catch (URISyntaxException e) { return null; } String scheme = uri.getScheme(); if ("rmi".equalsIgnoreCase(scheme)) { return getRmiRepository(uri.getSchemeSpecificPart()); } else if ("jndi".equalsIgnoreCase(scheme)) { Hashtable environment = new Hashtable(parameters); environment.remove(REPOSITORY_URI); return getJndiRepository( uri.getSchemeSpecificPart(), environment); } else { try { return getUrlRepository(uri.toURL()); } catch (MalformedURLException e) { return null; } } } else { return null; } } private Repository getUrlRepository(final URL url) throws RepositoryException { return new RmiSafeClientRepository(new ClientAdapterFactory()) { @Override protected RemoteRepository getRemoteRepository() throws RemoteException { try { InputStream stream = url.openStream(); try { Object remote = new ObjectInputStream(stream).readObject(); if (remote instanceof RemoteRepository) { return (RemoteRepository) remote; } else { throw new RemoteException("The resource at URL " + url + " is not a remote repository stub: " + remote); } } finally { if (stream != null) { stream.close(); } } } catch (ClassNotFoundException e) { throw new RemoteException("The resource at URL " + url + " requires a class that is not available", e); } catch (IOException e) { throw new RemoteException("Failed to read the resource at URL " + url, e); } } }; } @SuppressWarnings("rawtypes") private Repository getJndiRepository(final String name, final Hashtable environment) throws RepositoryException { return new RmiSafeClientRepository(new ClientAdapterFactory()) { @Override protected RemoteRepository getRemoteRepository() throws RemoteException { try { Object value = new InitialContext(environment).lookup(name); if (value instanceof RemoteRepository) { return (RemoteRepository) value; } else { throw new RemoteException("The JNDI resource " + name + " is not a remote repository stub: " + value); } } catch (NamingException e) { throw new RemoteException( "Failed to look up the JNDI resource " + name, e); } } }; } private Repository getRmiRepository(final String name) throws RepositoryException { return new RmiSafeClientRepository(new ClientAdapterFactory()) { @Override protected RemoteRepository getRemoteRepository() throws RemoteException { try { Object value = Naming.lookup(name); if (value instanceof RemoteRepository) { return (RemoteRepository) value; } else { throw new RemoteException("The RMI resource " + name + " is not a remote repository stub: " + value); } } catch (NotBoundException e) { throw new RemoteException( "RMI resource " + name + " not found", e); } catch (MalformedURLException e) { throw new RemoteException("Invalid RMI name: " + name, e); } catch (RemoteException e) { throw new RemoteException("Failed to look up the RMI resource " + name, e); } } }; } /** * Basic SafeClientRepository for the different lookup types of a rmi repository */ private static class RmiSafeClientRepository extends SafeClientRepository { public RmiSafeClientRepository(LocalAdapterFactory factory) { super(factory); } @Override protected RemoteRepository getRemoteRepository() throws RemoteException { return null; } } }