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().getValue(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().getValue(CONFIG_PM_DATASOURCE); 082 083 DataSourceDefinition dsDefinition = ConnectionHelper.getDataSourceDefinition(datasource); 084 085 Map<String, Object> parameters = dsDefinition.getParameters(); 086 String defUrl = (String) parameters.get("url"); 087 String defDriver = (String) parameters.get("driver"); 088 String defUser = (String) parameters.get("user"); 089 String defPassword = (String) 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 * Get the wrapped persistence manager 119 * @return the persistence manager 120 */ 121 public BundleDbPersistenceManager getWrappedPM() 122 { 123 return _wrappedPM; 124 } 125 126 /** 127 * Indicates the current JCR workspace. 128 * @param workspace the JCR workspace. 129 */ 130 public void setWorkspace(String workspace) 131 { 132 _workspace = workspace; 133 } 134 135 // Unsupported methods 136 137 @Override 138 public void setUrl(String newUrl) 139 { 140 throw new UnsupportedOperationException("setUrl() method is not supported for AmetysPersistenceManager."); 141 } 142 143 @Override 144 public void setUser(String unused) 145 { 146 throw new UnsupportedOperationException("setUser() method is not supported for AmetysPersistenceManager."); 147 } 148 149 @Override 150 public void setPassword(String unused) 151 { 152 throw new UnsupportedOperationException("setPassword() method is not supported for AmetysPersistenceManager."); 153 } 154 155 @Override 156 public void setDriver(String unused) 157 { 158 throw new UnsupportedOperationException("setDriver() method is not supported for AmetysPersistenceManager."); 159 } 160 161 // PersistenceManager methods 162 163 @Override 164 public void init(PMContext ctx) throws Exception 165 { 166 if (_useDefault) 167 { 168 String dbUrl = "jdbc:derby:" + ctx.getHomeDir().getCanonicalPath() + "/db;create=true"; 169 _wrappedPM.setUrl(dbUrl); 170 } 171 else 172 { 173 String prefix = _workspace == null ? "version_" : _workspace + "_"; 174 _wrappedPM.setSchemaObjectPrefix(prefix); 175 } 176 177 _wrappedPM.init(ctx); 178 } 179 180 @Override 181 public void close() throws Exception 182 { 183 _wrappedPM.close(); 184 } 185 186 @Override 187 public NodeState createNew(NodeId id) 188 { 189 return _wrappedPM.createNew(id); 190 } 191 192 @Override 193 public PropertyState createNew(PropertyId id) 194 { 195 return _wrappedPM.createNew(id); 196 } 197 198 @Override 199 public NodeState load(NodeId id) throws NoSuchItemStateException, ItemStateException 200 { 201 return _wrappedPM.load(id); 202 } 203 204 @Override 205 public PropertyState load(PropertyId id) throws NoSuchItemStateException, ItemStateException 206 { 207 return _wrappedPM.load(id); 208 } 209 210 @Override 211 public NodeReferences loadReferencesTo(NodeId id) throws NoSuchItemStateException, ItemStateException 212 { 213 return _wrappedPM.loadReferencesTo(id); 214 } 215 216 @Override 217 public boolean exists(NodeId id) throws ItemStateException 218 { 219 return _wrappedPM.exists(id); 220 } 221 222 @Override 223 public boolean exists(PropertyId id) throws ItemStateException 224 { 225 return _wrappedPM.exists(id); 226 } 227 228 @Override 229 public boolean existsReferencesTo(NodeId targetId) throws ItemStateException 230 { 231 return _wrappedPM.existsReferencesTo(targetId); 232 } 233 234 @Override 235 public void store(ChangeLog changeLog) throws ItemStateException 236 { 237 _wrappedPM.store(changeLog); 238 } 239 240 @Override 241 public void checkConsistency(String[] uuids, boolean recursive, boolean fix) 242 { 243 _wrappedPM.checkConsistency(uuids, recursive, fix); 244 } 245 246 // BundleDBPersistenceManager methods 247 248 @Override 249 public synchronized List<NodeId> getAllNodeIds(NodeId bigger, int maxCount) throws ItemStateException, RepositoryException 250 { 251 return _wrappedPM.getAllNodeIds(bigger, maxCount); 252 } 253 254 @Override 255 public synchronized void destroy(NodeReferences refs) throws ItemStateException 256 { 257 _wrappedPM.destroy(refs); 258 } 259 260 @Override 261 public synchronized Map<NodeId, NodeInfo> getAllNodeInfos(NodeId bigger, int maxCount) throws ItemStateException 262 { 263 return _wrappedPM.getAllNodeInfos(bigger, maxCount); 264 } 265 266 267 268 @Override 269 public void setBlockOnConnectionLoss(String block) 270 { 271 _wrappedPM.setBlockOnConnectionLoss(block); 272 } 273 274 @Override 275 public void setBundleCacheSize(String bundleCacheSize) 276 { 277 _wrappedPM.setBundleCacheSize(bundleCacheSize); 278 } 279 280 @Override 281 public void setConnectionFactory(ConnectionFactory connectionFactory) 282 { 283 _wrappedPM.setConnectionFactory(connectionFactory); 284 } 285 286 @Override 287 public void setConsistencyCheck(String check) 288 { 289 _wrappedPM.setConsistencyCheck(check); 290 } 291 292 @Override 293 public void setConsistencyFix(String fix) 294 { 295 _wrappedPM.setConsistencyFix(fix); 296 } 297 298 @Override 299 public void setErrorHandling(String errHandling) 300 { 301 _wrappedPM.setErrorHandling(errHandling); 302 } 303 304 @Override 305 public void setEventChannel(UpdateEventChannel eventChannel) 306 { 307 _wrappedPM.setEventChannel(eventChannel); 308 } 309 310 @Override 311 public void setExternalBLOBs(boolean externalBlobs) 312 { 313 _wrappedPM.setExternalBLOBs(externalBlobs); 314 } 315 316 @Override 317 public void setMinBlobSize(String minBlobSize) 318 { 319 _wrappedPM.setMinBlobSize(minBlobSize); 320 } 321 322 @Override 323 public void setSchemaObjectPrefix(String schemaPrefix) 324 { 325 _wrappedPM.setSchemaObjectPrefix(schemaPrefix); 326 } 327}