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.datasourcesexplorer; 017 018import java.sql.Connection; 019import java.sql.DatabaseMetaData; 020import java.sql.ResultSet; 021import java.util.ArrayList; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.avalon.framework.parameters.Parameters; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.cocoon.ProcessingException; 030import org.apache.cocoon.acting.ServiceableAction; 031import org.apache.cocoon.environment.ObjectModelHelper; 032import org.apache.cocoon.environment.Redirector; 033import org.apache.cocoon.environment.Request; 034import org.apache.cocoon.environment.SourceResolver; 035import org.apache.commons.lang3.StringUtils; 036 037import org.ametys.core.cocoon.JSonReader; 038import org.ametys.core.datasource.AbstractDataSourceManager.DataSourceDefinition; 039import org.ametys.core.datasource.ConnectionHelper; 040import org.ametys.core.datasource.DataSourceConsumerExtensionPoint; 041import org.ametys.core.datasource.LDAPDataSourceManager; 042import org.ametys.core.datasource.SQLDataSourceManager; 043import org.ametys.plugins.datasourcesexplorer.LDAPConnector.DN; 044 045/** 046 * Generates the list of tables on the given datasource id 047 */ 048public class GetDatasources extends ServiceableAction 049{ 050 private SQLDataSourceManager _sqlDataSourceManager; 051 private LDAPDataSourceManager _ldapDataSourceManager; 052 private DataSourceConsumerExtensionPoint _dataSourceConsumerEP; 053 private LDAPConnector _ldapConnector; 054 055 @Override 056 public void service(ServiceManager smanager) throws ServiceException 057 { 058 super.service(smanager); 059 060 _sqlDataSourceManager = (SQLDataSourceManager) smanager.lookup(SQLDataSourceManager.ROLE); 061 _ldapDataSourceManager = (LDAPDataSourceManager) smanager.lookup(LDAPDataSourceManager.ROLE); 062 _ldapConnector = (LDAPConnector) smanager.lookup(LDAPConnector.ROLE); 063 _dataSourceConsumerEP = (DataSourceConsumerExtensionPoint) smanager.lookup(DataSourceConsumerExtensionPoint.ROLE); 064 } 065 066 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 067 { 068 Map<String, Object> results = new HashMap<>(); 069 070 Request request = ObjectModelHelper.getRequest(objectModel); 071 request.setAttribute(JSonReader.OBJECT_TO_READ, results); 072 073 String id = request.getParameter("node"); 074 if (StringUtils.isBlank(id)) 075 { 076 id = "root"; 077 } 078 079 Object children; 080 if ("root".equals(id)) 081 { 082 children = _datasources2JSON(); 083 } 084 else if (id.startsWith(SQLDataSourceManager.SQL_DATASOURCE_PREFIX)) 085 { 086 children = _sqlDatasource2JSON(id); 087 } 088 else 089 { 090 children = _ldapDatasource2JSON(id); 091 } 092 093 results.put("id", id); 094 results.put("children", children); 095 096 return EMPTY_MAP; 097 } 098 099 private Object _datasources2JSON() 100 { 101 List<Map<String, Object>> datasources = new ArrayList<>(); 102 103 for (DataSourceDefinition dataSourceDefinition : _sqlDataSourceManager.getDataSourceDefinitions(true, true, false).values()) 104 { 105 Map<String, Object> datasource = new HashMap<>(); 106 datasources.add(datasource); 107 108 boolean isInUse = _dataSourceConsumerEP.isInUse(dataSourceDefinition.getId()) || (dataSourceDefinition.isDefault() && _dataSourceConsumerEP.isInUse(_sqlDataSourceManager.getDefaultDataSourceId())); 109 110 datasource.put("id", dataSourceDefinition.getId()); 111 datasource.put("nodetype", "datasource"); 112 datasource.put("type", "SQL"); 113 datasource.put("isDefault", dataSourceDefinition.isDefault()); 114 datasource.put("isInUse", isInUse); 115 datasource.put("text", dataSourceDefinition.getName()); 116 datasource.put("description", dataSourceDefinition.getDescription()); 117 datasource.put("iconCls", "ametysicon-data110"); 118 datasource.put("leaf", "false"); 119 } 120 121 for (DataSourceDefinition dataSourceDefinition : _ldapDataSourceManager.getDataSourceDefinitions(true, true, false).values()) 122 { 123 Map<String, Object> datasource = new HashMap<>(); 124 datasources.add(datasource); 125 126 boolean isInUse = _dataSourceConsumerEP.isInUse(dataSourceDefinition.getId()) || (dataSourceDefinition.isDefault() && _dataSourceConsumerEP.isInUse(_sqlDataSourceManager.getDefaultDataSourceId())); 127 128 datasource.put("id", dataSourceDefinition.getId()); 129 datasource.put("nodetype", "datasource"); 130 datasource.put("type", "LDAP"); 131 datasource.put("isDefault", dataSourceDefinition.isDefault()); 132 datasource.put("isInUse", isInUse); 133 datasource.put("text", dataSourceDefinition.getName()); 134 datasource.put("description", dataSourceDefinition.getDescription()); 135 datasource.put("iconCls", "ametysicon-agenda3"); 136 datasource.put("leaf", "false"); 137 } 138 139 return datasources; 140 } 141 142 private Object _sqlDatasource2JSON(String sqlDatasourceId) throws ProcessingException 143 { 144 List<Map<String, String>> tables = new ArrayList<>(); 145 146 Connection connection = null; 147 ResultSet rs = null; 148 try 149 { 150 connection = ConnectionHelper.getConnection(sqlDatasourceId); 151 152 String databaseType = ConnectionHelper.getDatabaseType(connection); 153 if (databaseType == null) 154 { 155 throw new IllegalArgumentException("The datasource '" + sqlDatasourceId + "' does not exist"); 156 } 157 158 DatabaseMetaData md = connection.getMetaData(); 159 rs = md.getTables(null, null, "%", null); 160 while (rs.next()) 161 { 162 Map<String, String> table = new HashMap<>(); 163 table.put("id", rs.getString(3)); 164 table.put("datasourceId", sqlDatasourceId); 165 table.put("nodetype", "sqltable"); 166 table.put("text", rs.getString(3)); 167 table.put("iconCls", "ametysicon-tables1"); 168 table.put("leaf", "true"); 169 tables.add(table); 170 } 171 } 172 catch (Exception e) 173 { 174 throw new ProcessingException("Cannot list SQL tables of datasource '" + sqlDatasourceId + "'", e); 175 } 176 finally 177 { 178 ConnectionHelper.cleanup(rs); 179 ConnectionHelper.cleanup(connection); 180 } 181 182 return tables; 183 } 184 185 private Object _ldapDatasource2JSON(String ldapDatasourcePath) throws ProcessingException 186 { 187 List<Map<String, String>> nodes = new ArrayList<>(); 188 189 String ldapDatasourceId = StringUtils.substringBefore(ldapDatasourcePath, ";"); 190 String currentDN = StringUtils.substringAfter(ldapDatasourcePath, ";"); 191 192 for (DN dn : _ldapConnector.getChildren(ldapDatasourceId, currentDN)) 193 { 194 Map<String, String> node = new HashMap<>(); 195 node.put("id", ldapDatasourceId + ";" + dn.getDN() + (StringUtils.isEmpty(currentDN) ? "" : "," + currentDN)); 196 node.put("datasourceId", ldapDatasourceId); 197 node.put("nodetype", "ldapnode"); 198 node.put("text", dn.getLabel()); 199 node.put("iconCls", "ametysicon-menu"); 200 node.put("leaf", dn.hasChild() ? "false" : "true"); 201 nodes.add(node); 202 } 203 204 return nodes; 205 } 206}