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