001 /*
002 * JBoss, Home of Professional Open Source.
003 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004 * as indicated by the @author tags. See the copyright.txt file in the
005 * distribution for a full listing of individual contributors.
006 *
007 * This is free software; you can redistribute it and/or modify it
008 * under the terms of the GNU Lesser General Public License as
009 * published by the Free Software Foundation; either version 2.1 of
010 * the License, or (at your option) any later version.
011 *
012 * This software is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this software; if not, write to the Free
019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021 */
022
023 package org.jboss.dna.repository.util;
024
025 import java.util.Map;
026 import java.util.concurrent.ConcurrentHashMap;
027 import javax.jcr.Credentials;
028 import javax.jcr.Repository;
029 import javax.jcr.Session;
030 import javax.naming.InitialContext;
031 import org.jboss.dna.common.SystemFailureException;
032 import org.jboss.dna.repository.RepositoryI18n;
033
034 /**
035 * A SessionFactory implementation that creates {@link Session} instances using {@link Repository} instances registered in JNDI.
036 * <p>
037 * This factory using a naming convention where the name supplied to the {@link #createSession(String)} contains both the name of
038 * the repository and the name of the workspace. Typically, this is <i><code>repositoryName/workspaceName</code></i>, where
039 * <code>repositoryName</code> is the JNDI name under which the Repository instance was bound, and <code>workspaceName</code>
040 * is the name of the workspace. Note that this method looks for the last delimiter in the whole name to distinguish between the
041 * repository and workspace names.
042 * </p>
043 * <p>
044 * For example, if "<code>java:comp/env/repository/dataRepository/myWorkspace</code>" is passed to the
045 * {@link #createSession(String)} method, this factory will look for a {@link Repository} instance registered in JDNI with the
046 * name "<code>java:comp/env/repository/dataRepository</code>" and use it to {@link Repository#login(String) create a session}
047 * to the workspace named "<code>myWorkspace</code>".
048 * </p>
049 * <p>
050 * By default, this factory creates an anonymous JCR session. To use sessions with specific {@link Credentials}, simply
051 * {@link #registerCredentials(String, Credentials) register} credentials for the appropriate repository/workspace name. For
052 * security reasons, it is not possible to retrieve the Credentials once registered with this factory.
053 * </p>
054 *
055 * @author Randall Hauch
056 */
057 public class SimpleSessionFactory extends AbstractSessionFactory {
058
059 private final Map<String, Repository> repositories = new ConcurrentHashMap<String, Repository>();
060
061 /**
062 * Create an instance of the factory by creating a new {@link InitialContext}.
063 */
064 public SimpleSessionFactory() {
065 super();
066 }
067
068 /**
069 * Create an instance of the factory by supplying the characters that may be used to delimit the workspace name from the
070 * repository name.
071 *
072 * @param workspaceDelimiters the delimiters, or null/empty if the default delimiter of '/' should be used.
073 */
074 public SimpleSessionFactory( char... workspaceDelimiters ) {
075 super(workspaceDelimiters);
076 }
077
078 /**
079 * {@inheritDoc}
080 */
081 @Override
082 protected void doRegisterRepository( String name,
083 Repository repository ) {
084 this.repositories.put(name, repository);
085 }
086
087 /**
088 * {@inheritDoc}
089 */
090 @Override
091 protected void doUnregisterRepository( String name ) throws SystemFailureException {
092 if (this.repositories.remove(name) == null) {
093 throw new SystemFailureException(RepositoryI18n.unableToRemoveRepository.text(name));
094 }
095 }
096
097 /**
098 * {@inheritDoc}
099 */
100 @Override
101 protected Repository findRegisteredRepository( String name ) throws SystemFailureException {
102 Repository repository = this.repositories.get(name);
103 if (repository == null) {
104 throw new SystemFailureException(RepositoryI18n.unableToFindRepositoryWithName.text(name));
105 }
106 return repository;
107 }
108
109 }