001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.jcr.jackrabbit;
016    
017    import com.liferay.portal.jcr.JCRFactory;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.FileUtil;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.PropsKeys;
023    import com.liferay.portal.kernel.util.SystemProperties;
024    import com.liferay.portal.kernel.util.Time;
025    import com.liferay.portal.util.PropsUtil;
026    
027    import java.io.File;
028    import java.io.IOException;
029    
030    import javax.jcr.Credentials;
031    import javax.jcr.RepositoryException;
032    import javax.jcr.Session;
033    import javax.jcr.SimpleCredentials;
034    
035    import org.apache.jackrabbit.core.TransientRepository;
036    
037    /**
038     * @author Michael Young
039     */
040    public class JCRFactoryImpl implements JCRFactory {
041    
042            public static final String CONFIG_FILE_PATH = PropsUtil.get(
043                    PropsKeys.JCR_JACKRABBIT_CONFIG_FILE_PATH);
044    
045            public static final char[] CREDENTIALS_PASSWORD = GetterUtil.getString(
046                    PropsUtil.get(PropsKeys.JCR_JACKRABBIT_CREDENTIALS_PASSWORD)).
047                            toCharArray();
048    
049            public static final String CREDENTIALS_USERNAME = PropsUtil.get(
050                    PropsKeys.JCR_JACKRABBIT_CREDENTIALS_USERNAME);
051    
052            public static final String REPOSITORY_HOME = PropsUtil.get(
053                    PropsKeys.JCR_JACKRABBIT_REPOSITORY_HOME);
054    
055            public static final String REPOSITORY_ROOT = PropsUtil.get(
056                    PropsKeys.JCR_JACKRABBIT_REPOSITORY_ROOT);
057    
058            @Override
059            public Session createSession(String workspaceName)
060                    throws RepositoryException {
061    
062                    Credentials credentials = new SimpleCredentials(
063                            CREDENTIALS_USERNAME, CREDENTIALS_PASSWORD);
064    
065                    Session session = null;
066    
067                    try {
068                            session = _transientRepository.login(credentials, workspaceName);
069                    }
070                    catch (RepositoryException re) {
071                            _log.error("Could not login to the workspace " + workspaceName);
072    
073                            throw re;
074                    }
075    
076                    return session;
077            }
078    
079            @Override
080            public void initialize() throws RepositoryException {
081                    Session session = null;
082    
083                    try {
084                            session = createSession(null);
085                    }
086                    catch (RepositoryException re) {
087                            _log.error("Could not initialize Jackrabbit");
088    
089                            throw re;
090                    }
091                    finally {
092                            if (session != null) {
093                                    session.logout();
094                            }
095                    }
096    
097                    _initialized = true;
098            }
099    
100            @Override
101            public void prepare() throws RepositoryException {
102                    try {
103                            File repositoryRoot = new File(JCRFactoryImpl.REPOSITORY_ROOT);
104    
105                            if (repositoryRoot.exists()) {
106                                    return;
107                            }
108    
109                            repositoryRoot.mkdirs();
110    
111                            File tempFile = new File(
112                                    SystemProperties.get(SystemProperties.TMP_DIR) +
113                                            File.separator + Time.getTimestamp());
114    
115                            String repositoryXmlPath =
116                                    "com/liferay/portal/jcr/jackrabbit/dependencies/" +
117                                            "repository-ext.xml";
118    
119                            ClassLoader classLoader = getClass().getClassLoader();
120    
121                            if (classLoader.getResource(repositoryXmlPath) == null) {
122                                    repositoryXmlPath =
123                                            "com/liferay/portal/jcr/jackrabbit/dependencies/" +
124                                                    "repository.xml";
125                            }
126    
127                            FileUtil.write(
128                                    tempFile, classLoader.getResourceAsStream(repositoryXmlPath));
129    
130                            FileUtil.copyFile(
131                                    tempFile, new File(JCRFactoryImpl.CONFIG_FILE_PATH));
132    
133                            tempFile.delete();
134                    }
135                    catch (IOException ioe) {
136                            _log.error("Could not prepare Jackrabbit directory");
137    
138                            throw new RepositoryException(ioe);
139                    }
140            }
141    
142            @Override
143            public void shutdown() {
144                    if (_initialized) {
145                            _transientRepository.shutdown();
146                    }
147    
148                    _initialized = false;
149            }
150    
151            protected JCRFactoryImpl() throws Exception {
152                    try {
153                            _transientRepository = new TransientRepository(
154                                    CONFIG_FILE_PATH, REPOSITORY_HOME);
155                    }
156                    catch (Exception e) {
157                            _log.error("Problem initializing Jackrabbit JCR.", e);
158    
159                            throw e;
160                    }
161    
162                    if (_log.isInfoEnabled()) {
163                            _log.info(
164                                    "Jackrabbit JCR intialized with config file path " +
165                                            CONFIG_FILE_PATH + " and repository home " +
166                                                    REPOSITORY_HOME);
167                    }
168            }
169    
170            private static Log _log = LogFactoryUtil.getLog(JCRFactoryImpl.class);
171    
172            private boolean _initialized;
173            private TransientRepository _transientRepository;
174    
175    }