Skip to content

Commit

Permalink
Oracle should be working now
Browse files Browse the repository at this point in the history
  • Loading branch information
ilgrosso committed Jan 23, 2025
1 parent 640fcea commit d97037c
Show file tree
Hide file tree
Showing 41 changed files with 493 additions and 1,150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
import org.apache.syncope.core.persistence.api.entity.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Schema;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand All @@ -45,11 +42,6 @@ public interface AnyDAO<A extends Any<?>> extends DAO<A> {

A authFind(String key);

List<A> findByPlainAttrValue(PlainSchema schema, PlainAttrValue attrValue, boolean ignoreCaseMatch);

Optional<A> findByPlainAttrUniqueValue(
PlainSchema schema, PlainAttrUniqueValue attrUniqueValue, boolean ignoreCaseMatch);

/**
* Find any objects by derived attribute value. This method could fail if one or more string literals contained
* into the derived attribute value provided derive from identifier (schema key) replacement. When you are going to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ public static SearchCond of(final AbstractSearchCond leaf) {
return cond;
}

public static SearchCond getNotLeaf(final AbstractSearchCond leaf) {
public static SearchCond negate(final AbstractSearchCond leaf) {
SearchCond cond = of(leaf);

cond.type = Type.NOT_LEAF;

return cond;
}

public static SearchCond and(final SearchCond left, final SearchCond right) {
private static SearchCond and(final SearchCond left, final SearchCond right) {
SearchCond cond = new SearchCond();

cond.type = Type.AND;
Expand All @@ -89,10 +89,10 @@ public static SearchCond and(final List<SearchCond> conditions) {
}

public static SearchCond and(final SearchCond... conditions) {
return or(Arrays.asList(conditions));
return and(Arrays.asList(conditions));
}

public static SearchCond or(final SearchCond left, final SearchCond right) {
private static SearchCond or(final SearchCond left, final SearchCond right) {
SearchCond cond = new SearchCond();

cond.type = Type.OR;
Expand Down Expand Up @@ -135,11 +135,12 @@ public String hasAnyTypeCond() {
switch (type) {
case LEAF:
case NOT_LEAF:
if (leaf instanceof AnyTypeCond) {
anyTypeName = ((AnyTypeCond) leaf).getAnyTypeKey();
if (leaf instanceof AnyTypeCond anyTypeCond) {
anyTypeName = anyTypeCond.getAnyTypeKey();
}
break;


case AND:
case OR:
if (left != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ protected SearchCond visitPrimitive(final SearchCondition<SearchBean> sc) {
if (notEquals.isPresent() && notEquals.get().getType() == AttrCond.Type.ISNULL) {
notEquals.get().setType(AttrCond.Type.ISNOTNULL);
} else {
leaf = SearchCond.getNotLeaf(leaf);
leaf = SearchCond.negate(leaf);
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void nieq() {
AnyCond anyCond = new AnyCond(AttrCond.Type.IEQ);
anyCond.setSchema("username");
anyCond.setExpression("rossini");
SearchCond leaf = SearchCond.getNotLeaf(anyCond);
SearchCond leaf = SearchCond.negate(anyCond);

assertEquals(leaf, SearchCondConverter.convert(VISITOR, fiql));
}
Expand Down Expand Up @@ -117,7 +117,7 @@ public void nilike() {
AttrCond attrCond = new AnyCond(AttrCond.Type.ILIKE);
attrCond.setSchema("username");
attrCond.setExpression("ros%");
SearchCond leaf = SearchCond.getNotLeaf(attrCond);
SearchCond leaf = SearchCond.negate(attrCond);

assertEquals(leaf, SearchCondConverter.convert(VISITOR, fiql));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.core.persistence.common.dao;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.commons.jexl3.parser.Parser;
import org.apache.commons.jexl3.parser.ParserConstants;
import org.apache.commons.jexl3.parser.Token;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.search.AttrCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

public class AnyFinder {

protected static final Logger LOG = LoggerFactory.getLogger(AnyFinder.class);

protected static final Comparator<String> LITERAL_COMPARATOR = (l1, l2) -> {
if (l1 == null && l2 == null) {
return 0;
} else if (l1 != null && l2 == null) {
return -1;
} else if (l1 == null) {
return 1;
} else if (l1.length() == l2.length()) {
return 0;
} else if (l1.length() > l2.length()) {
return -1;
} else {
return 1;
}
};

/**
* Split an attribute value recurring on provided literals/tokens.
*
* @param attrValue value to be split
* @param literals literals/tokens
* @return split value
*/
protected static List<String> split(final String attrValue, final List<String> literals) {
final List<String> attrValues = new ArrayList<>();

if (literals.isEmpty()) {
attrValues.add(attrValue);
} else {
for (String token : attrValue.split(Pattern.quote(literals.get(0)))) {
if (!token.isEmpty()) {
attrValues.addAll(split(token, literals.subList(1, literals.size())));
}
}
}

return attrValues;
}

protected final PlainSchemaDAO plainSchemaDAO;

protected final AnySearchDAO anySearchDAO;

public AnyFinder(final PlainSchemaDAO plainSchemaDAO, final AnySearchDAO anySearchDAO) {
this.plainSchemaDAO = plainSchemaDAO;
this.anySearchDAO = anySearchDAO;
}

@Transactional(readOnly = true)
public <A extends Any<?>> Optional<A> findByPlainAttrUniqueValue(
final AnyTypeKind anyTypeKind,
final PlainSchema schema,
final PlainAttrUniqueValue attrUniqueValue) {

AttrCond cond = new AttrCond(AttrCond.Type.EQ);
cond.setSchema(schema.getKey());
cond.setExpression(attrUniqueValue.getStringValue());

List<A> result = anySearchDAO.search(SearchCond.of(cond), anyTypeKind);
if (result.isEmpty()) {
return Optional.empty();
}
return Optional.of(result.get(0));
}

@Transactional(readOnly = true)
public <A extends Any<?>> List<A> findByDerAttrValue(
final AnyTypeKind anyTypeKind,
final DerSchema derSchema,
final String value,
final boolean ignoreCaseMatch) {

if (derSchema == null) {
LOG.error("No DerSchema");
return List.of();
}

Parser parser = new Parser(derSchema.getExpression());

// Schema keys
List<String> identifiers = new ArrayList<>();

// Literals
List<String> literals = new ArrayList<>();

// Get schema keys and literals
for (Token token = parser.getNextToken(); token != null && StringUtils.isNotBlank(token.toString());
token = parser.getNextToken()) {

if (token.kind == ParserConstants.STRING_LITERAL) {
literals.add(token.toString().substring(1, token.toString().length() - 1));
}

if (token.kind == ParserConstants.IDENTIFIER) {
identifiers.add(token.toString());
}
}

// Sort literals in order to process later literals included into others
literals.sort(LITERAL_COMPARATOR);

// Split value on provided literals
List<String> attrValues = split(value, literals);

if (attrValues.size() != identifiers.size()) {
LOG.error("Ambiguous JEXL expression resolution: literals and values have different size");
return List.of();
}

List<SearchCond> andConditions = new ArrayList<>();

// Contains used identifiers in order to avoid replications
Set<String> used = new HashSet<>();

// Create several clauses: one for eanch identifiers
for (int i = 0; i < identifiers.size() && !used.contains(identifiers.get(i)); i++) {
// verify schema existence and get schema type
PlainSchema schema = plainSchemaDAO.findById(identifiers.get(i)).orElse(null);

if (schema == null) {
LOG.error("Invalid schema '{}', ignoring", identifiers.get(i));
} else {
used.add(identifiers.get(i));

AttrCond cond = new AttrCond(ignoreCaseMatch ? AttrCond.Type.IEQ : AttrCond.Type.EQ);
cond.setSchema(schema.getKey());
cond.setExpression(attrValues.get(i));
andConditions.add(SearchCond.of(cond));
}
}

LOG.debug("Generated search {} conditions: {}", anyTypeKind, andConditions);

return anySearchDAO.search(SearchCond.and(andConditions), anyTypeKind);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.jpa.dao.AnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.MariaDBAnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.MariaDBJPAAnySearchDAO;
import org.apache.syncope.core.persistence.jpa.dao.repo.MariaDBPlainSchemaRepoExtImpl;
import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt;
Expand All @@ -53,12 +51,6 @@ public EntityFactory entityFactory() {
return new MariaDBEntityFactory();
}

@ConditionalOnMissingBean
@Bean
public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) {
return new MariaDBAnyFinder(plainSchemaDAO, entityManager);
}

@ConditionalOnMissingBean
@Bean
public AnySearchDAO anySearchDAO(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.jpa.dao.AnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.MySQLAnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.MySQLJPAAnySearchDAO;
import org.apache.syncope.core.persistence.jpa.dao.repo.MySQLPlainSchemaRepoExtImpl;
import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt;
Expand All @@ -53,12 +51,6 @@ public EntityFactory entityFactory() {
return new MySQLEntityFactory();
}

@ConditionalOnMissingBean
@Bean
public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) {
return new MySQLAnyFinder(plainSchemaDAO, entityManager);
}

@ConditionalOnMissingBean
@Bean
public AnySearchDAO anySearchDAO(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.jpa.dao.AnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.OracleAnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.OracleJPAAnySearchDAO;
import org.apache.syncope.core.persistence.jpa.dao.repo.OraclePlainSchemaRepoExtImpl;
import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt;
Expand All @@ -53,12 +51,6 @@ public EntityFactory entityFactory() {
return new OracleEntityFactory();
}

@ConditionalOnMissingBean
@Bean
public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) {
return new OracleAnyFinder(plainSchemaDAO, entityManager);
}

@ConditionalOnMissingBean
@Bean
public AnySearchDAO anySearchDAO(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.jpa.dao.AnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.PGAnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.PGJPAAnySearchDAO;
import org.apache.syncope.core.persistence.jpa.dao.repo.PGPlainSchemaRepoExtImpl;
import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt;
Expand All @@ -53,12 +51,6 @@ public EntityFactory entityFactory() {
return new PGEntityFactory();
}

@ConditionalOnMissingBean
@Bean
public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) {
return new PGAnyFinder(plainSchemaDAO, entityManager);
}

@ConditionalOnMissingBean
@Bean
public AnySearchDAO anySearchDAO(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@
import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
import org.apache.syncope.core.persistence.common.CommonPersistenceContext;
import org.apache.syncope.core.persistence.common.RuntimeDomainLoader;
import org.apache.syncope.core.persistence.common.dao.AnyFinder;
import org.apache.syncope.core.persistence.jpa.content.XMLContentExporter;
import org.apache.syncope.core.persistence.jpa.content.XMLContentLoader;
import org.apache.syncope.core.persistence.jpa.dao.AnyFinder;
import org.apache.syncope.core.persistence.jpa.dao.JPAAnyMatchDAO;
import org.apache.syncope.core.persistence.jpa.dao.JPAAuditEventDAO;
import org.apache.syncope.core.persistence.jpa.dao.JPABatchDAO;
Expand Down Expand Up @@ -371,6 +371,12 @@ protected Class<?> getRepositoryBaseClass(final RepositoryMetadata metadata) {
};
}

@ConditionalOnMissingBean
@Bean
public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final @Lazy AnySearchDAO anySearchDAO) {
return new AnyFinder(plainSchemaDAO, anySearchDAO);
}

@ConditionalOnMissingBean
@Bean
public AccessTokenDAO accessTokenDAO(final JpaRepositoryFactory jpaRepositoryFactory) {
Expand Down
Loading

0 comments on commit d97037c

Please sign in to comment.