/**
* Copyright (C) 2010 Asterios Raptis
*
* 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 de.alpharogroup.wicket.base.request.mapper;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.IRequestMapper;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Url;
import org.apache.wicket.request.mapper.CompoundRequestMapper;
import org.apache.wicket.util.lang.Args;
/**
* Compound {@link IRequestMapper} with request mappers, orders by the compatibility score they were
* added.
*
* For instance:
*
* <pre>
* public class WicketApplication extends WebApplication
* {
* ..
* public void init()
* {
* ...
* // install crypto mapper to encrypt all application urls
* getSecuritySettings().setCryptFactory(new KeyInSessionSunJceCryptFactory());
* setRootRequestMapper(new HighScoreRequestMapper().register(new CryptoMapper(getRootRequestMapper(), this)));
* ...
* }
* ...
* }
* </pre>
*/
public class HighScoreRequestMapper extends CompoundRequestMapper
{
/** The request mappers. */
private List<IRequestMapper> requestMappers = new CopyOnWriteArrayList<>();
/** The comparator. */
private Comparator<RequestMapperBean> comparator;
/**
* Instantiates a new {@link HighScoreRequestMapper}.
*/
public HighScoreRequestMapper()
{
}
/**
* Instantiates a new {@link HighScoreRequestMapper}.
*
* @param requestMappers
* the request mappers
*/
public HighScoreRequestMapper(final List<IRequestMapper> requestMappers)
{
this.requestMappers = Args.notNull(requestMappers, "requestMappers");
}
/**
* Gets the Comparator for this SortedProperties.
*
* @return The Comparator.
*/
private Comparator<RequestMapperBean> getComparator()
{
if (this.comparator == null)
{
this.comparator = newComparator();
}
return this.comparator;
}
/**
* {@inheritDoc}
*/
@Override
public int getCompatibilityScore(final Request request)
{
int score = Integer.MIN_VALUE;
for (final IRequestMapper requestMapper : this.requestMappers)
{
score = Math.max(score, requestMapper.getCompatibilityScore(request));
}
return score;
}
/**
* Initialize request mappers.
*
* @param request
* the request
* @return the collection
*/
private Collection<RequestMapperBean> initializeRequestMappers(final Request request)
{
final Set<RequestMapperBean> mapperBeans = new TreeSet<>(getComparator());
for (final IRequestMapper requestMapper : this.requestMappers)
{
mapperBeans.add(
new RequestMapperBean(requestMapper, requestMapper.getCompatibilityScore(request)));
}
return mapperBeans;
}
/**
* {@inheritDoc}
*/
@Override
public Url mapHandler(final IRequestHandler handler)
{
for (final IRequestMapper requestMapper : this.requestMappers)
{
final Url url = requestMapper.mapHandler(handler);
if (url != null)
{
return url;
}
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public IRequestHandler mapRequest(final Request request)
{
for (final RequestMapperBean mapperBean : initializeRequestMappers(request))
{
final IRequestHandler handler = mapperBean.getMapper().mapRequest(request);
if (handler != null)
{
return handler;
}
}
return null;
}
/**
* Factory method for creating a new Comparator for sort the compatibility score. This method is
* invoked in the method initializeRequestMappers and can be overridden so users can provide
* their own version of a Comparator.
*
* @return the new Comparator.
*/
protected Comparator<RequestMapperBean> newComparator()
{
return new Comparator<RequestMapperBean>()
{
@Override
public int compare(final RequestMapperBean o1, final RequestMapperBean o2)
{
return o1.getCompatibilityScore() - o2.getCompatibilityScore();
}
};
}
/**
* Register.
*
* @param encoder
* the encoder
* @return the high score request mapper
*/
public HighScoreRequestMapper register(final IRequestMapper encoder)
{
this.requestMappers.add(0, encoder);
return this;
}
/**
* Unregister.
*
* @param encoder
* the encoder
* @return the high score request mapper
*/
public HighScoreRequestMapper unregister(final IRequestMapper encoder)
{
this.requestMappers.remove(encoder);
return this;
}
}