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