package fr.openwide.core.wicket.more.link.descriptor.impl;
import java.util.Collection;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.Session;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.core.request.handler.PageProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.flow.RedirectToUrlException;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.lang.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import fr.openwide.core.spring.util.StringUtils;
import fr.openwide.core.wicket.more.link.descriptor.AbstractDynamicBookmarkableLink;
import fr.openwide.core.wicket.more.link.descriptor.IPageLinkDescriptor;
import fr.openwide.core.wicket.more.link.descriptor.LinkInvalidTargetRuntimeException;
import fr.openwide.core.wicket.more.link.descriptor.generator.ILinkGenerator;
import fr.openwide.core.wicket.more.link.descriptor.generator.IPageLinkGenerator;
import fr.openwide.core.wicket.more.link.descriptor.parameter.extractor.IPageLinkParametersExtractor;
import fr.openwide.core.wicket.more.link.descriptor.parameter.injector.LinkParameterInjectionRuntimeException;
import fr.openwide.core.wicket.more.link.descriptor.parameter.mapping.LinkParametersMapping;
import fr.openwide.core.wicket.more.link.descriptor.parameter.validator.ILinkParameterValidator;
import fr.openwide.core.wicket.more.link.descriptor.parameter.validator.LinkParameterModelValidationException;
import fr.openwide.core.wicket.more.link.descriptor.parameter.validator.LinkParameterSerializedFormValidationException;
import fr.openwide.core.wicket.more.link.descriptor.parameter.validator.LinkParameterValidationRuntimeException;
import fr.openwide.core.wicket.more.markup.html.template.model.NavigationMenuItem;
import fr.openwide.core.wicket.more.util.model.Models;
public class CorePageLinkDescriptorImpl extends AbstractCoreExplicitelyParameterizedLinkDescriptor implements IPageLinkDescriptor {
private static final long serialVersionUID = -9139677593653180236L;
private static final Logger EXTRACTOR_INTERFACE_LOGGER = LoggerFactory.getLogger(IPageLinkParametersExtractor.class);
private static final String ANCHOR_ROOT = "#";
private final IModel<? extends Class<? extends Page>> pageClassModel;
private boolean bypassPermissions = false;
public CorePageLinkDescriptorImpl(
IModel<? extends Class<? extends Page>> pageClassModel,
LinkParametersMapping parametersMapping,
ILinkParameterValidator validator) {
super(parametersMapping, validator);
Args.notNull(pageClassModel, "pageClassModel");
this.pageClassModel = pageClassModel;
}
protected Class<? extends Page> getValidPageClass() throws LinkInvalidTargetRuntimeException {
Class<? extends Page> pageClass = pageClassModel.getObject();
if (pageClass == null) {
throw new LinkInvalidTargetRuntimeException("The target page of this ILinkDescriptor was null");
}
if (! bypassPermissions) {
if (!Session.get().getAuthorizationStrategy().isInstantiationAuthorized(pageClass)) {
throw new LinkInvalidTargetRuntimeException("The instantiation of the target page class '" + pageClass
+ "' was not authorized when trying to render the URL.");
}
}
return pageClass;
}
@Override
public AbstractDynamicBookmarkableLink link(String wicketId) {
return new DynamicBookmarkablePageLink(wicketId, this);
}
@Override
public AbstractDynamicBookmarkableLink link(String wicketId, String anchor) {
AbstractDynamicBookmarkableLink link = link(wicketId);
link.add(new AttributeAppender("href", ANCHOR_ROOT + anchor));
return link;
}
@Override
public void extractSafely(PageParameters parameters, IPageLinkGenerator fallbackLink) throws RestartResponseException {
extractSafely(parameters, fallbackLink, null);
}
@Override
public void extractSafely(PageParameters parameters, IPageLinkGenerator fallbackLink, String errorMessage)
throws RestartResponseException {
try {
extract(parameters);
} catch (RuntimeException | LinkParameterSerializedFormValidationException |
LinkParameterModelValidationException e) {
EXTRACTOR_INTERFACE_LOGGER.error("Error while extracting page parameters", e);
if (StringUtils.hasText(errorMessage)) {
Session.get().error(errorMessage);
}
throw fallbackLink.newRestartResponseException();
}
}
@Override
public String url() throws LinkInvalidTargetRuntimeException, LinkParameterInjectionRuntimeException,
LinkParameterValidationRuntimeException {
return url(RequestCycle.get());
}
@Override
public String url(RequestCycle requestCycle) throws LinkInvalidTargetRuntimeException,
LinkParameterInjectionRuntimeException, LinkParameterValidationRuntimeException {
Class<? extends Page> pageClass = getValidPageClass();
PageParameters parameters = getValidatedParameters();
return requestCycle.urlFor(pageClass, parameters).toString();
}
@Override
public IPageLinkDescriptor wrap(Component component) {
return new CorePageLinkDescriptorImpl(
Models.wrap(pageClassModel, component),
parametersMapping.wrapOnAssignment(component),
parametersValidator
);
}
@Override
public void setResponsePage() throws LinkParameterValidationRuntimeException {
Class<? extends Page> pageClass = getValidPageClass();
PageParameters parameters = getValidatedParameters();
RequestCycle.get().setResponsePage(pageClass, parameters);
}
@Override
public RestartResponseException newRestartResponseException() throws LinkParameterValidationRuntimeException {
Class<? extends Page> pageClass = getValidPageClass();
PageParameters parameters = getValidatedParameters();
return new RestartResponseException(pageClass, parameters);
}
@Override
public RestartResponseAtInterceptPageException newRestartResponseAtInterceptPageException() throws LinkParameterValidationRuntimeException {
Class<? extends Page> pageClass = getValidPageClass();
PageParameters parameters = getValidatedParameters();
return new RestartResponseAtInterceptPageException(pageClass, parameters);
}
@Override
public RedirectToUrlException newRedirectToUrlException() throws LinkParameterValidationRuntimeException {
return new RedirectToUrlException(fullUrl());
}
@Override
public RedirectToUrlException newRedirectToUrlException(String anchor)
throws LinkParameterValidationRuntimeException, LinkParameterInjectionRuntimeException {
return new RedirectToUrlException(fullUrl() + ANCHOR_ROOT + anchor);
}
@Override
public NavigationMenuItem navigationMenuItem(IModel<String> labelModel) throws LinkParameterValidationRuntimeException {
return navigationMenuItem(labelModel, Lists.<NavigationMenuItem>newArrayListWithExpectedSize(0));
}
@Override
public NavigationMenuItem navigationMenuItem(IModel<String> labelModel, Collection<NavigationMenuItem> subMenuItems)
throws LinkParameterValidationRuntimeException {
return new NavigationMenuItem(labelModel, this, subMenuItems);
}
@Override
public boolean isAccessible() {
Class<? extends Page> pageClass = pageClassModel.getObject();
return pageClass != null && Session.get().getAuthorizationStrategy().isInstantiationAuthorized(pageClass)
&& super.isAccessible();
}
@Override
public ILinkGenerator chain(ILinkGenerator other) {
if (other instanceof IPageLinkGenerator) {
return chain((IPageLinkGenerator) other);
}
return new ChainedLinkGeneratorImpl(ImmutableList.of(this, other));
}
@Override
public IPageLinkGenerator chain(IPageLinkGenerator other) {
return new ChainedPageLinkGeneratorImpl(ImmutableList.of(this, other));
}
@Override
public boolean isActive(Class<? extends Page> selectedPage) {
Class<? extends Page> pageClass = pageClassModel.getObject();
if (pageClass == null) {
return false;
} else {
return pageClass.equals(selectedPage);
}
}
@Override
public void detach() {
super.detach();
pageClassModel.detach();
}
@Override
public void checkModelsSafely(IPageLinkGenerator fallbackLink) {
checkModelsSafely(fallbackLink, null);
}
@Override
public void checkModelsSafely(IPageLinkGenerator fallbackLink, String errorMessage) {
try {
checkModels();
} catch (RuntimeException | LinkParameterModelValidationException e) {
EXTRACTOR_INTERFACE_LOGGER.error("Error while extracting page parameters", e);
if (StringUtils.hasText(errorMessage)) {
Session.get().error(errorMessage);
}
throw fallbackLink.newRestartResponseException();
}
}
@Override
public PageProvider newPageProvider() {
return new PageProvider(getValidPageClass(), getValidatedParameters());
}
/**
* @see IPageLinkGenerator#bypassPermissions()
*/
@Deprecated
@Override
public IPageLinkGenerator bypassPermissions() {
bypassPermissions = true;
return this;
}
}