package fr.openwide.core.wicket.more.link.descriptor; import org.apache.wicket.markup.html.link.Link; import fr.openwide.core.wicket.more.link.descriptor.builder.LinkDescriptorBuilder; import fr.openwide.core.wicket.more.link.descriptor.builder.state.parameter.chosen.common.IChosenParameterState; import fr.openwide.core.wicket.more.link.descriptor.builder.state.parameter.mapping.IAddedParameterMappingState; import fr.openwide.core.wicket.more.link.descriptor.builder.state.validator.IValidatorState; import fr.openwide.core.wicket.more.link.descriptor.parameter.validator.LinkParameterValidationRuntimeException; /** * A {@link Link} whose parameters may change during the page life cycle (for instance on an Ajax refresh). * <p><strong>WARNING:</strong> if this link is rendered while its parameters are invalid, then a * {@link LinkParameterValidationRuntimeException} will be thrown when executing * {@link #onComponentTag(org.apache.wicket.markup.ComponentTag) onComponentTag}. Similarly, if the target is invalid, * then a {@link LinkInvalidTargetRuntimeException} will be thrown. * <br />By default, this should not happen as the link will be disabled unless it is completely valid. See * {@link #disableIfInvalid()} (the default), {@link #hideIfInvalid()} and {@link #throwExceptionIfInvalid()} for more * information. * @see LinkInvalidTargetRuntimeException * @see LinkParameterValidationRuntimeException * @see LinkDescriptorBuilder * @see IAddedParameterMappingState#mandatory() * @see IAddedParameterMappingState#optional() * @see IChosenParameterState#validator(fr.openwide.core.wicket.more.markup.html.factory.IDetachableFactory) * @see IChosenParameterState#validator(fr.openwide.core.wicket.more.link.descriptor.parameter.validator.factory.ILinkParameterValidatorFactory) * @see IValidatorState#validator(fr.openwide.core.wicket.more.link.descriptor.parameter.validator.ILinkParameterValidator) */ public abstract class AbstractDynamicBookmarkableLink extends Link<Void> { private static final long serialVersionUID = 1L; private static enum BehaviorIfInvalid { THROW_EXCEPTION { @Override protected void onConfigure(AbstractDynamicBookmarkableLink link) { link.setVisible(true); // If invalid, the exception will be thrown when rendering } }, HIDE { @Override protected void onConfigure(AbstractDynamicBookmarkableLink link) { link.setVisible(link.isValid()); } }, DISABLE { @Override protected void onConfigure(AbstractDynamicBookmarkableLink link) { link.setEnabled(link.isValid()); } }; protected abstract void onConfigure(AbstractDynamicBookmarkableLink link); } private BehaviorIfInvalid behaviorIfInvalid = BehaviorIfInvalid.DISABLE; private boolean absolute = false; public AbstractDynamicBookmarkableLink(String wicketId) { super(wicketId); } /** * @deprecated Use {@link #hideIfInvalid()} instead. */ @Deprecated public AbstractDynamicBookmarkableLink setAutoHideIfInvalid(boolean autoHideIfInvalid) { if (autoHideIfInvalid) { hideIfInvalid(); } else { this.behaviorIfInvalid = BehaviorIfInvalid.THROW_EXCEPTION; } return this; } /** * Sets the link up so that it will automatically hide (using {@link #setVisible(boolean)}) when its target or parameters are invalid. * <p>Default behavior is to automatically disable the link. */ public AbstractDynamicBookmarkableLink hideIfInvalid() { this.behaviorIfInvalid = BehaviorIfInvalid.HIDE; return this; } /** * Sets the link up so that it will automatically be disabled when its target or parameters are invalid. * @deprecated This is the default behavior, so calling this method is generally useless. The method is here for * compatibility reasons. */ @Deprecated public AbstractDynamicBookmarkableLink disableIfInvalid() { this.behaviorIfInvalid = BehaviorIfInvalid.DISABLE; return this; } /** * Sets the link up so that it will throw a {@link LinkInvalidTargetRuntimeException} or a {@link LinkParameterValidationRuntimeException} * if the target or the parameters are found to be invalid when executing {@link #onComponentTag(org.apache.wicket.markup.ComponentTag)}. * <p>Default behavior is to automatically disable the link. */ public AbstractDynamicBookmarkableLink throwExceptionIfInvalid() { this.behaviorIfInvalid = BehaviorIfInvalid.THROW_EXCEPTION; return this; } public boolean isAbsolute() { return absolute; } /** * Sets whether the link should be absolute or relative. * <p> Default is false: the link is relative by default. * * @param absolute True to make the link absolute. */ public AbstractDynamicBookmarkableLink setAbsolute(boolean absolute) { this.absolute = absolute; return this; } protected abstract boolean isValid(); @Override protected void onConfigure() { super.onConfigure(); behaviorIfInvalid.onConfigure(this); } @Override protected final CharSequence getURL() throws LinkInvalidTargetRuntimeException, LinkParameterValidationRuntimeException { if (isAbsolute()) { return getAbsoluteURL(); } else { return getRelativeURL(); } } protected abstract CharSequence getRelativeURL() throws LinkInvalidTargetRuntimeException, LinkParameterValidationRuntimeException; protected abstract CharSequence getAbsoluteURL() throws LinkInvalidTargetRuntimeException, LinkParameterValidationRuntimeException; @Override protected boolean getStatelessHint() { return true; } /** * No click event is allowed. */ @Override public final void onClick() { // Unused } }