001    package org.apache.archiva.metadata.repository;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.slf4j.Logger;
023    import org.slf4j.LoggerFactory;
024    
025    /**
026     * The repository session provides a single interface to accessing Archiva repositories. It provides access to three
027     * resources:
028     * <ul>
029     * <li>{@link MetadataRepository} - the metadata content repository for read/write access, in its current state (no
030     * remote resources will be retrieved in the process</li>
031     * <li>{@link MetadataResolver} - access to resolve metadata content, accommodating metadata not yet stored or up to
032     * date in the content repository (i.e. virtualised repositories, remote proxied content, or metadata in a different
033     * model format in the repository storage)</li>
034     * <li>{@link org.apache.archiva.metadata.repository.storage.RepositoryStorage} - access to the physical storage of a
035     * repository and the source artifacts and project models</li>
036     * </ul>
037     */
038    public class RepositorySession
039    {
040        private final MetadataRepository repository;
041    
042        private final MetadataResolver resolver;
043    
044        private boolean dirty;
045    
046        private Logger log = LoggerFactory.getLogger( getClass() );
047    
048        // FIXME: include storage here too - perhaps a factory based on repository ID, or one per type to retrieve and
049        //        operate on a given repo within the storage API
050    
051        public RepositorySession( MetadataRepository metadataRepository, MetadataResolver resolver )
052        {
053            this.repository = metadataRepository;
054            this.resolver = resolver;
055        }
056    
057        public MetadataRepository getRepository()
058        {
059            return repository;
060        }
061    
062        public MetadataResolver getResolver()
063        {
064            return resolver;
065        }
066    
067        public void save()
068        {
069            repository.save();
070    
071            dirty = false;
072        }
073    
074        public void revert()
075        {
076            repository.revert();
077            dirty = false;
078        }
079    
080        /**
081         * Close the session. Required to be called for all open sessions to ensure resources are properly released.
082         * If the session has been marked as dirty, it will be saved. This may save partial changes in the case of a typical
083         * <code>try { ... } finally { ... }</code> approach - if this is a problem, ensure you revert changes when an
084         * exception occurs.
085         * <b>can throw RuntimeException</b>
086         */
087        public void close()
088        {
089            try
090            {
091                if ( dirty )
092                {
093                    save();
094                }
095            }
096            finally
097            {
098                try
099                {
100                    repository.close();
101                }
102                catch ( MetadataRepositoryException e )
103                {
104                    throw new RuntimeException( e.getMessage(), e );
105                }
106            }
107        }
108    
109        /**
110         * ignore RuntimeException when closing repository
111         * @since 1.4-M4
112         */
113        public void closeQuietly()
114        {
115            try
116            {
117                this.close();
118            }
119            catch ( RuntimeException e )
120            {
121                log.warn( "ignore Runtime exception while closing: {}", e.getMessage(), e );
122            }
123        }
124    
125    
126        public void markDirty()
127        {
128            this.dirty = true;
129        }
130    }