Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add AsDomainNameStringValidator and BaseAsValidator
Showing
5 changed files
with
307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
src/main/java/uk/org/iay/incommon/mda/validate/BaseAsValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
/* | ||
* Licensed 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 uk.org.iay.incommon.mda.validate; | ||
|
||
import java.util.List; | ||
|
||
import javax.annotation.Nonnull; | ||
|
||
import net.shibboleth.metadata.Item; | ||
import net.shibboleth.metadata.pipeline.StageProcessingException; | ||
import net.shibboleth.metadata.validate.Validator; | ||
import net.shibboleth.utilities.java.support.component.ComponentInitializationException; | ||
|
||
/** | ||
* An abstract base class for {@link Validator} implementations which validate a value of | ||
* one type "as" another type. | ||
* | ||
* <p>The implementation calls a template method in the implementation subclass to perform the | ||
* conversion. If the conversion succeeds, a sequence of {@link Validator}s are applied to | ||
* that new value.</p> | ||
* | ||
* <p>If the value cannot be converted to the new type, the template method is expected to | ||
* throw {@link IllegalArgumentException}. In this case, behaviour depends on the | ||
* {@link #conversionRequired} property.</p> | ||
* | ||
* <p>If {@link #conversionRequired} is <code>true</code> (the default) then an error | ||
* status will be applied to the {@link Item}, and the validator will return | ||
* {@link net.shibboleth.metadata.validate.Validator.Action#DONE}.</p> | ||
* | ||
* <p>If {@link #conversionRequired} is <code>false</code> then the validator | ||
* will simply return {@link net.shibboleth.metadata.validate.Validator.Action#CONTINUE} | ||
* so that subsequent validators may still be applied. This allows several "as" validators | ||
* to be applied in sequence, each taking a different approach.</p> | ||
* | ||
* @param <V> type of the original value | ||
* @param <A> type of the new value to which validators should be applied | ||
*/ | ||
public abstract class BaseAsValidator<V, A> extends BaseLocalValidator implements Validator<V> { | ||
|
||
/** The validator sequence to apply. */ | ||
@Nonnull | ||
private ValidatorSequence<A> validators = new ValidatorSequence<>(); | ||
|
||
/** Whether conversion to the new type must succeed. Default: <code>true</code> */ | ||
private boolean conversionRequired = true; | ||
|
||
/** | ||
* Set the list of validators to apply to each item. | ||
* | ||
* @param newValidators the list of validators to set | ||
*/ | ||
public void setValidators(@Nonnull final List<Validator<A>> newValidators) { | ||
validators.setValidators(newValidators); | ||
} | ||
|
||
/** | ||
* Gets the list of validators being applied to each item. | ||
* | ||
* @return list of validators | ||
*/ | ||
@Nonnull | ||
public List<Validator<A>> getValidators() { | ||
return validators.getValidators(); | ||
} | ||
|
||
/** | ||
* Set whether conversion to the new type is required to succeed. | ||
* | ||
* @param required <code>true</code> if the conversion is required to succeed | ||
*/ | ||
public void setConversionRequired(final boolean required) { | ||
conversionRequired = required; | ||
} | ||
|
||
/** | ||
* Returns whether conversion to the new type is required to succeed. | ||
* | ||
* @return <code>true</code> if the conversion is required to succeed | ||
*/ | ||
public boolean isConversionRequired() { | ||
return conversionRequired; | ||
} | ||
|
||
/** | ||
* Apply each of the configured validators in turn to the provided object. | ||
* | ||
* @param value object to be validated | ||
* @param item the {@link Item} context for the validation | ||
* | ||
* @return the result of applying the validators to the value | ||
* | ||
* @throws StageProcessingException if errors occur during processing | ||
*/ | ||
protected Action applyValidators(@Nonnull final A value, @Nonnull final Item<?> item) | ||
throws StageProcessingException { | ||
return validators.validate(value, item, getId()); | ||
} | ||
|
||
/** | ||
* Convert from the old value type to the new. | ||
* | ||
* @param from a value of the old type | ||
* @return a value of the new type | ||
* @throws IllegalArgumentException if a conversion can not be performed | ||
*/ | ||
protected abstract A convert(@Nonnull final V from) throws IllegalArgumentException; | ||
|
||
@Override | ||
public Action validate(@Nonnull final V t, @Nonnull final Item<?> item, @Nonnull final String stageId) | ||
throws StageProcessingException { | ||
try { | ||
final A v = convert(t); | ||
return applyValidators(v, item); | ||
} catch (final IllegalArgumentException e) { | ||
if (isConversionRequired()) { | ||
addErrorMessage(t, item, stageId); | ||
return Action.DONE; | ||
} else { | ||
return Action.CONTINUE; | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
protected void doDestroy() { | ||
validators.destroy(); | ||
validators = null; | ||
super.doDestroy(); | ||
} | ||
|
||
@Override | ||
protected void doInitialize() throws ComponentInitializationException { | ||
super.doInitialize(); | ||
validators.setId(getId()); | ||
validators.initialize(); | ||
} | ||
|
||
} |
42 changes: 42 additions & 0 deletions
42
src/main/java/uk/org/iay/incommon/mda/validate/string/AsDomainNameStringValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Licensed 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 uk.org.iay.incommon.mda.validate.string; | ||
|
||
import javax.annotation.Nonnull; | ||
|
||
import com.google.common.net.InternetDomainName; | ||
|
||
import net.shibboleth.metadata.validate.Validator; | ||
import uk.org.iay.incommon.mda.validate.BaseAsValidator; | ||
|
||
/** | ||
* A <code>Validator</code> that checks {@link String} values as domain names by converting the | ||
* value to an {@link InternetDomainName} and applying a sequence of validators to that value. | ||
* | ||
* This validator fails (and returns {@link net.shibboleth.metadata.validate.Validator.Action#DONE}) if the | ||
* value can not be converted to an {@link InternetDomainName}. | ||
* | ||
* Otherwise, the validator applies the sequence of validators to the {@link InternetDomainName} and returns | ||
* the value of that sequence. | ||
*/ | ||
public class AsDomainNameStringValidator extends BaseAsValidator<String, InternetDomainName> | ||
implements Validator<String> { | ||
|
||
@Override | ||
protected InternetDomainName convert(@Nonnull final String domain) throws IllegalArgumentException { | ||
return InternetDomainName.from(domain); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
src/test/java/uk/org/iay/incommon/mda/validate/string/AsDomainNameStringValidatorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
|
||
package uk.org.iay.incommon.mda.validate.string; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.testng.Assert; | ||
import org.testng.annotations.Test; | ||
|
||
import com.google.common.net.InternetDomainName; | ||
|
||
import net.shibboleth.metadata.ErrorStatus; | ||
import net.shibboleth.metadata.Item; | ||
import net.shibboleth.metadata.pipeline.StageProcessingException; | ||
import net.shibboleth.metadata.validate.Validator; | ||
import net.shibboleth.metadata.validate.Validator.Action; | ||
import uk.org.iay.incommon.mda.validate.BaseLocalValidator; | ||
import uk.org.ukfederation.mda.MockItem; | ||
|
||
public class AsDomainNameStringValidatorTest { | ||
|
||
private static class CountingValidator extends BaseLocalValidator implements Validator<InternetDomainName> { | ||
public int count; | ||
private final Action action; | ||
|
||
@Override | ||
public Action validate(InternetDomainName e, Item<?> item, String stageId) throws StageProcessingException { | ||
count++; | ||
return action; | ||
} | ||
|
||
/** Constructor. */ | ||
public CountingValidator(final Action a) { | ||
action = a; | ||
} | ||
} | ||
|
||
@Test | ||
public void testOK() throws Exception { | ||
final CountingValidator counter = new CountingValidator(Action.CONTINUE); | ||
counter.setId("counter"); | ||
counter.initialize(); | ||
|
||
final List<Validator<InternetDomainName>> nestedSequence = new ArrayList<>(); | ||
nestedSequence.add(counter); | ||
|
||
final Item<String> item = new MockItem("content"); | ||
|
||
final AsDomainNameStringValidator val = new AsDomainNameStringValidator(); | ||
val.setId("id"); | ||
val.setValidators(nestedSequence); | ||
val.initialize(); | ||
|
||
final Action res = val.validate("example.org", item, "stage"); | ||
Assert.assertEquals(res, Action.CONTINUE); | ||
Assert.assertEquals(item.getItemMetadata().get(ErrorStatus.class).size(), 0); | ||
Assert.assertEquals(counter.count, 1); | ||
} | ||
|
||
@Test | ||
public void testNoConvertDefault() throws Exception { | ||
final CountingValidator counter = new CountingValidator(Action.CONTINUE); | ||
counter.setId("counter"); | ||
counter.initialize(); | ||
|
||
final List<Validator<InternetDomainName>> nestedSequence = new ArrayList<>(); | ||
nestedSequence.add(counter); | ||
|
||
final Item<String> item = new MockItem("content"); | ||
|
||
final AsDomainNameStringValidator val = new AsDomainNameStringValidator(); | ||
val.setId("id"); | ||
val.setValidators(nestedSequence); | ||
val.setMessage("quick brown %s"); | ||
val.initialize(); | ||
|
||
final Action res = val.validate("example**.org", item, "stage"); | ||
Assert.assertEquals(res, Action.DONE); | ||
Assert.assertEquals(item.getItemMetadata().get(ErrorStatus.class).size(), 1); | ||
final ErrorStatus err = item.getItemMetadata().get(ErrorStatus.class).get(0); | ||
Assert.assertTrue(err.getStatusMessage().contains("quick brown example**.org")); | ||
Assert.assertEquals(counter.count, 0); | ||
} | ||
|
||
@Test | ||
public void testNoConvertFalse() throws Exception { | ||
final CountingValidator counter = new CountingValidator(Action.CONTINUE); | ||
counter.setId("counter"); | ||
counter.initialize(); | ||
|
||
final List<Validator<InternetDomainName>> nestedSequence = new ArrayList<>(); | ||
nestedSequence.add(counter); | ||
|
||
final Item<String> item = new MockItem("content"); | ||
|
||
final AsDomainNameStringValidator val = new AsDomainNameStringValidator(); | ||
val.setId("id"); | ||
val.setConversionRequired(false); | ||
val.setValidators(nestedSequence); | ||
val.initialize(); | ||
|
||
final Action res = val.validate("example**.org", item, "stage"); | ||
Assert.assertEquals(res, Action.CONTINUE); | ||
Assert.assertEquals(item.getItemMetadata().get(ErrorStatus.class).size(), 0); | ||
Assert.assertEquals(counter.count, 0); | ||
} | ||
|
||
} |