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 Map<String, String> table = new HashMap<>(); 164 table.put("id", rs.getString(3)); 165 table.put("datasourceId", sqlDatasourceId); 166 table.put("nodetype", "sqltable"); 167 table.put("text", rs.getString(3)); 168 table.put("iconCls", "ametysicon-tables1"); 169 table.put("leaf", "true"); 170 tables.add(table); 171 } 172 } 173 catch (Exception e) 174 { 175 throw new ProcessingException("Cannot list SQL tables of datasource '" + sqlDatasourceId + "'", e); 176 } 177 finally 178 { 179 ConnectionHelper.cleanup(rs); 180 ConnectionHelper.cleanup(connection); 181 } 182 183 return tables; 184 } 185 186 private Object _ldapDatasource2JSON(String ldapDatasourcePath) throws ProcessingException 187 { 188 List<Map<String, String>> nodes = new ArrayList<>(); 189 190 String ldapDatasourceId = StringUtils.substringBefore(ldapDatasourcePath, ";"); 191 String currentDN = StringUtils.substringAfter(ldapDatasourcePath, ";"); 192 193 for (DN dn : _ldapConnector.getChildren(ldapDatasourceId, currentDN)) 194 { 195 Map<String, String> node = new HashMap<>(); 196 node.put("id", ldapDatasourceId + ";" + dn.getDN() + (StringUtils.isEmpty(currentDN) ? "" : "," + currentDN)); 197 node.put("datasourceId", ldapDatasourceId); 198 node.put("nodetype", "ldapnode"); 199 node.put("text", dn.getLabel()); 200 node.put("iconCls", "ametysicon-menu"); 201 node.put("leaf", dn.hasChild() ? "false" : "true"); 202 nodes.add(node); 203 } 204 205 return nodes; 206 } 207}