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.core.script; 017 018import java.sql.Connection; 019import java.util.HashSet; 020import java.util.Set; 021 022import org.apache.avalon.framework.configuration.Configurable; 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.ConfigurationException; 025import org.apache.avalon.framework.logger.AbstractLogEnabled; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029import org.apache.commons.lang3.StringUtils; 030import org.apache.commons.lang3.Strings; 031import org.apache.excalibur.source.SourceResolver; 032 033import org.ametys.core.datasource.ConnectionHelper; 034import org.ametys.core.datasource.SQLDataSourceManager; 035import org.ametys.runtime.config.Config; 036import org.ametys.runtime.plugin.Init; 037import org.ametys.runtime.plugin.component.PluginAware; 038 039/** 040 * Creates necessary SQL tables (if not already existing) at initialization. 041 */ 042public class SqlTablesInit extends AbstractLogEnabled implements Init, Serviceable, Configurable, PluginAware 043{ 044 /** Plugin name */ 045 protected String _pluginName; 046 047 /** The data source identifer */ 048 protected String _dataSourceId; 049 050 /** The set of configured table init scripts */ 051 protected Set<InitScript> _scripts; 052 053 /** SQL data source manager */ 054 protected SQLDataSourceManager _sqlDataSourceManager; 055 056 /** Source resolver */ 057 protected SourceResolver _sourceResolver; 058 059 @Override 060 public void setPluginInfo(String pluginName, String featureName, String id) 061 { 062 _pluginName = pluginName; 063 } 064 065 @Override 066 public void service(ServiceManager manager) throws ServiceException 067 { 068 _sqlDataSourceManager = (SQLDataSourceManager) manager.lookup(SQLDataSourceManager.ROLE); 069 _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 070 } 071 072 @Override 073 public void configure(Configuration configuration) throws ConfigurationException 074 { 075 Configuration dataSourceConf = configuration.getChild("datasource", false); 076 if (dataSourceConf == null) 077 { 078 throw new ConfigurationException("The 'datasource' configuration node must be defined.", dataSourceConf); 079 } 080 081 String dataSourceConfParam = dataSourceConf.getValue(); 082 String dataSourceConfType = dataSourceConf.getAttribute("type", "config"); 083 084 if (Strings.CS.equals(dataSourceConfType, "config")) 085 { 086 _dataSourceId = Config.getInstance().getValue(dataSourceConfParam); 087 } 088 else // expecting type="id" 089 { 090 _dataSourceId = dataSourceConfParam; 091 } 092 093 _scripts = new HashSet<>(); 094 Configuration[] scripts = configuration.getChildren("script"); 095 096 for (Configuration scriptConf : scripts) 097 { 098 String pluginName = scriptConf.getAttribute("plugin", _pluginName); 099 100 String testTable = scriptConf.getAttribute("testTable"); 101 if (StringUtils.isBlank(testTable)) 102 { 103 throw new ConfigurationException("The test table attribute cannot be blank."); 104 } 105 106 String fileName = scriptConf.getValue(); 107 if (StringUtils.isBlank(fileName)) 108 { 109 throw new ConfigurationException("The SQL file name cannot be blank."); 110 } 111 112 _scripts.add(new InitScript(pluginName, fileName, testTable)); 113 } 114 } 115 116 @Override 117 public void init() throws Exception 118 { 119 try 120 { 121 // Test and create tables 122 Connection connection = null; 123 try 124 { 125 connection = ConnectionHelper.getConnection(_dataSourceId); 126 127 String scriptFolder = ConnectionHelper.getDatabaseType(connection); 128 129 for (InitScript initScript : _scripts) 130 { 131 SQLScriptHelper.createTableIfNotExists(connection, initScript._testTable, "plugin:" + initScript._pluginName + "://scripts/" + scriptFolder + "/" + initScript._fileName, _sourceResolver); 132 } 133 } 134 finally 135 { 136 ConnectionHelper.cleanup(connection); 137 } 138 } 139 catch (Exception e) 140 { 141 String errorMsg = String.format("Error during SQL tables initialization for data source id: '%s'.", StringUtils.defaultString(_dataSourceId)); 142 getLogger().error(errorMsg, e); 143 } 144 } 145 146 private static class InitScript 147 { 148 final String _pluginName; 149 final String _fileName; 150 final String _testTable; 151 152 public InitScript(String pluginNameArg, String fileNameArg, String testTableArg) 153 { 154 _pluginName = pluginNameArg; 155 _fileName = fileNameArg; 156 _testTable = testTableArg; 157 } 158 } 159}