001    /*
002     * $Revision: 14968 $ 
003     * $Date: 2009-03-19 13:08:02 +0100 (Thu, 19 Mar 2009) $
004     *
005     * This file is part of ***  M y C o R e  ***
006     * See http://www.mycore.de/ for details.
007     *
008     * This program is free software; you can use it, redistribute it
009     * and / or modify it under the terms of the GNU General Public License
010     * (GPL) as published by the Free Software Foundation; either version 2
011     * of the License or (at your option) any later version.
012     *
013     * This program is distributed in the hope that it will be useful, but
014     * WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program, in a file called gpl.txt or license.txt.
020     * If not, write to the Free Software Foundation Inc.,
021     * 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
022     */
023    
024    package org.mycore.datamodel.ifs2;
025    
026    import java.io.File;
027    import java.util.Iterator;
028    
029    import org.apache.commons.vfs.FileObject;
030    import org.apache.log4j.Logger;
031    import org.mycore.common.MCRConfiguration;
032    import org.mycore.common.MCRConfigurationException;
033    import org.mycore.common.MCRSessionMgr;
034    import org.tmatesoft.svn.core.SVNException;
035    import org.tmatesoft.svn.core.SVNURL;
036    import org.tmatesoft.svn.core.auth.BasicAuthenticationManager;
037    import org.tmatesoft.svn.core.auth.SVNAuthentication;
038    import org.tmatesoft.svn.core.auth.SVNUserNameAuthentication;
039    import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
040    import org.tmatesoft.svn.core.io.SVNRepository;
041    import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
042    
043    /**
044     * Stores metadata objects both in a local filesystem structure and in a
045     * Subversion repository. Changes can be tracked and restored. To enable
046     * versioning, configure the repository URL, for example
047     * 
048     * MCR.IFS2.Store.DocPortal_document.SVNRepositoryURL=file:///foo/svnroot/
049     * 
050     * @author Frank Lützenkirchen
051     */
052    public class MCRVersioningMetadataStore extends MCRMetadataStore {
053    
054        protected final static Logger LOGGER = Logger.getLogger(MCRVersioningMetadataStore.class);
055    
056        protected SVNURL repURL;
057    
058        static {
059            FSRepositoryFactory.setup();
060        }
061    
062        /**
063         * Returns the store for the given metadata document type
064         * 
065         * @param type
066         *            the type of metadata to store
067         * @return the store for this metadata type
068         */
069        public static MCRVersioningMetadataStore getStore(String type) {
070            return (MCRVersioningMetadataStore) (MCRStore.getStore(type));
071        }
072    
073        protected void init(String type) {
074            super.init(type);
075    
076            String repositoryURL = MCRConfiguration.instance().getString("MCR.IFS2.Store." + type + ".SVNRepositoryURL");
077            try {
078                LOGGER.info("Versioning metadata store " + type + " repository URL: " + repositoryURL);
079                repURL = SVNURL.parseURIDecoded(repositoryURL);
080                File dir = new File(repURL.getPath());
081                if (!dir.exists()) {
082                    LOGGER.info("Repository does not exist, creating new SVN repository at " + repositoryURL);
083                    repURL = SVNRepositoryFactory.createLocalRepository(dir, true, false);
084                }
085            } catch (SVNException ex) {
086                String msg = "Error initializing SVN repository at URL " + repositoryURL;
087                throw new MCRConfigurationException(msg, ex);
088            }
089        }
090    
091        /**
092         * Returns the SVN repository used to manage metadata versions in this
093         * store.
094         * 
095         * @return the SVN repository used to manage metadata versions in this
096         *         store.
097         */
098        SVNRepository getRepository() throws Exception {
099            SVNRepository repository = SVNRepositoryFactory.create(repURL);
100            String user = MCRSessionMgr.getCurrentSession().getCurrentUserID();
101            SVNAuthentication[] auth = new SVNAuthentication[] { new SVNUserNameAuthentication(user, false) };
102            BasicAuthenticationManager authManager = new BasicAuthenticationManager(auth);
103            repository.setAuthenticationManager(authManager);
104            return repository;
105        }
106    
107        /**
108         * Returns the URL of the SVN repository used to manage metadata versions in
109         * this store.
110         * 
111         * @return the URL of the SVN repository used to manage metadata versions in
112         *         this store.
113         */
114        SVNURL getRepositoryURL() throws Exception {
115            return repURL;
116        }
117    
118        public MCRVersionedMetadata create(MCRContent xml, int id) throws Exception {
119            return (MCRVersionedMetadata) (super.create(xml, id));
120        }
121    
122        public MCRVersionedMetadata create(MCRContent xml) throws Exception {
123            return (MCRVersionedMetadata) (super.create(xml));
124        }
125    
126        /**
127         * Returns the metadata stored under the given ID, or null. Note that this
128         * metadata may not exist currently in the store, it may be a deleted
129         * version, which can be restored then.
130         * 
131         * @param id
132         *            the ID of the XML document
133         * @return the metadata stored under that ID, or null when there is no such
134         *         metadata object
135         */
136        public MCRVersionedMetadata retrieve(int id) throws Exception {
137            if (exists(id))
138                return (MCRVersionedMetadata) (super.retrieve(id));
139            else
140                return new MCRVersionedMetadata(this, getSlot(id), id);
141        }
142    
143        /**
144         * Updates all stored metadata to the latest revision in SVN
145         */
146        public void updateAll() throws Exception {
147            for (Iterator<Integer> ids = listIDs(true); ids.hasNext();)
148                retrieve(ids.next()).update();
149        }
150    
151        public void delete(int id) throws Exception {
152            MCRVersionedMetadata vm = retrieve(id);
153            vm.delete();
154        }
155    
156        protected MCRVersionedMetadata buildMetadataObject(FileObject fo, int id) {
157            return new MCRVersionedMetadata(this, fo, id);
158        }
159    }