com.ocpsoft.rewrite.servlet.config.rule.Join Maven / Gradle / Ivy
/*
* Copyright 2011 Lincoln Baxter, III
*
* 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 com.ocpsoft.rewrite.servlet.config.rule;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.ocpsoft.rewrite.bind.Binding;
import com.ocpsoft.rewrite.bind.RegexParameter;
import com.ocpsoft.rewrite.config.Condition;
import com.ocpsoft.rewrite.config.ConditionBuilder;
import com.ocpsoft.rewrite.config.Operation;
import com.ocpsoft.rewrite.config.Rule;
import com.ocpsoft.rewrite.context.EvaluationContext;
import com.ocpsoft.rewrite.event.Rewrite;
import com.ocpsoft.rewrite.param.Parameter;
import com.ocpsoft.rewrite.param.Parameterized;
import com.ocpsoft.rewrite.servlet.config.DispatchType;
import com.ocpsoft.rewrite.servlet.config.Forward;
import com.ocpsoft.rewrite.servlet.config.Path;
import com.ocpsoft.rewrite.servlet.config.QueryString;
import com.ocpsoft.rewrite.servlet.config.Redirect;
import com.ocpsoft.rewrite.servlet.config.Substitute;
import com.ocpsoft.rewrite.servlet.config.rule.Join.JoinParameterBuilder;
import com.ocpsoft.rewrite.servlet.http.event.HttpInboundServletRewrite;
import com.ocpsoft.rewrite.servlet.http.event.HttpOutboundServletRewrite;
import com.ocpsoft.rewrite.servlet.util.QueryStringBuilder;
/**
* {@link Rule} that creates a bi-directional rewrite rule between an externally facing URL and an internal server
* resource URL
*
* @author Lincoln Baxter, III
*/
public class Join implements Rule, Parameterized
{
private static final String CURRENT_JOIN = Join.class.getName() + "_current";
private String id;
private final String pattern;
private String resource;
private Path resourcePath;
private final Path path;
private Operation operation;
private Condition condition;
private boolean inboundCorrection = false;
protected Join(final String pattern)
{
this.pattern = pattern;
this.path = Path.matches(pattern);
}
/**
* The outward facing URL path to which this {@link Join} will apply.
*/
public static Join path(final String pattern)
{
return new Join(pattern);
}
/**
* The internal server resource (real or virtual) to be served.
*/
public Join to(final String resource)
{
this.resource = resource;
this.resourcePath = Path.matches(resource);
return this;
}
/**
* Redirect inbound requests for the internal resource to the outward facing URL instead.
*/
public Join withInboundCorrection()
{
this.inboundCorrection = true;
return this;
}
@Override
public boolean evaluate(final Rewrite event, final EvaluationContext context)
{
if (event instanceof HttpInboundServletRewrite)
{
path.withRequestBinding();
if (path.evaluate(event, context) && ((condition == null) || condition.evaluate(event, context)))
{
if (operation != null)
context.addPreOperation(operation);
return true;
}
else if (inboundCorrection
&& resourcePath.andNot(DispatchType.isForward()).evaluate(event, context)
&& ((condition == null) || condition.evaluate(event, context)))
{
List names = path.getPathExpression().getParameterNames();
for (String name : names) {
if (!QueryString.parameterExists(name).evaluate(event, context))
{
return false;
}
}
context.addPreOperation(Redirect.permanent(((HttpInboundServletRewrite) event).getContextPath()
+ pattern));
return true;
}
}
else if ((event instanceof HttpOutboundServletRewrite))
{
List parameters = getPathRequestParameters();
ConditionBuilder outbound = resourcePath;
for (String name : parameters)
{
outbound = outbound.and(QueryString.parameterExists(name));
}
if (outbound.evaluate(event, context) && ((condition == null) || condition.evaluate(event, context)))
{
if (operation != null)
context.addPreOperation(operation);
return true;
}
}
return false;
}
private List getPathRequestParameters()
{
List nonQueryParameters = resourcePath.getPathExpression().getParameterNames();
List queryParameters = path.getPathExpression().getParameterNames();
queryParameters.removeAll(nonQueryParameters);
return queryParameters;
}
@Override
public void perform(final Rewrite event, final EvaluationContext context)
{
if (event instanceof HttpInboundServletRewrite)
{
saveCurrentJoin(((HttpInboundServletRewrite) event).getRequest());
Forward.to(resource).perform(event, context);
}
else if (event instanceof HttpOutboundServletRewrite)
{
List parameters = getPathRequestParameters();
String outboundURL = ((HttpOutboundServletRewrite) event).getOutboundURL();
QueryStringBuilder query = QueryStringBuilder.begin();
if (outboundURL.contains("?"))
{
query.addParameters(outboundURL);
for (String string : parameters) {
List values = query.removeParameter(string);
if (values.size() > 1)
{
query.addParameter(string, values.subList(1, values.size()).toArray(new String[] {}));
}
}
}
Substitute.with(pattern + query.toQueryString()).perform(event, context);
}
}
private void saveCurrentJoin(final HttpServletRequest request)
{
request.setAttribute(CURRENT_JOIN, this);
}
/**
* Retrieve the {@link Join} that was invoked on the current request; if no {@link Join} was invoked, return null.
*/
public static Join getCurrentJoin(final HttpServletRequest request)
{
return (Join) request.getAttribute(CURRENT_JOIN);
}
@Override
public JoinParameterBuilder where(final String parameter)
{
return new JoinParameterBuilder(this, path.getPathExpression().getParameter(parameter));
}
@Override
public JoinParameterBuilder where(final String param, final String pattern)
{
return where(param).matches(pattern);
}
@Override
public JoinParameterBuilder where(final String param, final String pattern, final Binding binding)
{
return where(param, pattern).bindsTo(binding);
}
@Override
public JoinParameterBuilder where(final String param, final Binding binding)
{
return where(param).bindsTo(binding);
}
@Override
public String getId()
{
return id;
}
public Join when(final Condition condition)
{
this.condition = condition;
return this;
}
public Join perform(final Operation operation)
{
this.operation = operation;
return this;
}
/**
* Set the ID of this {@link Join}.
*/
public Join withId(final String id)
{
this.id = id;
return this;
}
/**
* Builder for {@link Join} specific {@link Parameter}
*
* @author Lincoln Baxter, III
*
*/
public class JoinParameterBuilder implements Parameterized, Rule
{
private final Join parent;
private final RegexParameter parameter;
public JoinParameterBuilder(final Join link, final RegexParameter parameter)
{
this.parent = link;
this.parameter = parameter;
}
public Join to(final String resource)
{
return parent.to(resource);
}
public JoinParameterBuilder matches(final String pattern)
{
parameter.matches(pattern);
return this;
}
public JoinParameterBuilder bindsTo(final Binding binding)
{
parameter.bindsTo(binding);
return this;
}
@Override
public JoinParameterBuilder where(final String param)
{
return parent.where(param);
}
@Override
public JoinParameterBuilder where(final String param, final String pattern)
{
return parent.where(param, pattern);
}
@Override
public JoinParameterBuilder where(final String param, final String pattern, final Binding binding)
{
return parent.where(param, pattern, binding);
}
@Override
public JoinParameterBuilder where(final String param, final Binding binding)
{
return parent.where(param, binding);
}
public Join when(final Condition condition)
{
return parent.when(condition);
}
public Join perform(final Operation operation)
{
return parent.perform(operation);
}
@Override
public String getId()
{
return parent.getId();
}
@Override
public boolean evaluate(final Rewrite event, final EvaluationContext context)
{
return parent.evaluate(event, context);
}
@Override
public void perform(final Rewrite event, final EvaluationContext context)
{
parent.perform(event, context);
}
}
@Override
public String toString()
{
return "Join [url=" + pattern + ", to=" + resource + ", id=" + id + ", inboundCorrection="
+ inboundCorrection + "]";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy