001    package org.apache.archiva.metadata.repository.jcr;
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.apache.archiva.metadata.model.MetadataFacetFactory;
023    import org.apache.archiva.metadata.repository.MetadataRepository;
024    import org.apache.archiva.metadata.repository.MetadataResolver;
025    import org.apache.archiva.metadata.repository.RepositorySession;
026    import org.apache.archiva.metadata.repository.RepositorySessionFactory;
027    import org.apache.commons.lang.StringUtils;
028    import org.apache.commons.lang.time.StopWatch;
029    import org.slf4j.Logger;
030    import org.slf4j.LoggerFactory;
031    import org.springframework.context.ApplicationContext;
032    import org.springframework.stereotype.Service;
033    
034    import javax.annotation.PostConstruct;
035    import javax.inject.Inject;
036    import javax.jcr.Repository;
037    import javax.jcr.RepositoryException;
038    import java.util.HashMap;
039    import java.util.Map;
040    
041    /**
042     *
043     */
044    @Service("repositorySessionFactory#jcr")
045    public class JcrRepositorySessionFactory
046        implements RepositorySessionFactory
047    {
048    
049        private Logger logger = LoggerFactory.getLogger( getClass() );
050    
051        @Inject
052        private ApplicationContext applicationContext;
053    
054        /**
055         *
056         */
057        private Map<String, MetadataFacetFactory> metadataFacetFactories;
058    
059        /**
060         *
061         */
062        @Inject
063        private Repository repository;
064    
065        /**
066         *
067         */
068        @Inject
069        private MetadataResolver metadataResolver;
070    
071        public RepositorySession createSession()
072        {
073            try
074            {
075                // FIXME: is this the right separation? or should a JCR session object contain the JCR session information?
076                //  such a change might allow us to avoid creating two objects for each request. It would also clear up
077                //  the ambiguities in the API where session & repository are the inverse of JCR; and the resolver is
078                //  retrieved from the session but must have it passed in. These should be reviewed before finalising the
079                //  API.
080                MetadataRepository metadataRepository = new JcrMetadataRepository( metadataFacetFactories, repository );
081    
082                return new RepositorySession( metadataRepository, metadataResolver );
083            }
084            catch ( RepositoryException e )
085            {
086                // FIXME: a custom exception requires refactoring for callers to handle it
087                throw new RuntimeException( e );
088            }
089        }
090    
091        @PostConstruct
092        public void initialize()
093            throws Exception
094        {
095            StopWatch stopWatch = new StopWatch();
096            stopWatch.start();
097    
098            metadataFacetFactories = applicationContext.getBeansOfType( MetadataFacetFactory.class );
099            // olamy with spring the "id" is now "metadataFacetFactory#hint"
100            // whereas was only hint with plexus so let remove  metadataFacetFactory#
101            Map<String, MetadataFacetFactory> cleanedMetadataFacetFactories =
102                new HashMap<String, MetadataFacetFactory>( metadataFacetFactories.size() );
103    
104            for ( Map.Entry<String, MetadataFacetFactory> entry : metadataFacetFactories.entrySet() )
105            {
106                cleanedMetadataFacetFactories.put( StringUtils.substringAfterLast( entry.getKey(), "#" ),
107                                                   entry.getValue() );
108            }
109    
110            metadataFacetFactories = cleanedMetadataFacetFactories;
111    
112            JcrMetadataRepository metadataRepository = null;
113            try
114            {
115                metadataRepository = new JcrMetadataRepository( metadataFacetFactories, repository );
116                JcrMetadataRepository.initialize( metadataRepository.getJcrSession() );
117            }
118            catch ( RepositoryException e )
119            {
120                throw new RuntimeException( e.getMessage(), e );
121            }
122            finally
123            {
124                if ( metadataRepository != null )
125                {
126                    metadataRepository.close();
127                }
128            }
129    
130            stopWatch.stop();
131            logger.info( "time to initialize JcrRepositorySessionFactory: {}", stopWatch.getTime() );
132        }
133    }