attributes which are not returnedByDefault really are not returned
- * unless
- * specified in attrsToGet
+ *
attributes which are not returnedByDefault really are not returned unless specified in attrsToGet
*
update of non-updateable attribute will fail
*
required attributes must be creatable
*
@@ -199,13 +198,10 @@ public void testReturnedByDefault(final ObjectClass objectClass) {
@MethodSource("objectClasses")
public void testNonUpdateable(final ObjectClass objectClass) {
boolean exceptionCaught = false;
- /** is there any non updateable item? (if not skip this test) */
- boolean isChanged = false;
/** logging info bean */
LogInfo logInfo = null;
if (ConnectorHelper.operationsSupported(getConnectorFacade(), objectClass, getAPIOperations())) {
- ConnectorObject obj = null;
Uid uid = null;
try {
@@ -216,7 +212,7 @@ public void testNonUpdateable(final ObjectClass objectClass) {
assertNotNull(uid, "Create returned null Uid.");
// get by uid
- obj = getConnectorFacade().getObject(objectClass,
+ ConnectorObject obj = getConnectorFacade().getObject(objectClass,
uid, getOperationOptionsByOp(objectClass, GetApiOp.class));
assertNotNull(obj, "Cannot retrieve created object.");
@@ -226,7 +222,7 @@ public void testNonUpdateable(final ObjectClass objectClass) {
Set nonUpdateableAttrs = getNonUpdateableAttributes(schema, objectClass);
// null indicates an empty set ==> no non-updateable attributes
- isChanged = (nonUpdateableAttrs != null);
+ boolean isChanged = (nonUpdateableAttrs != null);
if (isChanged) {
//keep logging info
@@ -286,7 +282,6 @@ public void testNonUpdateable(final ObjectClass objectClass) {
} else {
printSkipTestMsg("testNonUpdateable", objectClass);
}
-
}
/**
@@ -459,6 +454,10 @@ private void testReturnedByDefault(final ObjectClass objectClass, final ApiOpera
obj = coObjects.get(0);
break;
+ case LIVE_SYNC:
+ uid = testLivesync(objectClass, uid, attrs, oci, testMarkMsg);
+ break;
+
case SYNC:
uid = testSync(objectClass, uid, token, attrs, oci, testMarkMsg);
break;
@@ -468,7 +467,7 @@ private void testReturnedByDefault(final ObjectClass objectClass, final ApiOpera
* Check if attribute set contains non-returned by default
* Attributes. This is specific for AttributeTests
*/
- if (!apiOp.equals(ApiOperations.SYNC)) {
+ if (apiOp != ApiOperations.SYNC && apiOp != ApiOperations.LIVE_SYNC) {
assertNotNull(obj, "Unable to retrieve newly created object");
// obj is null for sync tests
checkAttributes(obj, oci, apiOp);
@@ -517,22 +516,136 @@ private void checkAttributes(ConnectorObject obj, ObjectClassInfo oci, ApiOperat
/**
* test sync
*
- * @param token
- * initialized token
- * @param attrs
- * newly created attributes
- * @param uid
- * the newly created object
- * @param oci
- * object class info
+ * @param attrs newly created attributes
+ * @param uid the newly created object
+ * @param oci object class info
* @param testMarkMsg test marker
* @return the updated Uid
*/
- private Uid testSync(ObjectClass objectClass, Uid uid, SyncToken token,
- Set attrs, ObjectClassInfo oci, String testMarkMsg) {
+ private Uid testLivesync(
+ ObjectClass objectClass,
+ Uid uid,
+ Set attrs,
+ ObjectClassInfo oci,
+ String testMarkMsg) {
+
+ /*
+ * CREATE: (was handled in the calling method, result of create is in
+ * param uid, cleanup is also in caller method.)
+ */
+ if (SyncApiOpTests.canSyncAfterOp(CreateApiOp.class)) {
+ // sync after create
+ List deltas = ConnectorHelper.livesync(getConnectorFacade(), objectClass, null);
+
+ // check that returned one delta
+ String msg = "%s Sync should have returned one sync delta after creation of one object, but returned: %d";
+ assertTrue(deltas.size() == 1, String.format(msg, testMarkMsg, deltas.size()));
+
+ // check delta
+ ConnectorHelper.checkLiveSyncDelta(getObjectClassInfo(objectClass), deltas.get(0), uid, attrs, false);
+
+ /*
+ * check the attributes inside delta This is specific for
+ * AttributeTests
+ */
+ ConnectorObject obj = deltas.get(0).getObject();
+ checkAttributes(obj, oci, ApiOperations.LIVE_SYNC);
+ }
+
+ /* UPDATE: */
+ if (ConnectorHelper.operationSupported(getConnectorFacade(), UpdateApiOp.class)
+ && SyncApiOpTests.canSyncAfterOp(UpdateApiOp.class)) {
+
+ Set replaceAttributes = ConnectorHelper.getUpdateableAttributes(
+ getDataProvider(),
+ getObjectClassInfo(objectClass),
+ getTestName(),
+ SyncApiOpTests.MODIFIED,
+ 0,
+ false,
+ false);
+
+ // update only in case there is something to update
+ if (!replaceAttributes.isEmpty()) {
+ replaceAttributes.add(uid);
+
+ assertTrue(!replaceAttributes.isEmpty(), testMarkMsg + " no update attributes were found");
+ Uid newUid = getConnectorFacade().update(
+ objectClass,
+ uid,
+ AttributeUtil.filterUid(replaceAttributes),
+ null);
+
+ // Update change of Uid must be propagated to
+ // replaceAttributes
+ if (!newUid.equals(uid)) {
+ replaceAttributes.remove(uid);
+ replaceAttributes.add(newUid);
+ uid = newUid;
+ }
+
+ // sync after update
+ List deltas = ConnectorHelper.livesync(getConnectorFacade(), objectClass, null);
+
+ // check that returned one delta
+ String msg = "%s Sync should have returned one sync delta after update of one object, but returned: %d";
+ assertTrue(deltas.size() == 1, String.format(msg, testMarkMsg, deltas.size()));
+
+ // check delta
+ ConnectorHelper.checkLiveSyncDelta(
+ getObjectClassInfo(objectClass), deltas.get(0), uid, replaceAttributes, false);
+
+ /*
+ * check the attributes inside delta This is specific for
+ * AttributeTests
+ */
+ ConnectorObject obj = deltas.get(0).getObject();
+ checkAttributes(obj, oci, ApiOperations.LIVE_SYNC);
+ }
+ }
+
+ /* DELETE: */
+ if (SyncApiOpTests.canSyncAfterOp(DeleteApiOp.class)) {
+ // delete object
+ getConnectorFacade().delete(objectClass, uid, null);
+
+ // sync after delete
+ List deltas = ConnectorHelper.livesync(getConnectorFacade(), objectClass, null);
+
+ // check that returned one delta
+ String msg = "%s Sync should have returned one sync delta after delete of one object, but returned: %d";
+ assertTrue(deltas.size() == 1, String.format(msg, testMarkMsg, deltas.size()));
+
+ // check delta
+ ConnectorHelper.checkLiveSyncDelta(getObjectClassInfo(objectClass), deltas.get(0), uid, null, false);
+
+ /*
+ * check the attributes inside delta This is specific for
+ * AttributeTests
+ */
+ ConnectorObject obj = deltas.get(0).getObject();
+ checkAttributes(obj, oci, ApiOperations.LIVE_SYNC);
+ }
+ return uid;
+ }
- List deltas = null;
- String msg = null;
+ /**
+ * test sync
+ *
+ * @param token initialized token
+ * @param attrs newly created attributes
+ * @param uid the newly created object
+ * @param oci object class info
+ * @param testMarkMsg test marker
+ * @return the updated Uid
+ */
+ private Uid testSync(
+ ObjectClass objectClass,
+ Uid uid,
+ SyncToken token,
+ Set attrs,
+ ObjectClassInfo oci,
+ String testMarkMsg) {
/*
* CREATE: (was handled in the calling method, result of create is in
@@ -540,17 +653,15 @@ private Uid testSync(ObjectClass objectClass, Uid uid, SyncToken token,
*/
if (SyncApiOpTests.canSyncAfterOp(CreateApiOp.class)) {
// sync after create
- deltas = ConnectorHelper.sync(getConnectorFacade(),
- objectClass, token,
- null);
+ List deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token, null);
// check that returned one delta
- msg = "%s Sync should have returned one sync delta after creation of one object, but returned: %d";
+ String msg = "%s Sync should have returned one sync delta after creation of one object, but returned: %d";
assertTrue(deltas.size() == 1, String.format(msg, testMarkMsg, deltas.size()));
// check delta
- ConnectorHelper.checkSyncDelta(getObjectClassInfo(objectClass), deltas.get(0),
- uid, attrs, SyncDeltaType.CREATE_OR_UPDATE, false);
+ ConnectorHelper.checkSyncDelta(
+ getObjectClassInfo(objectClass), deltas.get(0), uid, attrs, SyncDeltaType.CREATE_OR_UPDATE, false);
/*
* check the attributes inside delta This is specific for
@@ -572,10 +683,10 @@ private Uid testSync(ObjectClass objectClass, Uid uid, SyncToken token,
SyncApiOpTests.MODIFIED, 0, false, false);
// update only in case there is something to update
- if (replaceAttributes.size() > 0) {
+ if (!replaceAttributes.isEmpty()) {
replaceAttributes.add(uid);
- assertTrue(replaceAttributes.size() > 0, testMarkMsg + " no update attributes were found");
+ assertTrue(!replaceAttributes.isEmpty(), testMarkMsg + " no update attributes were found");
Uid newUid = getConnectorFacade().update(
objectClass,
uid,
@@ -591,12 +702,10 @@ private Uid testSync(ObjectClass objectClass, Uid uid, SyncToken token,
}
// sync after update
- deltas = ConnectorHelper.sync(getConnectorFacade(),
- objectClass, token,
- null);
+ List deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token, null);
// check that returned one delta
- msg = "%s Sync should have returned one sync delta after update of one object, but returned: %d";
+ String msg = "%s Sync should have returned one sync delta after update of one object, but returned: %d";
assertTrue(deltas.size() == 1, String.format(msg, testMarkMsg, deltas.size()));
// check delta
@@ -618,21 +727,18 @@ private Uid testSync(ObjectClass objectClass, Uid uid, SyncToken token,
/* DELETE: */
if (SyncApiOpTests.canSyncAfterOp(DeleteApiOp.class)) {
// delete object
- getConnectorFacade().delete(objectClass, uid,
- null);
+ getConnectorFacade().delete(objectClass, uid, null);
// sync after delete
- deltas = ConnectorHelper.sync(getConnectorFacade(),
- objectClass, token,
- null);
+ List deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token, null);
// check that returned one delta
- msg = "%s Sync should have returned one sync delta after delete of one object, but returned: %d";
+ String msg = "%s Sync should have returned one sync delta after delete of one object, but returned: %d";
assertTrue(deltas.size() == 1, String.format(msg, testMarkMsg, deltas.size()));
// check delta
- ConnectorHelper.checkSyncDelta(getObjectClassInfo(objectClass), deltas.get(0),
- uid, null, SyncDeltaType.DELETE, false);
+ ConnectorHelper.checkSyncDelta(
+ getObjectClassInfo(objectClass), deltas.get(0), uid, null, SyncDeltaType.DELETE, false);
/*
* check the attributes inside delta This is specific for
@@ -650,6 +756,7 @@ private Uid testSync(ObjectClass objectClass, Uid uid, SyncToken token,
enum ApiOperations {
SEARCH(SearchApiOp.class),
GET(GetApiOp.class),
+ LIVE_SYNC(LiveSyncApiOp.class),
SYNC(SyncApiOp.class);
private final String s;
diff --git a/java/connector-framework-contract/src/main/java/org/identityconnectors/contract/test/ConnectorHelper.java b/java/connector-framework-contract/src/main/java/org/identityconnectors/contract/test/ConnectorHelper.java
index 545c1514..263adc67 100644
--- a/java/connector-framework-contract/src/main/java/org/identityconnectors/contract/test/ConnectorHelper.java
+++ b/java/connector-framework-contract/src/main/java/org/identityconnectors/contract/test/ConnectorHelper.java
@@ -69,6 +69,7 @@
import org.identityconnectors.framework.common.objects.AttributeDeltaUtil;
import org.identityconnectors.framework.common.objects.AttributeInfo;
import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.LiveSyncDelta;
import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.ObjectClassInfo;
@@ -317,6 +318,23 @@ public static Map search2Map(
return foundObjects;
}
+ /**
+ * Performs livesync on connector facade.
+ *
+ * @returns list of deltas
+ */
+ public static List livesync(ConnectorFacade connectorFacade, ObjectClass objClass,
+ OperationOptions opOptions) {
+ final List returnedDeltas = new ArrayList<>();
+
+ connectorFacade.livesync(objClass, delta -> {
+ returnedDeltas.add(delta);
+ return true;
+ }, opOptions);
+
+ return returnedDeltas;
+ }
+
/**
* Performs sync on connector facade.
*
@@ -386,9 +404,9 @@ public static boolean checkObject(ObjectClassInfo objectClassInfo, ConnectorObje
boolean success = true;
requestedAttributes.stream().
- filter((attribute) -> (isReadable(objectClassInfo, attribute))).
- filter((attribute) -> (checkNotReturnedByDefault || isReturnedByDefault(objectClassInfo, attribute))).
- forEachOrdered((attribute) -> {
+ filter(attribute -> isReadable(objectClassInfo, attribute)).
+ filter(attribute -> checkNotReturnedByDefault || isReturnedByDefault(objectClassInfo, attribute)).
+ forEachOrdered(attribute -> {
Attribute createdAttribute = connectorObj.getAttributeByName(attribute.getName());
if (createdAttribute == null) {
fail(String.format("Attribute '%s' is missing.", attribute.getName()));
@@ -474,10 +492,33 @@ static boolean checkValue(List fetchedValues, List expectedValues) {
}
/**
- * Check that passed SyncDelta has exptected values.
+ * Check that passed SyncDelta has expected values.
*/
- public static void checkSyncDelta(ObjectClassInfo ocInfo, SyncDelta delta, Uid uid, Set attributes,
- SyncDeltaType deltaType, boolean checkNotReturnedByDefault) {
+ public static void checkLiveSyncDelta(
+ final ObjectClassInfo ocInfo,
+ final LiveSyncDelta delta,
+ final Uid uid, Set attributes,
+ final boolean checkNotReturnedByDefault) {
+
+ // check that Uid is correct
+ String msg = "Sync returned wrong Uid, expected: %s, returned: %s.";
+ assertEquals(delta.getUid(), uid, String.format(msg, uid, delta.getUid()));
+
+ // check that attributes are correct
+ ConnectorHelper.checkObject(ocInfo, delta.getObject(), attributes, checkNotReturnedByDefault);
+ }
+
+ /**
+ * Check that passed SyncDelta has expected values.
+ */
+ public static void checkSyncDelta(
+ final ObjectClassInfo ocInfo,
+ final SyncDelta delta,
+ final Uid uid,
+ final Set attributes,
+ final SyncDeltaType deltaType,
+ boolean checkNotReturnedByDefault) {
+
// check that Uid is correct
String msg = "Sync returned wrong Uid, expected: %s, returned: %s.";
assertEquals(delta.getUid(), uid, String.format(msg, uid, delta.getUid()));
diff --git a/java/connector-framework-contract/src/main/java/org/identityconnectors/contract/test/SyncApiOpTests.java b/java/connector-framework-contract/src/main/java/org/identityconnectors/contract/test/SyncApiOpTests.java
index c0fea0af..5dcfe742 100644
--- a/java/connector-framework-contract/src/main/java/org/identityconnectors/contract/test/SyncApiOpTests.java
+++ b/java/connector-framework-contract/src/main/java/org/identityconnectors/contract/test/SyncApiOpTests.java
@@ -89,18 +89,14 @@ public Set> getAPIOperations() {
@Override
protected void testRun(ObjectClass objectClass) {
Uid uid = null;
- Set attrs = null;
- List deltas = null;
- SyncToken token = null;
- String msg = null;
try {
// start synchronizing from now
- token = getConnectorFacade().getLatestSyncToken(objectClass);
+ SyncToken token = getConnectorFacade().getLatestSyncToken(objectClass);
/* CREATE: */
// create record
- attrs = ConnectorHelper.getCreateableAttributes(getDataProvider(),
+ Set attrs = ConnectorHelper.getCreateableAttributes(getDataProvider(),
getObjectClassInfo(objectClass), getTestName(), 0, true, false);
uid = getConnectorFacade().create(objectClass, attrs,
getOperationOptionsByOp(objectClass, CreateApiOp.class));
@@ -108,16 +104,16 @@ protected void testRun(ObjectClass objectClass) {
if (canSyncAfterOp(CreateApiOp.class)) {
// sync after create
- deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token,
+ List deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token,
getOperationOptionsByOp(objectClass, SyncApiOp.class));
// check that returned one delta
- msg = "Sync should have returned one sync delta after creation of one object, but returned: %d";
+ String msg = "Sync should have returned one sync delta after creation of one object, but returned: %d";
assertTrue(deltas.size() == 1, String.format(msg, deltas.size()));
// check delta
- ConnectorHelper.checkSyncDelta(getObjectClassInfo(objectClass), deltas.get(0), uid, attrs,
- SyncDeltaType.CREATE_OR_UPDATE, true);
+ ConnectorHelper.checkSyncDelta(
+ getObjectClassInfo(objectClass), deltas.get(0), uid, attrs, SyncDeltaType.CREATE_OR_UPDATE, true);
token = deltas.get(0).getToken();
}
@@ -131,10 +127,10 @@ && canSyncAfterOp(UpdateApiOp.class)) {
false);
// update only in case there is something to update
- if (replaceAttributes.size() > 0) {
+ if (!replaceAttributes.isEmpty()) {
replaceAttributes.add(uid);
- assertTrue((replaceAttributes.size() > 0), "no update attributes were found");
+ assertTrue((!replaceAttributes.isEmpty()), "no update attributes were found");
Uid newUid = getConnectorFacade().update(
objectClass, uid, AttributeUtil.filterUid(replaceAttributes),
getOperationOptionsByOp(objectClass, UpdateApiOp.class));
@@ -148,11 +144,12 @@ && canSyncAfterOp(UpdateApiOp.class)) {
}
// sync after update
- deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token,
+ List deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token,
getOperationOptionsByOp(objectClass, SyncApiOp.class));
// check that returned one delta
- msg = "Sync should have returned one sync delta after update of one object, but returned: %d";
+ String msg =
+ "Sync should have returned one sync delta after update of one object, but returned: %d";
assertTrue(deltas.size() == 1, String.format(msg, deltas.size()));
// check delta
@@ -170,16 +167,16 @@ && canSyncAfterOp(UpdateApiOp.class)) {
getOperationOptionsByOp(objectClass, DeleteApiOp.class));
// sync after delete
- deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token,
+ List deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token,
getOperationOptionsByOp(objectClass, SyncApiOp.class));
// check that returned one delta
- msg = "Sync should have returned one sync delta after delete of one object, but returned: %d";
+ String msg = "Sync should have returned one sync delta after delete of one object, but returned: %d";
assertTrue(deltas.size() == 1, String.format(msg, deltas.size()));
// check delta
- ConnectorHelper.checkSyncDelta(getObjectClassInfo(objectClass), deltas.get(0), uid, null,
- SyncDeltaType.DELETE, true);
+ ConnectorHelper.checkSyncDelta(
+ getObjectClassInfo(objectClass), deltas.get(0), uid, null, SyncDeltaType.DELETE, true);
}
} finally {
// cleanup test data
@@ -209,8 +206,7 @@ && canSyncAfterOp(CreateApiOp.class)) {
uid = getConnectorFacade().create(objectClass, attrs, null);
assertNotNull(uid, "Create returned null uid.");
- List deltas = ConnectorHelper.sync(getConnectorFacade(),
- objectClass, token, null);
+ List deltas = ConnectorHelper.sync(getConnectorFacade(), objectClass, token, null);
// check that returned one delta
final String MSG =
diff --git a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/AttributesToGetResultsHandler.java b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/AttributesToGetResultsHandler.java
index 82ab10a9..0830176d 100644
--- a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/AttributesToGetResultsHandler.java
+++ b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/AttributesToGetResultsHandler.java
@@ -19,13 +19,14 @@
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
+ * Portions Copyrighted 2024 ConnId
*/
package org.identityconnectors.framework.impl.api.local.operations;
import java.util.HashSet;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
-
import org.identityconnectors.common.Assertions;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -33,18 +34,18 @@
import org.identityconnectors.framework.common.objects.ConnectorObjectBuilder;
import org.identityconnectors.framework.common.objects.OperationOptions;
-
/**
* Simple class for common results handler components that involve
* {@link OperationOptions#OP_ATTRIBUTES_TO_GET}.
*/
public abstract class AttributesToGetResultsHandler {
+
private final String[] attrsToGet;
/**
* Keep the attribute to get..
*/
- public AttributesToGetResultsHandler(String[] attributesToGet) {
+ public AttributesToGetResultsHandler(final String[] attributesToGet) {
Assertions.nullCheck(attributesToGet, "attrsToGet");
this.attrsToGet = attributesToGet;
}
@@ -54,26 +55,22 @@ public AttributesToGetResultsHandler(String[] attributesToGet) {
* not in the {@link OperationOptions#OP_ATTRIBUTES_TO_GET} set.
*
* @param attributesToGet
- * case insensitive set of attribute names.
+ * case insensitive set of attribute names.
*/
public Set reduceToAttrsToGet(Set attributesToGet) {
- Set ret = new HashSet(attrsToGet.length);
+ Set ret = new HashSet<>(attrsToGet.length);
Map map = AttributeUtil.toMap(attributesToGet);
for (String attrName : attrsToGet) {
Attribute attr = map.get(attrName);
- // TODO: Should we throw if the attribute is not yet it was
- // requested?? Or do we ignore because the API maybe asking
- // for what the resource doesn't have??
- if (attr != null) {
- ret.add(attr);
- }
+ // TODO: Should we throw if the attribute is not yet it was requested?? Or do we ignore because the API
+ // maybe asking for what the resource doesn't have??
+ Optional.ofNullable(attr).ifPresent(ret::add);
}
return ret;
}
public ConnectorObject reduceToAttrsToGet(ConnectorObject obj) {
- // clone the object and reduce the attributes only the set of
- // attributes.
+ // clone the object and reduce the attributes only the set of attributes.
ConnectorObjectBuilder bld = new ConnectorObjectBuilder();
bld.setUid(obj.getUid());
bld.setName(obj.getName());
diff --git a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/LiveSyncImpl.java b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/LiveSyncImpl.java
index 1bdb3b8f..4e35236a 100644
--- a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/LiveSyncImpl.java
+++ b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/LiveSyncImpl.java
@@ -22,6 +22,7 @@
*/
package org.identityconnectors.framework.impl.api.local.operations;
+import java.util.Optional;
import org.identityconnectors.common.Assertions;
import org.identityconnectors.common.logging.Log;
import org.identityconnectors.framework.api.ResultsHandlerConfiguration;
@@ -93,7 +94,7 @@ public static class AttributesToGetLiveSyncResultsHandler
private final LiveSyncResultsHandler handler;
- public AttributesToGetLiveSyncResultsHandler(final LiveSyncResultsHandler handler, String[] attrsToGet) {
+ public AttributesToGetLiveSyncResultsHandler(final LiveSyncResultsHandler handler, final String[] attrsToGet) {
super(attrsToGet);
this.handler = handler;
}
@@ -101,9 +102,7 @@ public AttributesToGetLiveSyncResultsHandler(final LiveSyncResultsHandler handle
@Override
public boolean handle(final LiveSyncDelta delta) {
LiveSyncDeltaBuilder bld = new LiveSyncDeltaBuilder(delta);
- if (delta.getObject() != null) {
- bld.setObject(reduceToAttrsToGet(delta.getObject()));
- }
+ Optional.ofNullable(delta.getObject()).ifPresent(obj -> bld.setObject(reduceToAttrsToGet(obj)));
return handler.handle(bld.build());
}
}
diff --git a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/SyncImpl.java b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/SyncImpl.java
index 287f8be7..695c8611 100644
--- a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/SyncImpl.java
+++ b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/api/local/operations/SyncImpl.java
@@ -25,6 +25,7 @@
*/
package org.identityconnectors.framework.impl.api.local.operations;
+import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import org.identityconnectors.common.Assertions;
import org.identityconnectors.common.logging.Log;
@@ -155,7 +156,7 @@ public static class AttributesToGetSyncResultsHandler
private final SyncResultsHandler handler;
- public AttributesToGetSyncResultsHandler(final SyncResultsHandler handler, String[] attrsToGet) {
+ public AttributesToGetSyncResultsHandler(final SyncResultsHandler handler, final String[] attrsToGet) {
super(attrsToGet);
this.handler = handler;
}
@@ -163,9 +164,7 @@ public AttributesToGetSyncResultsHandler(final SyncResultsHandler handler, Strin
@Override
public boolean handle(final SyncDelta delta) {
SyncDeltaBuilder bld = new SyncDeltaBuilder(delta);
- if (delta.getObject() != null) {
- bld.setObject(reduceToAttrsToGet(delta.getObject()));
- }
+ Optional.ofNullable(delta.getObject()).ifPresent(obj -> bld.setObject(reduceToAttrsToGet(obj)));
return handler.handle(bld.build());
}
}
diff --git a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/CommonObjectHandlers.java b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/CommonObjectHandlers.java
index b116d501..f4c4c1d3 100644
--- a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/CommonObjectHandlers.java
+++ b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/CommonObjectHandlers.java
@@ -21,6 +21,7 @@
* ====================
* Portions Copyrighted 2010-2013 ForgeRock AS.
* Portions Copyrighted 2015-2016 Evolveum
+ * Portions Copyrighted 2024 ConnId
*/
package org.identityconnectors.framework.impl.serializer;
@@ -33,7 +34,6 @@
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
-
import org.identityconnectors.common.script.Script;
import org.identityconnectors.common.script.ScriptBuilder;
import org.identityconnectors.framework.api.operations.APIOperation;
@@ -716,6 +716,27 @@ public void serialize(final Object object, final ObjectEncoder encoder) {
}
});
+ HANDLERS.add(new AbstractObjectSerializationHandler(LiveSyncDelta.class, "LiveSyncDelta") {
+
+ @Override
+ public Object deserialize(final ObjectDecoder decoder) {
+ return new LiveSyncDeltaBuilder().
+ setObjectClass((ObjectClass) decoder.readObjectField("ObjectClass", ObjectClass.class, null)).
+ setUid((Uid) decoder.readObjectField("Uid", Uid.class, null)).
+ setObject((ConnectorObject) decoder.
+ readObjectField("ConnectorObject", ConnectorObject.class, null)).
+ build();
+ }
+
+ @Override
+ public void serialize(final Object object, final ObjectEncoder encoder) {
+ final LiveSyncDelta val = (LiveSyncDelta) object;
+ encoder.writeObjectField("ObjectClass", val.getObjectClass(), true);
+ encoder.writeObjectField("Uid", val.getUid(), true);
+ encoder.writeObjectField("ConnectorObject", val.getObject(), true);
+ }
+ });
+
HANDLERS.add(new AbstractObjectSerializationHandler(SyncDelta.class, "SyncDelta") {
@Override
diff --git a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/ObjectTypeMapper.java b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/ObjectTypeMapper.java
index 1c453ae8..429626be 100644
--- a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/ObjectTypeMapper.java
+++ b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/ObjectTypeMapper.java
@@ -19,30 +19,33 @@
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
+ * Portions Copyrighted 2024 ConnId
*/
package org.identityconnectors.framework.impl.serializer;
/**
- * Interface to be implemented to handle the serialization/
- * deserialization of an object.
+ * Interface to be implemented to handle the serialization/deserialization of an object.
*/
public interface ObjectTypeMapper {
/**
- * Returns the type of object being serialized. This is
- * an abstract type name that is intended to be language
- * neutral.
+ * Returns the type of object being serialized.
+ *
+ * @return an abstract type name that is intended to be language neutral
*/
String getHandledSerialType();
/**
* Returns the java class handled by this handler.
+ *
+ * @return the java class handled by this handler
*/
Class> getHandledObjectType();
/**
- * Should we match subclasses of the given class or only
- * the exact class?
+ * Should we match subclasses of the given class or only the exact class?
+ *
+ * @return whether subclasses of the given class or only the exact class should be matched
*/
boolean isMatchSubclasses();
}
diff --git a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/Primitives.java b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/Primitives.java
index b3d4ca24..69f5b543 100644
--- a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/Primitives.java
+++ b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/Primitives.java
@@ -40,7 +40,6 @@
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
-
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.security.EncryptorFactory;
import org.identityconnectors.common.security.GuardedByteArray;
@@ -50,10 +49,9 @@
class Primitives {
- public static final List HANDLERS = new ArrayList();
+ public static final List HANDLERS = new ArrayList<>();
static {
-
HANDLERS.add(new AbstractObjectSerializationHandler(Boolean.class, "Boolean") {
@Override
@@ -376,10 +374,9 @@ public Object deserialize(final ObjectDecoder decoder) {
@Override
public void serialize(final Object object, final ObjectEncoder encoder) {
final ZonedDateTime val = (ZonedDateTime) object;
- // Make sure we have timezone as (numeric) offset instead of
- // using zone ID. We do this by invoking toOffsetDateTime().
- // This makes the timestamp ISO-8601 compatible and therefore
- // more portable.
+ // Make sure we have timezone as (numeric) offset instead of using zone ID. We do this by invoking
+ // toOffsetDateTime().
+ // This makes the timestamp ISO-8601 compatible and therefore more portable.
encoder.writeStringContents(val.toOffsetDateTime().toString());
}
});
@@ -441,14 +438,11 @@ public void serialize(final Object object, final ObjectEncoder encoder) {
// special case - for case insensitive maps
if (CollectionUtil.isCaseInsensitiveMap(map)) {
encoder.writeBooleanField("caseInsensitive", true);
- } // for all other sorted maps, we don't know how
- // to serialize them
+ } // for all other sorted maps, we don't know how to serialize them
else if (map instanceof SortedMap) {
throw new IllegalArgumentException("Serialization of SortedMap not supported");
}
- map.forEach((key, value) -> {
- encoder.writeObjectContents(new MapEntry(key, value));
- });
+ map.forEach((key, value) -> encoder.writeObjectContents(new MapEntry(key, value)));
}
@Override
@@ -513,9 +507,7 @@ public void serialize(final Object object, final ObjectEncoder encoder) {
else if (set instanceof SortedSet) {
throw new IllegalArgumentException("Serialization of SortedSet not supported");
}
- set.forEach((obj) -> {
- encoder.writeObjectContents(obj);
- });
+ set.forEach((obj) -> encoder.writeObjectContents(obj));
}
@Override
diff --git a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/binary/BinaryObjectEncoder.java b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/binary/BinaryObjectEncoder.java
index 23cbef1f..5c4d7ce6 100644
--- a/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/binary/BinaryObjectEncoder.java
+++ b/java/connector-framework-internal/src/main/java/org/identityconnectors/framework/impl/serializer/binary/BinaryObjectEncoder.java
@@ -379,7 +379,7 @@ public void writeDoubleField(String fieldName, double v) {
public void writeFloatContents(float v) {
internalEncoder.startAnonymousField();
// write as double since C# only knows how to deal with that
- internalEncoder.writeDouble((double) v);
+ internalEncoder.writeDouble(v);
internalEncoder.endField();
}
@@ -387,7 +387,7 @@ public void writeFloatContents(float v) {
public void writeFloatField(String fieldName, float v) {
internalEncoder.startField(fieldName);
// write as double since C# only knows how to deal with that
- internalEncoder.writeDouble((double) v);
+ internalEncoder.writeDouble(v);
internalEncoder.endField();
}
diff --git a/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/api/ConnectorFacadeTests.java b/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/api/ConnectorFacadeTests.java
index c8a3c534..87e18e3f 100644
--- a/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/api/ConnectorFacadeTests.java
+++ b/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/api/ConnectorFacadeTests.java
@@ -32,7 +32,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.api.APIConfiguration;
@@ -47,6 +46,7 @@
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.LiveSyncDelta;
import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.ResultsHandler;
@@ -510,6 +510,24 @@ public void checkCalls(List calls) {
});
}
+ @Test
+ public void livesyncCallPattern() {
+ testCallPattern(new TestOperationPattern() {
+
+ @Override
+ public void makeCall(ConnectorFacade facade) {
+ // create an empty results handler..
+ // call the search method..
+ facade.livesync(ObjectClass.ACCOUNT, (LiveSyncDelta delta) -> true, null);
+ }
+
+ @Override
+ public void checkCalls(List calls) {
+ assertEquals(calls.remove(0).getMethodName(), "livesync");
+ }
+ });
+ }
+
@Test
public void syncCallPattern() {
testCallPattern(new TestOperationPattern() {
@@ -585,8 +603,8 @@ public void updateMergeTests() {
addAttrSet.add(AttributeBuilder.build(ATTR_NAME, ADDED));
Name name = obj.getName();
addAttrSet.remove(name);
- Uid uid = facade.
- addAttributeValues(ObjectClass.ACCOUNT, obj.getUid(), AttributeUtil.filterUid(addAttrSet), null);
+ Uid uid = facade.addAttributeValues(
+ ObjectClass.ACCOUNT, obj.getUid(), AttributeUtil.filterUid(addAttrSet), null);
// get back the object and see if there are the same..
addAttrSet.add(name);
ConnectorObject addO = new ConnectorObject(ObjectClass.ACCOUNT, addAttrSet);
@@ -603,8 +621,8 @@ public void updateMergeTests() {
// attempt to delete a value from an attribute..
Set deleteAttrs = CollectionUtil.newSet(addO.getAttributes());
deleteAttrs.remove(name);
- uid = facade.removeAttributeValues(ObjectClass.ACCOUNT, addO.getUid(), AttributeUtil.filterUid(deleteAttrs),
- null);
+ uid = facade.removeAttributeValues(
+ ObjectClass.ACCOUNT, addO.getUid(), AttributeUtil.filterUid(deleteAttrs), null);
obj = facade.getObject(ObjectClass.ACCOUNT, uid, null);
expected = AttributeBuilder.build(ATTR_NAME, ADDED);
actual = obj.getAttributeByName(ATTR_NAME);
@@ -613,8 +631,7 @@ public void updateMergeTests() {
Set nonExist = new HashSet<>();
nonExist.add(newUid(1));
nonExist.add(AttributeBuilder.build("does not exist", "asdfe"));
- uid = facade.removeAttributeValues(ObjectClass.ACCOUNT, addO.getUid(), AttributeUtil.filterUid(nonExist),
- null);
+ facade.removeAttributeValues(ObjectClass.ACCOUNT, addO.getUid(), AttributeUtil.filterUid(nonExist), null);
obj = facade.getObject(ObjectClass.ACCOUNT, newUid(1), null);
assertTrue(obj.getAttributeByName("does not exist") == null);
}
diff --git a/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/api/local/operations/ObjectNormalizerFacadeTests.java b/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/api/local/operations/ObjectNormalizerFacadeTests.java
index c2f59654..4d12572f 100644
--- a/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/api/local/operations/ObjectNormalizerFacadeTests.java
+++ b/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/api/local/operations/ObjectNormalizerFacadeTests.java
@@ -31,6 +31,8 @@
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
import org.identityconnectors.framework.common.objects.ConnectorObjectBuilder;
+import org.identityconnectors.framework.common.objects.LiveSyncDelta;
+import org.identityconnectors.framework.common.objects.LiveSyncDeltaBuilder;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.SyncDelta;
import org.identityconnectors.framework.common.objects.SyncDeltaBuilder;
@@ -189,6 +191,29 @@ public void testConnectorObject() {
assertFalse(expected.equals(v1));
}
+ @Test
+ public void testLiveSyncDelta() {
+ ConnectorObjectBuilder objbuilder = new ConnectorObjectBuilder();
+ objbuilder.setName("myname");
+ objbuilder.setUid("myuid");
+ objbuilder.addAttribute(createTestAttribute());
+ ConnectorObject obj = objbuilder.build();
+
+ LiveSyncDeltaBuilder builder = new LiveSyncDeltaBuilder();
+ builder.setObject(obj);
+ LiveSyncDelta v1 = builder.build();
+ LiveSyncDelta v2 = createTestNormalizer().normalizeLiveSyncDelta(v1);
+ builder = new LiveSyncDeltaBuilder();
+ objbuilder = new ConnectorObjectBuilder();
+ objbuilder.setName("myname");
+ objbuilder.setUid("myuid");
+ objbuilder.addAttribute(createNormalizedTestAttribute());
+ builder.setObject(objbuilder.build());
+ LiveSyncDelta expected = builder.build();
+ assertEquals(v2, expected);
+ assertFalse(expected.equals(v1));
+ }
+
@Test
public void testSyncDelta() {
ConnectorObjectBuilder objbuilder = new ConnectorObjectBuilder();
diff --git a/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/serializer/ObjectSerializationTests.java b/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/serializer/ObjectSerializationTests.java
index 268784ae..a81e0ddf 100644
--- a/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/serializer/ObjectSerializationTests.java
+++ b/java/connector-framework-internal/src/test/java/org/identityconnectors/framework/impl/serializer/ObjectSerializationTests.java
@@ -46,7 +46,6 @@
import java.util.Map;
import java.util.Set;
import java.util.Collections;
-
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.pooling.ObjectPoolConfiguration;
import org.identityconnectors.common.script.Script;
@@ -1076,6 +1075,28 @@ public void testSyncDelta() {
assertEquals(v1, v2);
}
+ @Test
+ public void testLiveSyncDelta() {
+ ConnectorObjectBuilder bld = new ConnectorObjectBuilder();
+ bld.setUid("foo");
+ bld.setName("name");
+ LiveSyncDeltaBuilder builder = new LiveSyncDeltaBuilder();
+ builder.setObject(bld.build());
+ LiveSyncDelta v1 = builder.build();
+ LiveSyncDelta v2 = (LiveSyncDelta) cloneObject(v1);
+ assertEquals(new Uid("foo"), v2.getObject().getUid());
+ assertEquals(v1, v2);
+
+ builder = new LiveSyncDeltaBuilder();
+ builder.setObjectClass(ObjectClass.ACCOUNT);
+ builder.setUid(new Uid("foo"));
+ v1 = builder.build();
+ v2 = (LiveSyncDelta) cloneObject(v1);
+ assertEquals(ObjectClass.ACCOUNT, v2.getObjectClass());
+ assertEquals(new Uid("foo"), v2.getUid());
+ assertEquals(v1, v2);
+ }
+
@Test
public void testNull() {
Object v1 = null;
diff --git a/java/connector-framework/src/main/java/org/identityconnectors/framework/common/FrameworkUtil.java b/java/connector-framework/src/main/java/org/identityconnectors/framework/common/FrameworkUtil.java
index 499af23c..aed73b97 100644
--- a/java/connector-framework/src/main/java/org/identityconnectors/framework/common/FrameworkUtil.java
+++ b/java/connector-framework/src/main/java/org/identityconnectors/framework/common/FrameworkUtil.java
@@ -40,7 +40,6 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.IOUtil;
import org.identityconnectors.common.ReflectionUtil;
@@ -128,8 +127,7 @@ public static Set> allAPIOperations() {
}
/**
- * Determines the default set of operations that a {@link Connector}
- * supports.
+ * Determines the default set of operations that a {@link Connector} supports.
*/
public static Set> getDefaultSupportedOperations(
Class extends Connector> connector) {
@@ -198,8 +196,7 @@ public static Set> getAllSupportedConfigTypes() {
/**
* Determines if the class is a supported configuration type.
*
- * @param clazz
- * the type to check against the list of supported types.
+ * @param clazz the type to check against the list of supported types.
* @return true if the type is in the list otherwise false.
*/
public static boolean isSupportedConfigurationType(Class> clazz) {
@@ -249,8 +246,7 @@ public static Set> getAllSupportedAttributeTypes() {
/**
* Determines if the class is a supported attribute type.
*
- * @param clazz
- * the type to check against a supported list of types.
+ * @param clazz the type to check against a supported list of types.
* @return true if the type is on the supported list otherwise false.
*/
public static boolean isSupportedAttributeType(final Class> clazz) {
@@ -284,10 +280,8 @@ public static boolean isSupportedAttributeType(final Class> clazz) {
*
ZonedDateTime.class
*
*
- * @param clazz
- * type to check against the support list of types.
- * @throws IllegalArgumentException
- * if the type is not on the supported list.
+ * @param clazz type to check against the support list of types.
+ * @throws IllegalArgumentException if the type is not on the supported list.
*/
public static void checkAttributeType(final Class> clazz) {
if (!FrameworkUtil.isSupportedAttributeType(clazz)) {
@@ -297,13 +291,11 @@ public static void checkAttributeType(final Class> clazz) {
}
/**
- * Determines if the class of the object is a supported attribute type. If
- * not it throws an {@link IllegalArgumentException}.
+ * Determines if the class of the object is a supported attribute type. If not it throws an
+ * {@link IllegalArgumentException}.
*
- * @param value
- * The value to check or null.
- * @throws IllegalArgumentException
- * If the class of the object is a supported attribute type.
+ * @param value The value to check or null.
+ * @throws IllegalArgumentException If the class of the object is a supported attribute type.
*/
public static void checkAttributeValue(Object value) {
if (value != null) {
@@ -312,15 +304,12 @@ public static void checkAttributeValue(Object value) {
}
/**
- * Determines if the class of the object is a supported attribute type. If
- * not it throws an {@link IllegalArgumentException}.
+ * Determines if the class of the object is a supported attribute type. If not it throws an
+ * {@link IllegalArgumentException}.
*
- * @param name
- * The name of the attribute to check
- * @param value
- * The value to check or null.
- * @throws IllegalArgumentException
- * If the class of the object is a supported attribute type.
+ * @param name The name of the attribute to check
+ * @param value The value to check or null.
+ * @throws IllegalArgumentException If the class of the object is a supported attribute type.
*/
public static void checkAttributeValue(String name, Object value) {
if (value instanceof Map) {
@@ -352,10 +341,9 @@ private static void checkAttributeValue(StringBuilder name, Object value) {
checkAttributeValue(nameBuilder, entryValue);
}
} else {
- throw new IllegalArgumentException(
- MessageFormat
- .format("Map Attribute ''{0}'' must have String key, type ''{1}'' is not supported.",
- name, null != key ? key.getClass() : "null"));
+ throw new IllegalArgumentException(MessageFormat.format(
+ "Map Attribute ''{0}'' must have String key, type ''{1}'' is not supported.",
+ name, null != key ? key.getClass() : "null"));
}
}
} else if (value != null) {
@@ -367,17 +355,14 @@ private static void checkAttributeValue(StringBuilder name, Object value) {
}
/**
- * Determines if the class is a supported type for an OperationOption. If
- * not it throws an {@link IllegalArgumentException}.
+ * Determines if the class is a supported type for an OperationOption. If not it throws an
+ * {@link IllegalArgumentException}.
*
- * @param clazz
- * type to check against the support list of types.
- * @throws IllegalArgumentException
- * if the type is not on the supported list.
+ * @param clazz type to check against the support list of types.
+ * @throws IllegalArgumentException if the type is not on the supported list.
*/
public static void checkOperationOptionType(final Class> clazz) {
- // the set of supported operation option types
- // is the same as that for configuration beans plus Name,
+ // the set of supported operation option types is the same as that for configuration beans plus Name,
// ObjectClass, Uid, and QualifiedUid
if (clazz.isArray()) {
@@ -405,19 +390,15 @@ public static void checkOperationOptionType(final Class> clazz) {
return; // ok
}
- throw new IllegalArgumentException("OperationOption type '" + clazz.getName()
- + "' is not supported.");
+ throw new IllegalArgumentException("OperationOption type '" + clazz.getName() + "' is not supported.");
}
/**
- * Determines if the class of the object is a supported attribute type. If
- * not it throws an {@link IllegalArgumentException}.
- *
- * @param value
- * The value to check or null.
- * @throws IllegalArgumentException
- * if the class of the object is a supported attribute type
+ * Determines if the class of the object is a supported attribute type. If not it throws an
+ * {@link IllegalArgumentException}.
*
+ * @param value The value to check or null.
+ * @throws IllegalArgumentException if the class of the object is a supported attribute type
*/
public static void checkOperationOptionValue(Object value) {
if (value != null) {
@@ -451,8 +432,7 @@ static Version getFrameworkVersion(ClassLoader loader) throws IOException {
String version = props.getProperty(PROP_FRAMEWORK_VERSION);
if (version == null) {
throw new IllegalStateException(
- "connectors-framework.properties does not contain a "
- + PROP_FRAMEWORK_VERSION + " property");
+ "connectors-framework.properties does not contain a " + PROP_FRAMEWORK_VERSION + " property");
}
if (StringUtil.isBlank(version)) {
throw new IllegalStateException(
diff --git a/java/connector-framework/src/main/java/org/identityconnectors/framework/common/objects/AttributeBuilder.java b/java/connector-framework/src/main/java/org/identityconnectors/framework/common/objects/AttributeBuilder.java
index e780f387..8f2fc463 100644
--- a/java/connector-framework/src/main/java/org/identityconnectors/framework/common/objects/AttributeBuilder.java
+++ b/java/connector-framework/src/main/java/org/identityconnectors/framework/common/objects/AttributeBuilder.java
@@ -20,6 +20,7 @@
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
* Portions Copyrighted 2016 Evolveum
+ * Portions Copyrighted 2024 ConnId
*/
package org.identityconnectors.framework.common.objects;
@@ -28,7 +29,6 @@
import java.util.Collection;
import java.util.Date;
import java.util.List;
-
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.StringUtil;
import org.identityconnectors.common.security.GuardedString;
@@ -37,14 +37,11 @@
import org.identityconnectors.framework.common.FrameworkUtil;
/**
- * Simplifies constructing instances of {@link Attribute}. A {@code Connector}
- * developer does not need to implement the {@code Attribute} interface. The
- * builder returns an instance of an implementation of {@link Attribute} that
- * overrides the methods {@code equals()}, {@code hashcode()} and
- * {@code toString()} to provide a uniform and robust class. This implementation
- * is backed by an {@link ArrayList} that contains the values and preserves the
- * order of those values (in case the order of values is significant to the
- * target system or application).
+ * Simplifies constructing instances of {@link Attribute}. A {@code Connector} developer does not need to implement the
+ * {@code Attribute} interface. The builder returns an instance of an implementation of {@link Attribute} that
+ * overrides the methods {@code equals()}, {@code hashcode()} and {@code toString()} to provide a uniform and robust
+ * class. This implementation is backed by an {@link ArrayList} that contains the values and preserves the order of
+ * those values (in case the order of values is significant to the target system or application).
*
* @author Will Droste
* @since 1.0
@@ -53,17 +50,16 @@ public final class AttributeBuilder {
private final static String NAME_ERROR = "Name must not be blank!";
- String name;
+ private String name;
+
+ private List