001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.repository.provider; 017 018import java.util.List; 019import java.util.Map; 020 021import javax.jcr.RepositoryException; 022 023import org.apache.jackrabbit.core.cluster.UpdateEventChannel; 024import org.apache.jackrabbit.core.id.NodeId; 025import org.apache.jackrabbit.core.id.PropertyId; 026import org.apache.jackrabbit.core.persistence.PMContext; 027import org.apache.jackrabbit.core.persistence.PersistenceManager; 028import org.apache.jackrabbit.core.persistence.pool.BundleDbPersistenceManager; 029import org.apache.jackrabbit.core.persistence.pool.DerbyPersistenceManager; 030import org.apache.jackrabbit.core.persistence.pool.MySqlPersistenceManager; 031import org.apache.jackrabbit.core.persistence.pool.OraclePersistenceManager; 032import org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager; 033import org.apache.jackrabbit.core.persistence.util.NodeInfo; 034import org.apache.jackrabbit.core.state.ChangeLog; 035import org.apache.jackrabbit.core.state.ItemStateException; 036import org.apache.jackrabbit.core.state.NoSuchItemStateException; 037import org.apache.jackrabbit.core.state.NodeReferences; 038import org.apache.jackrabbit.core.state.NodeState; 039import org.apache.jackrabbit.core.state.PropertyState; 040import org.apache.jackrabbit.core.util.db.ConnectionFactory; 041 042import org.ametys.core.datasource.AbstractDataSourceManager.DataSourceDefinition; 043import org.ametys.core.datasource.ConnectionHelper; 044import org.ametys.runtime.config.Config; 045 046/** 047 * Ametys implementation of Jackrabbit's {@link PersistenceManager}. 048 * This implementation is only a wrapper to an actual {@link BundleDbPersistenceManager}, depending on the config parameter. 049 */ 050public class AmetysPersistenceManager extends BundleDbPersistenceManager 051{ 052 /** 053 * Config parameter's name to use default Jackrabbit behaviour. 054 */ 055 public static final String CONFIG_USE_DEFAULT = "org.ametys.plugins.repository.default-datasource"; 056 057 /** 058 * Config parameter's name referencing the datasource to use. 059 */ 060 public static final String CONFIG_PM_DATASOURCE = "org.ametys.plugins.repository.datasource"; 061 062 private BundleDbPersistenceManager _wrappedPM; 063 private boolean _useDefault; 064 private String _workspace; 065 066 /** 067 * Constructor. 068 */ 069 public AmetysPersistenceManager() 070 { 071 _useDefault = Config.getInstance().getValueAsBoolean(CONFIG_USE_DEFAULT); 072 073 if (_useDefault) 074 { 075 _wrappedPM = new DerbyPersistenceManager(); 076 _wrappedPM.setSchemaObjectPrefix(""); 077 _wrappedPM.setExternalBLOBs(true); 078 } 079 else 080 { 081 String datasource = Config.getInstance().getValueAsString(CONFIG_PM_DATASOURCE); 082 083 DataSourceDefinition dsDefinition = ConnectionHelper.getDataSourceDefinition(datasource); 084 085 Map<String, String> parameters = dsDefinition.getParameters(); 086 String defUrl = parameters.get("url"); 087 String defDriver = parameters.get("driver"); 088 String defUser = parameters.get("user"); 089 String defPassword = parameters.get("password"); 090 091 String dbType = ConnectionHelper.getDatabaseType(defUrl); 092 switch (dbType) 093 { 094 case ConnectionHelper.DATABASE_DERBY: 095 _wrappedPM = new DerbyPersistenceManager(); 096 break; 097 case ConnectionHelper.DATABASE_MYSQL: 098 _wrappedPM = new MySqlPersistenceManager(); 099 break; 100 case ConnectionHelper.DATABASE_ORACLE: 101 _wrappedPM = new OraclePersistenceManager(); 102 break; 103 case ConnectionHelper.DATABASE_POSTGRES: 104 _wrappedPM = new PostgreSQLPersistenceManager(); 105 break; 106 default: 107 throw new IllegalArgumentException("Datasource URL " + defUrl + " is not supported for Jackrabbit PersistenceManagers."); 108 } 109 110 _wrappedPM.setUrl(defUrl); 111 _wrappedPM.setDriver(defDriver); 112 _wrappedPM.setUser(defUser); 113 _wrappedPM.setPassword(defPassword); 114 } 115 } 116 117 /** 118 * Indicates the current JCR workspace. 119 * @param workspace the JCR workspace. 120 */ 121 public void setWorkspace(String workspace) 122 { 123 _workspace = workspace; 124 } 125 126 // Unsupported methods 127 128 @Override 129 public void setUrl(String newUrl) 130 { 131 throw new UnsupportedOperationException("setUrl() method is not supported for AmetysPersistenceManager."); 132 } 133 134 @Override 135 public void setUser(String unused) 136 { 137 throw new UnsupportedOperationException("setUser() method is not supported for AmetysPersistenceManager."); 138 } 139 140 @Override 141 public void setPassword(String unused) 142 { 143 throw new UnsupportedOperationException("setPassword() method is not supported for AmetysPersistenceManager."); 144 } 145 146 @Override 147 public void setDriver(String unused) 148 { 149 throw new UnsupportedOperationException("setDriver() method is not supported for AmetysPersistenceManager."); 150 } 151 152 // PersistenceManager methods 153 154 @Override 155 public void init(PMContext ctx) throws Exception 156 { 157 if (_useDefault) 158 { 159 String dbUrl = "jdbc:derby:" + ctx.getHomeDir().getCanonicalPath() + "/db;create=true"; 160 _wrappedPM.setUrl(dbUrl); 161 } 162 else 163 { 164 String prefix = _workspace == null ? "version_" : _workspace + "_"; 165 _wrappedPM.setSchemaObjectPrefix(prefix); 166 } 167 168 _wrappedPM.init(ctx); 169 } 170 171 @Override 172 public void close() throws Exception 173 { 174 _wrappedPM.close(); 175 } 176 177 @Override 178 public NodeState createNew(NodeId id) 179 { 180 return _wrappedPM.createNew(id); 181 } 182 183 @Override 184 public PropertyState createNew(PropertyId id) 185 { 186 return _wrappedPM.createNew(id); 187 } 188 189 @Override 190 public NodeState load(NodeId id) throws NoSuchItemStateException, ItemStateException 191 { 192 return _wrappedPM.load(id); 193 } 194 195 @Override 196 public PropertyState load(PropertyId id) throws NoSuchItemStateException, ItemStateException 197 { 198 return _wrappedPM.load(id); 199 } 200 201 @Override 202 public NodeReferences loadReferencesTo(NodeId id) throws NoSuchItemStateException, ItemStateException 203 { 204 return _wrappedPM.loadReferencesTo(id); 205 } 206 207 @Override 208 public boolean exists(NodeId id) throws ItemStateException 209 { 210 return _wrappedPM.exists(id); 211 } 212 213 @Override 214 public boolean exists(PropertyId id) throws ItemStateException 215 { 216 return _wrappedPM.exists(id); 217 } 218 219 @Override 220 public boolean existsReferencesTo(NodeId targetId) throws ItemStateException 221 { 222 return _wrappedPM.existsReferencesTo(targetId); 223 } 224 225 @Override 226 public void store(ChangeLog changeLog) throws ItemStateException 227 { 228 _wrappedPM.store(changeLog); 229 } 230 231 @Override 232 public void checkConsistency(String[] uuids, boolean recursive, boolean fix) 233 { 234 _wrappedPM.checkConsistency(uuids, recursive, fix); 235 } 236 237 // BundleDBPersistenceManager methods 238 239 @Override 240 public synchronized List<NodeId> getAllNodeIds(NodeId bigger, int maxCount) throws ItemStateException, RepositoryException 241 { 242 return _wrappedPM.getAllNodeIds(bigger, maxCount); 243 } 244 245 @Override 246 public synchronized void destroy(NodeReferences refs) throws ItemStateException 247 { 248 _wrappedPM.destroy(refs); 249 } 250 251 @Override 252 public synchronized Map<NodeId, NodeInfo> getAllNodeInfos(NodeId bigger, int maxCount) throws ItemStateException 253 { 254 return _wrappedPM.getAllNodeInfos(bigger, maxCount); 255 } 256 257 258 259 @Override 260 public void setBlockOnConnectionLoss(String block) 261 { 262 _wrappedPM.setBlockOnConnectionLoss(block); 263 } 264 265 @Override 266 public void setBundleCacheSize(String bundleCacheSize) 267 { 268 _wrappedPM.setBundleCacheSize(bundleCacheSize); 269 } 270 271 @Override 272 public void setConnectionFactory(ConnectionFactory connectionFactory) 273 { 274 _wrappedPM.setConnectionFactory(connectionFactory); 275 } 276 277 @Override 278 public void setConsistencyCheck(String check) 279 { 280 _wrappedPM.setConsistencyCheck(check); 281 } 282 283 @Override 284 public void setConsistencyFix(String fix) 285 { 286 _wrappedPM.setConsistencyFix(fix); 287 } 288 289 @Override 290 public void setErrorHandling(String errHandling) 291 { 292 _wrappedPM.setErrorHandling(errHandling); 293 } 294 295 @Override 296 public void setEventChannel(UpdateEventChannel eventChannel) 297 { 298 _wrappedPM.setEventChannel(eventChannel); 299 } 300 301 @Override 302 public void setExternalBLOBs(boolean externalBlobs) 303 { 304 _wrappedPM.setExternalBLOBs(externalBlobs); 305 } 306 307 @Override 308 public void setMinBlobSize(String minBlobSize) 309 { 310 _wrappedPM.setMinBlobSize(minBlobSize); 311 } 312 313 @Override 314 public void setSchemaObjectPrefix(String schemaPrefix) 315 { 316 _wrappedPM.setSchemaObjectPrefix(schemaPrefix); 317 } 318}