Skip to content

Commit

Permalink
feat: merge ORM from Gluu (#2468)
Browse files Browse the repository at this point in the history
  • Loading branch information
yurem authored Oct 6, 2022
1 parent d60c27c commit 93149fd
Show file tree
Hide file tree
Showing 14 changed files with 293 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.orm.couchbase;

import java.util.List;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.jans.orm.couchbase.impl.CouchbaseEntryManager;
import io.jans.orm.couchbase.operation.impl.CouchbaseConnectionProvider;
import io.jans.orm.model.base.SimpleUser;
import io.jans.orm.search.filter.Filter;

/**
* @author Yuriy Movchan Date: 11/03/2022
*/
public final class CouchbaseScimSubstringSearchSample {

private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConnectionProvider.class);

private CouchbaseScimSubstringSearchSample() {
}

public static void main(String[] args) {
// Prepare sample connection details
CouchbaseEntryManagerSample couchbaseEntryManagerSample = new CouchbaseEntryManagerSample();

// Create Couchbase entry manager
CouchbaseEntryManager couchbaseEntryManager = couchbaseEntryManagerSample.createCouchbaseEntryManager();
Filter filter = Filter.createORFilter(Filter.createORFilter(Filter.createSubstringFilter("oxTrustPhoneValue", null, new String[] {"\"type\":null"}, null).multiValued(), Filter.createSubstringFilter("oxTrustPhoneValue", null, new String[] {"\"value\":\"", "+", "\""}, null).multiValued()),
Filter.createSubstringFilter("mail", null, null, "jans.io"));
System.out.println(filter);

List<SimpleUser> users = couchbaseEntryManager.findEntries("ou=people,o=jans", SimpleUser.class, filter);
for (SimpleUser user : users) {
LOG.info("User with uid: '{}' with DN: '{}'", user.getUserId(), user.getDn());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ public ConvertedExpression convertToCouchbaseFilter(Filter genericFilter, Map<St

StringBuilder like = new StringBuilder();
if (currentGenericFilter.getSubInitial() != null) {
String variableExpressionInitial = buildVariableExpression(internalAttribute + "_i", multiValued, currentGenericFilter.getSubInitial(), queryParameters);
String subInital = currentGenericFilter.getSubInitial() + "%";
String variableExpressionInitial = buildVariableExpression(internalAttribute + "_i", multiValued, subInital, queryParameters);
filterParameters.add(variableExpressionInitial);
like.append("$" + variableExpressionInitial);
}
Expand All @@ -255,7 +256,8 @@ public ConvertedExpression convertToCouchbaseFilter(Filter genericFilter, Map<St
}

if (currentGenericFilter.getSubFinal() != null) {
String variableExpressionFinal = buildVariableExpression(internalAttribute + "_f", multiValued, currentGenericFilter.getSubFinal(), queryParameters);
String subFinal = "%" + currentGenericFilter.getSubFinal();
String variableExpressionFinal = buildVariableExpression(internalAttribute + "_f", multiValued, subFinal, queryParameters);
filterParameters.add(variableExpressionFinal);
like.append("$" + variableExpressionFinal);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* oxCore is available under the MIT License (2014). See http://opensource.org/licenses/MIT for full text.
*
* Copyright (c) 2020, Gluu
*/

package SqlScimSubstringSearchSample;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.jans.orm.model.base.SimpleUser;
import io.jans.orm.search.filter.Filter;
import io.jans.orm.sql.impl.SqlEntryManager;
import io.jans.orm.sql.persistence.SqlEntryManagerSample;

/**
* @author Yuriy Movchan Date: 11/03/2016
*/
public final class SqlScimSubstringSearchSample {

private static final Logger LOG = LoggerFactory.getLogger(SqlScimSubstringSearchSample.class);

private SqlScimSubstringSearchSample() {
}

public static void main(String[] args) {
// Prepare sample connection details
SqlEntryManagerSample sqlEntryManagerSample = new SqlEntryManagerSample();

// Create Couchbase entry manager
SqlEntryManager sqlEntryManager = sqlEntryManagerSample.createSqlEntryManager();
Filter filter = Filter.createORFilter(Filter.createORFilter(Filter.createSubstringFilter("oxTrustPhoneValue", null, new String[] {"\"type\":null"}, null).multiValued(), Filter.createSubstringFilter("oxTrustPhoneValue", null, new String[] {"\"value\":\"", "+", "\""}, null).multiValued()),
Filter.createSubstringFilter("mail", null, null, "gluu.org"));
System.out.println(filter);

List<SimpleUser> users = sqlEntryManager.findEntries("ou=people,o=gluu", SimpleUser.class, filter);
for (SimpleUser user : users) {
LOG.info("User with uid: '{}' with DN: '{}'", user.getUserId(), user.getDn());
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* oxCore is available under the MIT License (2014). See http://opensource.org/licenses/MIT for full text.
*
* Copyright (c) 2014, Gluu
*/

package io.jans.orm.sql;

import java.util.List;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.jans.orm.search.filter.Filter;
import io.jans.orm.sql.impl.SqlEntryManager;
import io.jans.orm.sql.model.SimpleUser;
import io.jans.orm.sql.operation.impl.SqlConnectionProvider;
import io.jans.orm.sql.persistence.SqlEntryManagerSample;

/**
* @author Yuriy Movchan Date: 01/15/2020
*/
public final class SqlScimUserSearchSample {

private static final Logger LOG = LoggerFactory.getLogger(SqlConnectionProvider.class);

private SqlScimUserSearchSample() {
}

public static void main(String[] args) throws InterruptedException {
// Prepare sample connection details
final SqlEntryManagerSample sqlEntryManagerSample = new SqlEntryManagerSample();
final SqlEntryManager sqlEntryManager = sqlEntryManagerSample.createSqlEntryManager();

Filter filter0 = Filter.createEqualityFilter(Filter.createLowercaseFilter("uid"),"test-0.8372945581513689");
System.out.println(filter0);
List<SimpleUser> users0 = sqlEntryManager.findEntries("ou=people,o=jans", SimpleUser.class, filter0);
System.out.println(users0);

Filter filter1 = Filter.createORFilter(Filter.createSubstringFilter("oxTrustImsValue",null, new String[] {"\"value\":\"Skype\""}, null).multiValued(),
Filter.createEqualityFilter("nickname", null), Filter.createSubstringFilter("nickname",null, new String[] {}, null));
System.out.println(filter1);
List<SimpleUser> users = sqlEntryManager.findEntries("ou=people,o=jans", SimpleUser.class, filter1);
System.out.println(users);

Filter filter2 = Filter.createGreaterOrEqualFilter("oxCreationTimestamp","2022-09-23T09:01:28.637");
System.out.println(filter2);
List<SimpleUser> users2 = sqlEntryManager.findEntries("ou=people,o=gluu", SimpleUser.class, filter2);
System.out.println(users2);
}

}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.orm.sql.dsl.template;

import com.querydsl.sql.MySQLTemplates;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package io.jans.orm.sql.dsl.template;
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.orm.sql.dsl.template;

import com.querydsl.sql.PostgreSQLTemplates;
import com.querydsl.sql.SQLTemplates;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.orm.sql.dsl.types;

import java.sql.PreparedStatement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,22 @@ protected <T> PagedResult<EntryData> findEntriesImpl(String baseDN, Class<T> ent
} catch (SearchException ex) {
throw new EntryPersistenceException(String.format("Failed to find entries with key: '%s'", key), ex);
} catch (Exception ex) {
throw new EntryPersistenceException(String.format("Failed to find entries with key: '%s', expression: '%s'", key, convertedExpression), ex);
throw new EntryPersistenceException(String.format("Failed to find entries with key: '%s', expression: '%s'", key, toExpressionForException(convertedExpression, searchFilter)), ex);
}
}

private String toExpressionForException(ConvertedExpression convertedExpression, Filter searchFilter) {
String result = searchFilter.toString();
try {
result = convertedExpression.toString();
} catch (Exception ex) {
// QueryDSL can't convert filter
LOG.error(String.format("QueryDSL can't build query based on filter: '%s'", result));
}

return result;
}

@Override
protected <T> boolean contains(String baseDN, String[] objectClasses, Class<T> entryClass, List<PropertyAnnotation> propertiesAnnotations, Filter filter, String[] ldapReturnAttributes) {
if (StringHelper.isEmptyString(baseDN)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import io.jans.orm.sql.operation.SupportedDbType;
import io.jans.orm.util.ArrayHelper;
import io.jans.orm.util.StringHelper;
import org.apache.commons.text.StringEscapeUtils;

/**
* Filter to SQL query convert
Expand All @@ -63,6 +64,8 @@ public class SqlFilterConverter {
private Path<Long> longDocAlias = ExpressionUtils.path(Long.class, "doc");
private Path<Date> dateDocAlias = ExpressionUtils.path(Date.class, "doc");
private Path<Object> objectDocAlias = ExpressionUtils.path(Object.class, "doc");

public static String[] SPECIAL_REGEX_CHARACTERS = new String[] { "\\", "/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}" };


public SqlFilterConverter(SqlOperationService operationService) {
Expand Down Expand Up @@ -177,7 +180,7 @@ private ConvertedExpression convertToSqlFilterImpl(TableMapping tableMapping, Fi
}
}

boolean multiValued = isMultiValue(currentGenericFilter, propertiesAnnotationsMap);
boolean multiValued = isMultiValue(tableMapping, currentGenericFilter, propertiesAnnotationsMap);
Expression columnExpression = buildTypedPath(tableMapping, currentGenericFilter, propertiesAnnotationsMap, jsonAttributes, processor, skipAlias);

if (FilterType.EQUALITY == type) {
Expand All @@ -201,7 +204,7 @@ private ConvertedExpression convertToSqlFilterImpl(TableMapping tableMapping, Fi
if (multiValued) {
if (SupportedDbType.POSTGRESQL == this.dbType) {
return buildPostgreSqlMultivaluedComparisionExpression(tableMapping, jsonAttributes,
currentGenericFilter, type, columnExpression);
currentGenericFilter, columnExpression);
} else {
if (currentGenericFilter.getMultiValuedCount() > 1) {
Collection<Predicate> expressions = new ArrayList<>(currentGenericFilter.getMultiValuedCount());
Expand Down Expand Up @@ -233,7 +236,7 @@ private ConvertedExpression convertToSqlFilterImpl(TableMapping tableMapping, Fi
if (multiValued) {
if (SupportedDbType.POSTGRESQL == this.dbType) {
return buildPostgreSqlMultivaluedComparisionExpression(tableMapping, jsonAttributes,
currentGenericFilter, type, columnExpression);
currentGenericFilter, columnExpression);
} else {
if (currentGenericFilter.getMultiValuedCount() > 1) {
Collection<Predicate> expressions = new ArrayList<>(currentGenericFilter.getMultiValuedCount());
Expand Down Expand Up @@ -295,17 +298,26 @@ private ConvertedExpression convertToSqlFilterImpl(TableMapping tableMapping, Fi
}

if (FilterType.SUBSTRING == type) {
String matchChar = multiValued && (SupportedDbType.POSTGRESQL == this.dbType) ? ".*" : "%";
StringBuilder like = new StringBuilder();
if (currentGenericFilter.getSubInitial() != null) {
like.append(currentGenericFilter.getSubInitial());
}
like.append("%");
like.append(matchChar);

String[] subAny = currentGenericFilter.getSubAny();
if ((subAny != null) && (subAny.length > 0)) {
for (String any : subAny) {
like.append(any);
like.append("%");
if (SupportedDbType.POSTGRESQL == this.dbType) {
if (multiValued) {
like.append(escapeRegex(any));
} else {
like.append(any);
}
} else {
like.append(any);
}
like.append(matchChar);
}
}

Expand All @@ -316,8 +328,10 @@ private ConvertedExpression convertToSqlFilterImpl(TableMapping tableMapping, Fi
Expression expression;
if (multiValued) {
if (SupportedDbType.POSTGRESQL == this.dbType) {
String likeString = "\"" + StringEscapeUtils.escapeJava(like.toString()) + "\"";
return buildPostgreSqlMultivaluedComparisionExpression(tableMapping, jsonAttributes,
currentGenericFilter, type, columnExpression);
currentGenericFilter, columnExpression, Expressions.constant("like_regex"),
likeString);
} else {
if (currentGenericFilter.getMultiValuedCount() > 1) {
Collection<Predicate> expressions = new ArrayList<>(currentGenericFilter.getMultiValuedCount());
Expand Down Expand Up @@ -351,19 +365,41 @@ private ConvertedExpression convertToSqlFilterImpl(TableMapping tableMapping, Fi
}

private ConvertedExpression buildPostgreSqlMultivaluedComparisionExpression(TableMapping tableMapping,
Map<String, Class<?>> jsonAttributes, Filter currentGenericFilter, FilterType type,
Map<String, Class<?>> jsonAttributes, Filter currentGenericFilter,
Expression columnExpression) throws SearchException {
Object typedArrayExpressionValue = prepareTypedArrayExpressionValue(tableMapping, currentGenericFilter);
return buildPostgreSqlMultivaluedComparisionExpression(tableMapping, jsonAttributes, currentGenericFilter, columnExpression,
Expressions.constant(currentGenericFilter.getType().getSign()), typedArrayExpressionValue);
}

private ConvertedExpression buildPostgreSqlMultivaluedComparisionExpression(TableMapping tableMapping,
Map<String, Class<?>> jsonAttributes, Filter currentGenericFilter, Expression columnExpression, Expression operationExpession, Object expressionValue) {
Expression<?> typedArrayExpression = expressionValue == null ? Expressions.nullExpression() : Expressions.constant(expressionValue);

Operation<Boolean> operation = ExpressionUtils.predicate(SqlOps.PGSQL_JSON_NOT_EMPTY_ARRAY,
ExpressionUtils.predicate(SqlOps.PGSQL_JSON_PATH_QUERY_ARRAY,
columnExpression, Expressions.constant(type.getSign()),
Expressions.constant(prepareTypedArrayExpressionValue(tableMapping, currentGenericFilter))));
columnExpression, operationExpession,
typedArrayExpression));
return ConvertedExpression.build(operation, jsonAttributes);
}

protected Boolean isMultiValue(Filter currentGenericFilter, Map<String, PropertyAnnotation> propertiesAnnotationsMap) {
Boolean isMultiValuedDetected = determineMultiValuedByType(currentGenericFilter.getAttributeName(), propertiesAnnotationsMap);
if (Boolean.TRUE.equals(currentGenericFilter.getMultiValued()) || Boolean.TRUE.equals(isMultiValuedDetected)) {
return true;
protected Boolean isMultiValue(TableMapping tableMapping, Filter filter, Map<String, PropertyAnnotation> propertiesAnnotationsMap) throws SearchException {
String attributeName = filter.getAttributeName();
AttributeType attributeType = null;
if (StringHelper.isNotEmpty(attributeName)) {
attributeType = getAttributeType(tableMapping, filter.getAttributeName());
if (attributeType == null) {
if (tableMapping != null) {
throw new SearchException(String.format(String.format("Failed to find attribute type for '%s'", filter.getAttributeName())));
}
}
}

Boolean isMultiValuedDetected = determineMultiValuedByType(filter.getAttributeName(), propertiesAnnotationsMap);
if ((Boolean.TRUE.equals(filter.getMultiValued()) || Boolean.TRUE.equals(isMultiValuedDetected))) {
if ((attributeType != null) && Boolean.TRUE.equals(attributeType.getMultiValued())) {
return true;
}
}

return false;
Expand Down Expand Up @@ -409,7 +445,9 @@ private String toInternalAttribute(String attributeName) {
}

private Expression buildTypedExpression(TableMapping tableMapping, Filter filter) throws SearchException {
return Expressions.constant(prepareTypedExpressionValue(tableMapping, filter));
Object expressionValue = prepareTypedExpressionValue(tableMapping, filter);
Expression<?> expression = expressionValue == null ? Expressions.nullExpression() : Expressions.constant(expressionValue);
return expression;
}

private Expression buildTypedArrayExpression(TableMapping tableMapping, Filter filter) throws SearchException {
Expand Down Expand Up @@ -549,4 +587,13 @@ protected String convertValueToJson(Object propertyValue) throws SearchException
}
}

private Object escapeRegex(String str) {
String result = str;
for (String ch : SPECIAL_REGEX_CHARACTERS) {
result = result.replace(ch, "\\" + ch);
}

return result;
}

}
6 changes: 6 additions & 0 deletions jans-orm/sql/src/main/java/io/jans/orm/sql/impl/SqlOps.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.orm.sql.impl;

import com.querydsl.core.types.Operator;
Expand Down
Loading

0 comments on commit 93149fd

Please sign in to comment.