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 javax.jcr.Credentials;
026 import javax.jcr.Repository;
027 import javax.jcr.Session;
028 import javax.naming.Context;
029 import javax.naming.InitialContext;
030 import javax.naming.NamingException;
031 import org.jboss.dna.common.SystemFailureException;
032 import org.jboss.dna.common.util.CheckArg;
033 import org.jboss.dna.repository.RepositoryI18n;
034
035 /**
036 * A SessionFactory implementation that creates {@link Session} instances using {@link Repository} instances registered in JNDI.
037 * <p>
038 * This factory using a naming convention where the name supplied to the {@link #createSession(String)} contains both the name of
039 * the repository and the name of the workspace. Typically, this is <i><code>repositoryName/workspaceName</code></i>, where
040 * <code>repositoryName</code> is the JNDI name under which the Repository instance was bound, and <code>workspaceName</code>
041 * is the name of the workspace. Note that this method looks for the last delimiter in the whole name to distinguish between the
042 * repository and workspace names.
043 * </p>
044 * <p>
045 * For example, if "<code>java:comp/env/repository/dataRepository/myWorkspace</code>" is passed to the
046 * {@link #createSession(String)} method, this factory will look for a {@link Repository} instance registered in JDNI with the
047 * name "<code>java:comp/env/repository/dataRepository</code>" and use it to {@link Repository#login(String) create a session}
048 * to the workspace named "<code>myWorkspace</code>".
049 * </p>
050 * <p>
051 * By default, this factory creates an anonymous JCR session. To use sessions with specific {@link Credentials}, simply
052 * {@link #registerCredentials(String, Credentials) register} credentials for the appropriate repository/workspace name. For
053 * security reasons, it is not possible to retrieve the Credentials once registered with this factory.
054 * </p>
055 * @author Randall Hauch
056 */
057 public class JndiSessionFactory extends AbstractSessionFactory {
058
059 private final Context context;
060
061 /**
062 * Create an instance of the factory by creating a new {@link InitialContext}. This is equivalent to calling
063 * <code>new JndiSessionFactory(new InitialContext())</code>.
064 * @throws NamingException if there is a problem creating the InitialContext.
065 */
066 public JndiSessionFactory() throws NamingException {
067 this(new InitialContext());
068 }
069
070 /**
071 * Create an instance of the factory by supplying the characters that may be used to delimit the workspace name from the
072 * repository name. This constructor initializes the factory with a new {@link InitialContext}, and is equivalent to calling
073 * <code>new JndiSessionFactory(new InitialContext(),workspaceDelimiters)</code>.
074 * @param workspaceDelimiters the delimiters, or null/empty if the default delimiter of '/' should be used.
075 * @throws NamingException if there is a problem creating the InitialContext.
076 */
077 public JndiSessionFactory( char... workspaceDelimiters ) throws NamingException {
078 this(new InitialContext(), workspaceDelimiters);
079 }
080
081 /**
082 * Create an instance of the factory using the supplied JNDI context.
083 * @param context the naming context
084 * @throws IllegalArgumentException if the context parameter is null
085 */
086 public JndiSessionFactory( Context context ) {
087 this(context, DEFAULT_DELIMITERS);
088 }
089
090 /**
091 * Create an instance of the factory by supplying naming context and the characters that may be used to delimit the workspace
092 * name from the repository name.
093 * @param context the naming context
094 * @param workspaceDelimiters the delimiters, or null/empty if the default delimiter of '/' should be used.
095 * @throws IllegalArgumentException if the context parameter is null
096 */
097 public JndiSessionFactory( Context context, char... workspaceDelimiters ) {
098 super(workspaceDelimiters);
099 CheckArg.isNotNull(context, "initial context");
100 this.context = context;
101 }
102
103 /**
104 * {@inheritDoc}
105 */
106 @Override
107 protected void doRegisterRepository( String name, Repository repository ) throws SystemFailureException {
108 try {
109 this.context.bind(name, repository);
110 } catch (NamingException e) {
111 throw new SystemFailureException(RepositoryI18n.unableToRegisterRepositoryInJndi.text(name));
112 }
113 }
114
115 /**
116 * {@inheritDoc}
117 */
118 @Override
119 protected void doUnregisterRepository( String name ) throws SystemFailureException {
120 try {
121 this.context.unbind(name);
122 } catch (NamingException e) {
123 throw new SystemFailureException(RepositoryI18n.unableToUnregisterRepositoryInJndi.text(name));
124 }
125 }
126
127 /**
128 * {@inheritDoc}
129 */
130 @Override
131 protected Repository findRegisteredRepository( String name ) throws SystemFailureException {
132 try {
133 return (Repository)this.context.lookup(name);
134 } catch (NamingException e) {
135 throw new SystemFailureException(RepositoryI18n.unableToFindRepositoryInJndi.text(name));
136 }
137 }
138 }