From 0bfb9ce7f7f52a1a581e7876cda1c2288a6dab39 Mon Sep 17 00:00:00 2001
From: Glenn Van Lint <glenn.vanlint@is4u.be>
Date: Tue, 07 May 2013 08:55:20 +0000
Subject: [PATCH] Added search functionality.
---
opendj-sdk/opendj3/opendj-virtual/src/main/java/org/forgerock/opendj/virtual/JDBCConnection.java | 261 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 257 insertions(+), 4 deletions(-)
diff --git a/opendj-sdk/opendj3/opendj-virtual/src/main/java/org/forgerock/opendj/virtual/JDBCConnection.java b/opendj-sdk/opendj3/opendj-virtual/src/main/java/org/forgerock/opendj/virtual/JDBCConnection.java
index 0af1d04..8da548c 100644
--- a/opendj-sdk/opendj3/opendj-virtual/src/main/java/org/forgerock/opendj/virtual/JDBCConnection.java
+++ b/opendj-sdk/opendj3/opendj-virtual/src/main/java/org/forgerock/opendj/virtual/JDBCConnection.java
@@ -24,6 +24,7 @@
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
@@ -220,7 +221,7 @@
final String compareAttributeName = request.getAttributeDescription().toString();
final String compareAttributeValue = request.getAssertionValueAsString();
final String compareColumnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, compareAttributeName);
-
+
final Statement st = connection.createStatement();
final String sql = "SELECT * FROM " + tableName + " WHERE " + columnName + "='" + filterAttributeValue + "' AND " + compareColumnName + "='" + compareAttributeValue + "'";
final ResultSet rs = st.executeQuery(sql);
@@ -366,13 +367,265 @@
{
// TODO Auto-generated method stub
}
-
+
+ private String convertSearchFilter(final Filter filter, final String baseDN){
+ String filterString = filter.toString();
+ int stringIndex = 0;
+ int subStringCount = 0;
+
+ while(filterString.charAt(stringIndex) == '('){
+ if(filterString.charAt(stringIndex + 2) == '('){
+ subStringCount++;
+ }
+ stringIndex += 2;
+ }
+ int subStringStartIndex = 2 * subStringCount;
+ int subStringEndIndex = 0;
+ final String[] subStrings = new String[subStringCount];
+ final char[] operationChars = new char[subStringCount];
+
+ while(subStringStartIndex > 0){
+ final char operationChar = filterString.charAt(subStringStartIndex - 1);
+ subStringEndIndex = filterString.indexOf("))") + 1;
+ String subString = filterString.substring(subStringStartIndex, subStringEndIndex);
+ subString = subString.replace("()","");
+
+ operationChars[subStringCount - subStringStartIndex / 2] = operationChar;
+ subStrings[subStringCount - subStringStartIndex / 2] = subString;
+
+ final String replaceString = filterString.substring(subStringStartIndex - 1, subStringEndIndex);
+ filterString = filterString.replace(replaceString, "");
+
+ subStringStartIndex-=2;
+ }
+ String convertedFilterString = "";
+
+ for(int i = 0; i < subStringCount; i++){
+ final char operationChar = operationChars[i];
+ if(operationChar == '!'){
+ String subString = subStrings[i];
+ if(subString.isEmpty()){
+ subString = subStrings[i-1];
+ subString = subString.replace(">=", ">");
+ subString = subString.replace("<=", "<");
+ subString = subString.replace("=", "!=");
+ subString = subString.replace(">", ">=");
+ subString = subString.replace("<", "<=");
+ subStrings[i-1] = subString;
+ }
+ else{
+ subString = subString.replace(">=", ">");
+ subString = subString.replace("<=", "<");
+ subString = subString.replace("=", "!=");
+ subString = subString.replace(">", ">=");
+ subString = subString.replace("<", "<=");
+ subStrings[i] = subString;
+ }
+ }
+ }
+ boolean multipleSubStrings = false;
+ if(subStringCount > 1) multipleSubStrings = true;
+
+ for(int i = 0; i < subStringCount; i++){
+ final char operationChar = operationChars[i];
+ String operationString = "";
+
+ if(operationChar == '&'){
+ operationString = " AND ";
+ }
+ else if (operationChar == '|'){
+ operationString = " OR ";
+ }
+
+ String subString = subStrings[i];
+ if (subString.isEmpty()) continue;
+
+ subString = subString.substring(1, subString.length() - 1);
+ String[] subStringSplitter = subString.split("\\)\\(");
+
+ for(int j = 0; j < subStringSplitter.length; j++){
+ String subStringFilter = subStringSplitter[j];
+ final String[] subStringFilterSplitter;
+
+ subStringFilter = subStringFilter.replace("\\02a", "*");
+ subStringFilter = subStringFilter.replace("\\028", "(");
+ subStringFilter = subStringFilter.replace("\\029", ")");
+
+ if(subStringFilter.contains("!=")) subStringFilterSplitter = subStringFilter.split("!=");
+ else if(subStringFilter.contains("<=")) subStringFilterSplitter = subStringFilter.split("<=");
+ else if(subStringFilter.contains(">=")) subStringFilterSplitter = subStringFilter.split(">=");
+ else subStringFilterSplitter = subStringFilter.split("=");
+
+ final String filterAttributeName = subStringFilterSplitter[0];
+ String filterColumnName = null;;
+ Object columnDataType = null;
+ final List<String> OUList = jdbcm.getOrganizationalUnits(baseDN);
+
+ for(Iterator<String> iter = OUList.iterator(); iter.hasNext();){
+ final String OUName = iter.next();
+ final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName);
+ filterColumnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, filterAttributeName);
+
+ if(filterColumnName == null) continue;
+ else columnDataType = jdbcm.getTableColumnDataType(tableName, filterColumnName);
+ break;
+ }
+
+ if(columnDataType != Integer.class){
+ String filterAttributeValue = subStringFilterSplitter[1];
+ String filterColumnValue = "'" + filterAttributeValue + "'";
+ filterAttributeValue = filterAttributeValue.replace("*", "\\*");
+ filterAttributeValue = filterAttributeValue.replace("(", "\\(");
+ filterAttributeValue = filterAttributeValue.replace(")", "\\)");
+
+ if(filterColumnValue.length() > 3 && filterColumnValue.contains("*")){
+ filterColumnValue = filterColumnValue.replace("*", "%");
+
+ if(subStringFilter.contains("!=")) subStringFilter = subStringFilter.replace("!=", " not like ");
+ else subStringFilter = subStringFilter.replace("=", " like ");
+ }
+ subStringFilter = subStringFilter.replaceFirst(filterAttributeValue, filterColumnValue);
+ }
+
+ if(filterColumnName == null) continue;
+ subStringFilter = subStringFilter.replaceFirst(filterAttributeName, filterColumnName);
+
+ if(j != 0 || i != 0) convertedFilterString = convertedFilterString.concat(operationString);
+ convertedFilterString = convertedFilterString.concat(subStringFilter);
+ }
+ if(multipleSubStrings && i < subStringCount -1) convertedFilterString = "(" + convertedFilterString + ")";
+ }
+ return convertedFilterString;
+ }
@Override
public Result search(SearchRequest request, SearchResultHandler handler) throws ErrorResultException
{
- // TODO Auto-generated method stub
- return null;
+ Result r;
+ try{
+ final DN DN = request.getName();
+ final int DNSize = DN.size();
+ final String baseDN = DN.parent(DNSize - 2).toString();
+ RDN OU = null;
+ RDN rDN = null;
+ String OUName = "";
+ String rDNAttributeName = "";
+ String rDNAttributeValue = "";
+
+ if(DNSize > 3){
+ OU = DN.parent(1).rdn();
+ OUName = OU.getFirstAVA().getAttributeValue().toString();
+ rDN = DN.parent(0).rdn();
+ rDNAttributeName = rDN.getFirstAVA().getAttributeType().getNameOrOID();
+ rDNAttributeValue = rDN.getFirstAVA().getAttributeValue().toString();
+ }
+ else if(DNSize > 2){
+ OU = DN.parent(0).rdn();
+ OUName = OU.getFirstAVA().getAttributeValue().toString();
+ }
+
+
+ final List<String> returnAttributeNames = request.getAttributes();
+ final List<String> returnColumnNames = new ArrayList<String>();
+
+ final Filter searchFilter = request.getFilter();
+ final String convertedFilterString = convertSearchFilter(searchFilter, baseDN);
+
+ if(returnAttributeNames != null){
+
+ for(Iterator<String> iter = returnAttributeNames.iterator();iter.hasNext();){
+
+ if(OU == null){
+ final String returnAttributeName = iter.next();
+ final List<String> OUList = jdbcm.getOrganizationalUnits(baseDN);
+
+ for(Iterator<String> iterOU = OUList.iterator(); iterOU.hasNext();){
+ OUName = iterOU.next();
+ final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName);
+ final String returnColumnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, returnAttributeName);
+
+ if(returnColumnName == null) continue;
+ else returnColumnNames.add(returnColumnName);
+ break;
+ }
+ }
+ else {
+ final String returnAttributeName = iter.next();
+ final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName);
+ final String returnColumnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, returnAttributeName);
+ returnColumnNames.add(returnColumnName);
+ }
+ }
+ }
+ String selectString = "";
+ String fromString = "";
+ String whereString = convertedFilterString;
+
+ if(returnColumnNames.isEmpty()) selectString = "*";
+
+ if(OU == null){
+ final List<String> OUList = jdbcm.getOrganizationalUnits(baseDN);
+
+ for(int i = 0; i < OUList.size(); i++){
+ final String currentOU = OUList.get(i);
+ final String currentTable = jdbcm.getTableNameFromMapping(baseDN, currentOU);
+
+ if(currentTable == null) continue;
+ final List<String> currentTableColumnNames = jdbcm.getTableColumns(currentTable);
+
+ if(i > 0) fromString = fromString.concat(",");
+ fromString = fromString.concat(currentTable);
+
+ for(int j = 0; j < returnColumnNames.size(); j++){
+ final String returnColumnName = returnColumnNames.get(j);
+
+ if(currentTableColumnNames.contains(returnColumnName)){
+ if(j > 0) selectString = selectString.concat(",");
+ selectString = selectString.concat(currentTable + "." + returnColumnName);
+ }
+ }
+ }
+ }
+ else{
+ final String selectTable = jdbcm.getTableNameFromMapping(baseDN, OUName);
+ fromString = fromString.concat(selectTable);
+
+ for(int j = 0; j < returnColumnNames.size(); j++){
+ final String returnColumnName = returnColumnNames.get(j);
+
+ if(j > 0) selectString = selectString.concat(",");
+ selectString = selectString.concat(returnColumnName);
+ }
+
+ if(rDN != null){
+ final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName);
+ final String columnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, rDNAttributeName);
+ whereString = columnName + "='" + rDNAttributeValue + "'";
+ }
+ }
+
+ String sql = "SELECT " + selectString + " FROM " + fromString;
+ if(!whereString.isEmpty()) sql = sql.concat(" WHERE " + whereString);
+
+ final Statement st = connection.createStatement();
+ ResultSet rs = st.executeQuery(sql);
+ ResultSetMetaData rsmd = rs.getMetaData();
+
+ while (rs.next()) {
+ System.out.println("# Row: " +rs.getRow());
+
+ for(int i = 1; i <= rsmd.getColumnCount(); i++){
+ System.out.println(rsmd.getTableName(i) + ":" + rsmd.getColumnName(i) + " = " + rs.getObject(i));
+ }
+ System.out.println();
+ }
+
+ r = Responses.newResult(ResultCode.SUCCESS);
+ }catch (SQLException e){
+ System.out.println(e.toString());
+ r = Responses.newResult(ResultCode.OPERATIONS_ERROR);
+ }
+ return r;
}
@Override
--
Gitblit v1.10.0