Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ and minimize the interactions with the ConnId framework and have much of that
taken care of by a common API.

# Change Log

+ **5.1.4** - Added Annotation-based adapter framework (03/10/2025).
+ **5.1.3** - FIN-12722 - Add fullConnectionTest method to BaseConnector (01/10/2025)
+ **5.1.2** - FIN-12722 - Add non existent value caching to CacheMap implementation (01/08/2025)
+ **5.1.1** - FIN-12722 - Add fetchAll to CacheMap implementation (01/06/2025)
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
software_version=5.1.3
software_version=5.1.5
test_connector_version=3.0.4
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,36 @@ public class AdapterValueTypeConverter {

private AdapterValueTypeConverter() {}

public static <T> T getSingleAttributeValueNoEnum(
Class<T> returnType, Set<Attribute> attributes, String stringValue) {
if (stringValue == null) {
return null;
}
return getAttributeValue(returnType, attributes, stringValue, true);
}

public static <T> T getSingleAttributeValue(
Class<T> returnType, Set<Attribute> attributes, Enum<?> enumValue) {
if (enumValue == null) {
return null;
}
return getAttributeValue(returnType, attributes, enumValue.toString(), true);
return getSingleAttributeValueNoEnum(returnType, attributes, enumValue.toString());
}

public static <T> T getMultipleAttributeValueNoEnum(
Class<T> returnType, Set<Attribute> attributes, String stringValue) {
if (stringValue == null) {
return null;
}
return getAttributeValue(returnType, attributes, stringValue, false);
}

public static <T> T getMultipleAttributeValue(
Class<T> returnType, Set<Attribute> attributes, Enum<?> enumValue) {
if (enumValue == null) {
return null;
}
return getAttributeValue(returnType, attributes, enumValue.toString(), false);
return getMultipleAttributeValueNoEnum(returnType, attributes, enumValue.toString());
}

public static String getIdentityIdAttributeValue(Set<Attribute> attributes) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.exclamationlabs.connid.base.connector.util.annotationFramework;

import com.exclamationlabs.connid.base.connector.attribute.ConnectorAttribute;
import com.exclamationlabs.connid.base.connector.driver.Driver;
import com.exclamationlabs.connid.base.connector.model.IdentityModel;
import com.exclamationlabs.connid.base.connector.util.annotationFramework.annotations.AttributeIdentityValue;
import com.exclamationlabs.connid.base.connector.util.annotationFramework.annotations.AttributeNameValue;
import java.util.Set;
import org.identityconnectors.framework.common.objects.Attribute;

public abstract class AnnotatedIdentityModel implements IdentityModel {
protected void modifyConnectorAttributes(Set<ConnectorAttribute> result, Driver driver) {}

protected void beforeConstructModel(
Set<Attribute> attributes,
Set<Attribute> addedMultiValueAttributes,
Set<Attribute> removedMultiValueAttributes,
boolean isCreate,
AnnotatedIdentityModel annotatedIdentityModel,
Driver driver) {}

protected void afterConstructModel(
Set<Attribute> attributes,
Set<Attribute> addedMultiValueAttributes,
Set<Attribute> removedMultiValueAttributes,
boolean isCreate,
AnnotatedIdentityModel annotatedIdentityModel,
Driver driver) {}

protected void beforeConstructAttributes(
AnnotatedIdentityModel identityModel, Set<Attribute> attributes, Driver driver) {}

protected void afterConstructAttributes(
AnnotatedIdentityModel identityModel, Set<Attribute> attributes, Driver driver) {}

@Override
public String getIdentityIdValue() {
return AttributeUtils.getAnnotatedValue(this, AttributeIdentityValue.class);
}

@Override
public String getIdentityNameValue() {
return AttributeUtils.getAnnotatedValue(this, AttributeNameValue.class);
}

@Override
public String getValueBySearchableAttributeName(String attributeName) {
return IdentityModel.super.getValueBySearchableAttributeName(attributeName);
}

@Override
public String identityToString() {
return IdentityModel.super.identityToString();
}

@Override
public boolean identityEquals(
Class<? extends IdentityModel> identityClass, IdentityModel compareSource, Object compareTo) {
return IdentityModel.super.identityEquals(identityClass, compareSource, compareTo);
}

@Override
public int identityHashCode() {
return IdentityModel.super.identityHashCode();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.exclamationlabs.connid.base.connector.util.annotationFramework;

import com.exclamationlabs.connid.base.connector.adapter.BaseAdapter;
import com.exclamationlabs.connid.base.connector.attribute.ConnectorAttribute;
import com.exclamationlabs.connid.base.connector.configuration.ConnectorConfiguration;
import com.exclamationlabs.connid.base.connector.logging.Logger;
import com.exclamationlabs.connid.base.connector.util.annotationFramework.annotations.AdapterSettings;
import java.util.HashSet;
import java.util.Set;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.ObjectClass;

public class AnnotationAdapter<T extends AnnotatedIdentityModel, U extends ConnectorConfiguration>
extends BaseAdapter<T, U> {
protected Class<T> clazz;
protected AdapterSettings settings;

public AnnotationAdapter(Class<T> AnnotatedIdentityModelClass) {
this.clazz = AnnotatedIdentityModelClass;
settings = AttributeUtils.getAdapterSettingsAnnotation(clazz);
if (settings == null) {
throw new RuntimeException("AnnotationIdentiyModels must have an AdapterSettings annotation");
}
}

@Override
public ObjectClass getType() {
return new ObjectClass(settings.type());
}

@Override
public Class<T> getIdentityModelClass() {
return clazz;
}

@Override
public Set<ConnectorAttribute> getConnectorAttributes() {
Set<ConnectorAttribute> result = new HashSet<>();
AttributeUtils.createAttributesFromAnnotations(clazz, result);
T o = AttributeUtils.instantiateClass(clazz);
o.modifyConnectorAttributes(result, this.getDriver());
if (settings.logAttributes()) {
Logger.info(this, "Logging getConnectorAttributes");
AttributeUtils.logAttributes(this, result);
}
return result;
}

@Override
protected Set<Attribute> constructAttributes(T model) {
Set<Attribute> attributes = new HashSet<>();
model.beforeConstructAttributes(model, attributes, this.getDriver());
AttributeUtils.constructAttributesFromAnnotations(model, attributes);
model.afterConstructAttributes(model, attributes, this.getDriver());
if (settings.logAttributes()) {
Logger.info(this, "Logging constructAttributes");
AttributeUtils.logAttributeValues(this, attributes);
}
return attributes;
}

@Override
protected T constructModel(
Set<Attribute> attributes,
Set<Attribute> addedMultiValueAttributes,
Set<Attribute> removedMultiValueAttributes,
boolean isCreate) {
T o = AttributeUtils.instantiateClass(clazz);
o.beforeConstructModel(
attributes,
addedMultiValueAttributes,
removedMultiValueAttributes,
isCreate,
o,
this.getDriver());
AttributeUtils.constructModelFromAnnotations(
attributes, addedMultiValueAttributes, removedMultiValueAttributes, isCreate, o);
o.afterConstructModel(
attributes,
addedMultiValueAttributes,
removedMultiValueAttributes,
isCreate,
o,
this.getDriver());
if (settings.logAttributes()) {
Logger.info(this, "Logging constructModel");
Logger.info(this, o.toString());
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.exclamationlabs.connid.base.connector.util.annotationFramework;

import com.exclamationlabs.connid.base.connector.adapter.EnhancedPaginationAndFiltering;
import com.exclamationlabs.connid.base.connector.configuration.ConnectorConfiguration;
import java.util.Set;

public class AnnotationAdapterWithPaging<
T extends AnnotatedIdentityModel, U extends ConnectorConfiguration>
extends AnnotationAdapter<T, U> implements EnhancedPaginationAndFiltering {

public AnnotationAdapterWithPaging(Class<T> AnnotatedIdentityModelClass) {
super(AnnotatedIdentityModelClass);
}

@Override
public boolean getSearchResultsContainsAllAttributes() {
return settings.resultsContainsAllAttributes();
}

@Override
public boolean getSearchResultsContainsNameAttribute() {
return settings.resultsContainsNameAttribute();
}

@Override
public boolean getOneByName() {
return settings.getOneByName();
}

@Override
public Set<String> getSearchResultsAttributesPresent() {
return AttributeUtils.getAnnotatedSearchResultFields(clazz);
}

@Override
public boolean getFilteringRequiresFullImport() {
return settings.filteringRequiresFullImport();
}

@Override
public Integer getSubsequentRequestThreadCount() {
return EnhancedPaginationAndFiltering.super.getSubsequentRequestThreadCount();
}

@Override
public Integer getImportUsingPaginationThreadCount() {
return EnhancedPaginationAndFiltering.super.getImportUsingPaginationThreadCount();
}
}
Loading