001    /*
002     * JBoss DNA (http://www.jboss.org/dna)
003     * See the COPYRIGHT.txt file distributed with this work for information
004     * regarding copyright ownership.  Some portions may be licensed
005     * to Red Hat, Inc. under one or more contributor license agreements.
006     * See the AUTHORS.txt file in the distribution for a full listing of 
007     * individual contributors. 
008     *
009     * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010     * is licensed to you under the terms of the GNU Lesser General Public License as
011     * published by the Free Software Foundation; either version 2.1 of
012     * the License, or (at your option) any later version.
013     *
014     * JBoss DNA is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this software; if not, write to the Free
021     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023     */
024    package org.jboss.dna.web.jcr.rest.spi;
025    
026    import java.io.IOException;
027    import java.io.InputStream;
028    import java.util.HashSet;
029    import java.util.Set;
030    import javax.jcr.Repository;
031    import javax.jcr.RepositoryException;
032    import javax.jcr.Session;
033    import javax.servlet.ServletContext;
034    import javax.servlet.http.HttpServletRequest;
035    import net.jcip.annotations.ThreadSafe;
036    import org.jboss.dna.jcr.JcrConfiguration;
037    import org.jboss.dna.jcr.JcrEngine;
038    import org.jboss.dna.jcr.SecurityContextCredentials;
039    import org.jboss.dna.web.jcr.rest.ServletSecurityContext;
040    import org.jboss.resteasy.spi.NotFoundException;
041    import org.jboss.resteasy.spi.UnauthorizedException;
042    import org.xml.sax.SAXException;
043    
044    /**
045     * Repository provider backed by the DNA JCR implementation.
046     * <p>
047     * The provider instantiates a {@link JcrEngine} that is {@link JcrConfiguration#loadFrom(InputStream) configured from} the file
048     * in the location specified by the servlet context parameter {@code org.jboss.dna.web.jcr.rest.CONFIG_FILE}. This location must
049     * be accessible by the classloader for this class.
050     * </p>
051     * 
052     * @see RepositoryProvider
053     * @see Class#getResourceAsStream(String)
054     */
055    @ThreadSafe
056    public class DnaJcrRepositoryProvider implements RepositoryProvider {
057    
058        public static final String CONFIG_FILE = "org.jboss.dna.web.jcr.rest.CONFIG_FILE";
059    
060        private JcrEngine jcrEngine;
061    
062        public DnaJcrRepositoryProvider() {
063        }
064    
065        public Set<String> getJcrRepositoryNames() {
066            return new HashSet<String>(jcrEngine.getRepositoryNames());
067        }
068    
069        private Repository getRepository( String repositoryName ) throws RepositoryException {
070            return jcrEngine.getRepository(repositoryName);
071        }
072    
073        public void startup( ServletContext context ) {
074            String configFile = context.getInitParameter(CONFIG_FILE);
075    
076            try {
077                InputStream configFileInputStream = getClass().getResourceAsStream(configFile);
078                jcrEngine = new JcrConfiguration().loadFrom(configFileInputStream).build();
079                jcrEngine.start();
080            } catch (IOException ioe) {
081                throw new IllegalStateException(ioe);
082            } catch (SAXException saxe) {
083                throw new IllegalStateException(saxe);
084            }
085    
086        }
087    
088        public void shutdown() {
089            jcrEngine.shutdown();
090        }
091    
092        /**
093         * Returns an active session for the given workspace name in the named repository.
094         * 
095         * @param request the servlet request; may not be null or unauthenticated
096         * @param repositoryName the name of the repository in which the session is created
097         * @param workspaceName the name of the workspace to which the session should be connected
098         * @return an active session with the given workspace in the named repository
099         * @throws RepositoryException if any other error occurs
100         */
101        public Session getSession( HttpServletRequest request,
102                                   String repositoryName,
103                                   String workspaceName ) throws RepositoryException {
104            assert request != null;
105            assert request.getUserPrincipal() != null : "Request must be authorized";
106    
107            // Sanity check in case assertions are disabled
108            if (request.getUserPrincipal() == null) {
109                throw new UnauthorizedException("Client is not authorized");
110            }
111    
112            Repository repository;
113    
114            try {
115                repository = getRepository(repositoryName);
116    
117            } catch (RepositoryException re) {
118                throw new NotFoundException(re.getMessage(), re);
119            }
120    
121            return repository.login(new SecurityContextCredentials(new ServletSecurityContext(request)), workspaceName);
122    
123        }
124    }