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.repository.util; 025 026 import java.util.HashSet; 027 import java.util.Set; 028 import java.util.concurrent.atomic.AtomicBoolean; 029 import javax.jcr.RepositoryException; 030 import javax.jcr.Session; 031 import org.jboss.dna.graph.ExecutionContext; 032 import org.jboss.dna.repository.RepositoryI18n; 033 034 /** 035 * The context of an execution within a JCR environment. 036 * 037 * @author Randall Hauch 038 */ 039 public class JcrExecutionContext extends ExecutionContext { 040 041 private final String repositoryWorkspaceForNamespaceRegistry; 042 private final ClosableSessionFactory sessionFactory; 043 private final JcrTools jcrTools; 044 045 public JcrExecutionContext( ExecutionContext context, 046 final SessionFactory sessionFactory, 047 String repositoryWorkspaceForNamespaceRegistry ) { 048 super(context.with(new JcrNamespaceRegistry(sessionFactory, repositoryWorkspaceForNamespaceRegistry))); 049 this.sessionFactory = new ClosableSessionFactory(sessionFactory); 050 this.jcrTools = new JcrTools(); 051 this.repositoryWorkspaceForNamespaceRegistry = repositoryWorkspaceForNamespaceRegistry; 052 } 053 054 public JcrExecutionContext( SessionFactory sessionFactory, 055 String repositoryWorkspaceForNamespaceRegistry ) { 056 this(new ExecutionContext(), sessionFactory, repositoryWorkspaceForNamespaceRegistry); 057 } 058 059 /** 060 * Get the session factory, which can be used to obtain sessions temporarily for this context. Any session obtained from this 061 * factory should be {@link Session#logout() closed} before the execution finishes. 062 * 063 * @return the session factory 064 */ 065 public SessionFactory getSessionFactory() { 066 return this.sessionFactory; 067 } 068 069 /** 070 * Get a set of utilities for working with JCR. 071 * 072 * @return the tools 073 */ 074 public JcrTools getTools() { 075 return this.jcrTools; 076 } 077 078 /** 079 * {@inheritDoc} 080 * 081 * @see org.jboss.dna.graph.ExecutionContext#clone() 082 */ 083 @Override 084 public JcrExecutionContext clone() { 085 return new JcrExecutionContext(this, this.sessionFactory.getDelegateFactory(), 086 this.repositoryWorkspaceForNamespaceRegistry); 087 } 088 089 /** 090 * This this context and release all resources (including any Session instances created). 091 */ 092 public void close() { 093 this.sessionFactory.close(); 094 } 095 096 protected static class ClosableSessionFactory implements SessionFactory { 097 private final SessionFactory delegateFactory; 098 private final Set<Session> sessions = new HashSet<Session>(); 099 protected final AtomicBoolean closed = new AtomicBoolean(false); 100 101 protected ClosableSessionFactory( SessionFactory sessionFactory ) { 102 this.delegateFactory = sessionFactory; 103 } 104 105 public SessionFactory getDelegateFactory() { 106 return this.delegateFactory; 107 } 108 109 public Session createSession( String name ) throws RepositoryException { 110 if (closed.get()) throw new IllegalStateException(RepositoryI18n.executionContextHasBeenClosed.text()); 111 Session session = delegateFactory.createSession(name); 112 if (session != null) sessions.add(session); 113 return session; 114 } 115 116 public synchronized void close() { 117 if (this.closed.get()) return; 118 this.closed.set(true); 119 for (Session session : sessions) { 120 if (session != null) session.logout(); 121 } 122 } 123 } 124 125 }