/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions copyright [year] [name of copyright owner]".
*
* Copyright 2015 ForgeRock AS.
*/
package org.forgerock.openidm.managed;
import static java.text.MessageFormat.format;
import static org.forgerock.openidm.util.RelationshipUtil.REFERENCE_ID;
import org.forgerock.json.JsonValue;
import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.NotFoundException;
import org.forgerock.json.resource.ReadRequest;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.json.resource.ResourceResponse;
import org.forgerock.services.context.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class for Validators of relationship requests. When a relationship action is determined to be invalid, the
* validateRelationship method will throw a BadRequestException with a message indicating the details of the reason for
* it being invalid.
*/
abstract class RelationshipValidator {
private static final Logger logger = LoggerFactory.getLogger(RelationshipValidator.class);
/**
* The relationship provider that owns this validator.
*/
private RelationshipProvider relationshipProvider;
RelationshipValidator(RelationshipProvider relationshipProvider) {
this.relationshipProvider = relationshipProvider;
}
/**
* Simple getter to return the provider that owns this validator.
*
* @return the provider that owns this validator.
*/
RelationshipProvider getRelationshipProvider() {
return relationshipProvider;
}
/**
* Return the readRequest which should succeed to indicate a valid relationship and return any content that
* will assist with further validation.
*
* @param relationshipField the field to validate.
* @return the request needed to test validity.
*/
abstract ReadRequest newValidateRequest(JsonValue relationshipField);
/**
* Implement to test the response provided from the read of the relationship.
*
* @param relationshipField The field that is being validated.
* @param response The contents will hold the response from the read call made on the relationship field.
* @throws BadRequestException if the response is invalid based on the implementation of the validator.
*/
abstract void validateSuccessfulReadResponse(JsonValue relationshipField, ResourceResponse response)
throws BadRequestException;
/**
* Validates that the relationshipField will not create an invalid condition.
* Does a read on the relationshipField.
*
* @param relationshipField the field to be validated.
* @param context context of the request working with the relationship.
* @throws ResourceException BadRequestException when the relationship is invalid, otherwise for other issues.
*/
final void validateRelationship(final JsonValue relationshipField, Context context)
throws ResourceException {
if (relationshipField.isCollection()) {
String message = format("''{0}'' is invalid as a relationship reference", relationshipField.asCollection());
logger.debug(message);
throw new BadRequestException(message);
}
try {
validateSuccessfulReadResponse(relationshipField, relationshipProvider.getConnection()
.read(context, newValidateRequest(relationshipField)));
} catch (NotFoundException e) {
String message = format("The referenced relationship ''{0}'' on ''{1}'', does not exist",
relationshipField.get(REFERENCE_ID).asString(), relationshipField.getPointer());
logger.debug(message);
throw new BadRequestException(message, e);
}
}
}