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     * Unless otherwise indicated, all code in JBoss DNA is licensed
010     * 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.jcr;
025    
026    import java.util.Collections;
027    import java.util.HashMap;
028    import java.util.Map;
029    import java.util.concurrent.locks.Lock;
030    import java.util.concurrent.locks.ReentrantLock;
031    import javax.jcr.Repository;
032    import javax.jcr.RepositoryException;
033    import org.jboss.dna.common.collection.Problems;
034    import org.jboss.dna.common.util.CheckArg;
035    import org.jboss.dna.graph.ExecutionContext;
036    import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
037    import org.jboss.dna.graph.connector.RepositorySource;
038    import org.jboss.dna.jcr.JcrRepository.Options;
039    import org.jboss.dna.repository.DnaEngine;
040    import org.jboss.dna.repository.RepositoryService;
041    import org.jboss.dna.repository.observation.ObservationService;
042    import org.jboss.dna.repository.sequencer.SequencingService;
043    
044    /**
045     * The basic component that encapsulates the JBoss DNA services, including the {@link Repository} instances.
046     */
047    public class JcrEngine {
048    
049        private final DnaEngine dnaEngine;
050        private final Map<String, JcrRepository> repositories;
051        private final Lock repositoriesLock;
052    
053        JcrEngine( DnaEngine dnaEngine ) {
054            this.dnaEngine = dnaEngine;
055            this.repositories = new HashMap<String, JcrRepository>();
056            this.repositoriesLock = new ReentrantLock();
057        }
058    
059        /**
060         * Get the problems that were encountered when setting up this engine from the configuration.
061         * 
062         * @return the problems, which may be empty but will never be null
063         */
064        public Problems getProblems() {
065            return dnaEngine.getProblems();
066        }
067    
068        /**
069         * Get the execution context for this engine. This context can be used to create additional (perhaps narrowed) contexts.
070         * 
071         * @return the engine's execution context; never null
072         */
073        public final ExecutionContext getExecutionContext() {
074            return dnaEngine.getExecutionContext();
075        }
076    
077        /**
078         * Get the RepositorySource with the supplied name.
079         * 
080         * @param repositoryName the name of the repository (or repository source)
081         * @return the named repository source, or null if there is no such repository
082         */
083        protected final RepositorySource getRepositorySource( String repositoryName ) {
084            return dnaEngine.getRepositorySource(repositoryName);
085        }
086    
087        protected final RepositoryConnectionFactory getRepositoryConnectionFactory() {
088            return dnaEngine.getRepositoryConnectionFactory();
089        }
090    
091        protected final RepositoryService getRepositoryService() {
092            return dnaEngine.getRepositoryService();
093        }
094    
095        protected final ObservationService getObservationService() {
096            return dnaEngine.getObservationService();
097        }
098    
099        protected final SequencingService getSequencingService() {
100            return dnaEngine.getSequencingService();
101        }
102    
103        /**
104         * Get the {@link Repository} implementation for the named repository.
105         * 
106         * @param repositoryName the name of the repository, which corresponds to the name of a configured {@link RepositorySource}
107         * @return the named repository instance
108         * @throws IllegalArgumentException if the repository name is null, blank or invalid
109         * @throws RepositoryException if there is no repository with the specified name
110         */
111        public final Repository getRepository( String repositoryName ) throws RepositoryException {
112            CheckArg.isNotEmpty(repositoryName, "repositoryName");
113            try {
114                repositoriesLock.lock();
115                JcrRepository repository = repositories.get(repositoryName);
116                if (repository == null) {
117                    if (getRepositorySource(repositoryName) == null) {
118                        // The repository name is not a valid repository ...
119                        String msg = JcrI18n.repositoryDoesNotExist.text(repositoryName);
120                        throw new RepositoryException(msg);
121                    }
122                    repository = doCreateJcrRepository(repositoryName);
123                    repositories.put(repositoryName, repository);
124                }
125                return repository;
126            } finally {
127                repositoriesLock.unlock();
128            }
129        }
130    
131        protected JcrRepository doCreateJcrRepository( String repositoryName ) {
132            RepositoryConnectionFactory connectionFactory = getRepositoryConnectionFactory();
133            Map<String, String> descriptors = null;
134            Map<Options, String> options = Collections.singletonMap(Options.PROJECT_NODE_TYPES, "false");
135            return new JcrRepository(getExecutionContext(), connectionFactory, repositoryName, descriptors, options);
136        }
137    
138        /*
139         * Lifecycle methods
140         */
141    
142        public void start() {
143            dnaEngine.start();
144        }
145    
146        public void shutdown() {
147            dnaEngine.shutdown();
148        }
149    }