Created
July 23, 2008 13:15
-
-
Save darrinholst/1720 to your computer and use it in GitHub Desktop.
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
package your.domain.routing; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.servlet.http.HttpServletRequest; | |
import your.domain.handler.Handler; | |
public class FirstAvailableMatchRouter implements Router { | |
private List<Route> routes = new ArrayList<Route>(); | |
public void setRoutes( List<Route> routes ) { | |
this.routes.clear(); | |
this.routes.addAll( routes ); | |
} | |
public Handler route( HttpServletRequest request ) { | |
String uri = request.getRequestURI().replaceFirst( request.getContextPath() + "/", "" ); | |
for( Route route : routes ) { | |
if( route.matches( uri, request ) ) { | |
return route.getHandler(); | |
} | |
} | |
return Router.NOT_FOUND; | |
} | |
} |
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
package your.domain.routing; | |
import static org.easymock.EasyMock.*; | |
import static org.junit.Assert.*; | |
import java.util.Arrays; | |
import org.junit.Before; | |
import org.junit.Test; | |
import your.domain.WebTestCase; | |
import your.domain.rhigis.handler.Handler; | |
public class FirstAvailableMatchRouterTest extends WebTestCase { | |
private FirstAvailableMatchRouter router; | |
private Route route1; | |
private Route route2; | |
private Handler handler; | |
@Before | |
public void setup() { | |
route1 = mock( Route.class ); | |
route2 = mock( Route.class ); | |
handler = mock( Handler.class ); | |
router = new FirstAvailableMatchRouter(); | |
router.setRoutes( Arrays.asList( route1, route2 ) ); | |
} | |
@Test | |
public void testMatchFoundOnFirstRoute() throws Exception { | |
expect( request.getRequestURI() ).andReturn( "/context-root/some/uri" ); | |
expect( request.getContextPath() ).andReturn( "/context-root" ); | |
expect( route1.matches( "some/uri", request ) ).andReturn( true ); | |
expect( route1.getHandler() ).andReturn( handler ); | |
replayWebMocks(); | |
assertSame( handler, router.route( request ) ); | |
verifyWebMocks(); | |
} | |
@Test | |
public void testMatchFoundOnSecondRoute() throws Exception { | |
expect( request.getRequestURI() ).andReturn( "/context-root/some/uri" ); | |
expect( request.getContextPath() ).andReturn( "/context-root" ); | |
expect( route1.matches( "some/uri", request ) ).andReturn( false ); | |
expect( route2.matches( "some/uri", request ) ).andReturn( true ); | |
expect( route2.getHandler() ).andReturn( handler ); | |
replayWebMocks(); | |
assertSame( handler, router.route( request ) ); | |
verifyWebMocks(); | |
} | |
@Test | |
public void testNoMatchFound() throws Exception { | |
expect( request.getRequestURI() ).andReturn( "/context-root/some/uri" ); | |
expect( request.getContextPath() ).andReturn( "/context-root" ); | |
expect( route1.matches( "some/uri", request ) ).andReturn( false ); | |
expect( route2.matches( "some/uri", request ) ).andReturn( false ); | |
replayWebMocks(); | |
assertSame( Router.NOT_FOUND, router.route( request ) ); | |
verifyWebMocks(); | |
} | |
} | |
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
package your.domain.handler; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
public interface Handler { | |
void doGet( HttpServletRequest request, HttpServletResponse response ) throws Exception; | |
void doPost( HttpServletRequest request, HttpServletResponse response ) throws Exception; | |
void doPut( HttpServletRequest request, HttpServletResponse response ) throws Exception; | |
void doDelete( HttpServletRequest request, HttpServletResponse response ) throws Exception; | |
} |
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
package your.domain.routing; | |
import javax.servlet.http.HttpServletRequest; | |
import your.domain.handler.Handler; | |
public interface Route { | |
Handler getHandler(); | |
boolean matches( String uri, HttpServletRequest request ); | |
} |
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
package your.domain.routing; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import javax.servlet.http.HttpServletRequest; | |
import your.domain.handler.Handler; | |
public class RouteImpl implements Route { | |
private static final String VARIABLE = "\\{(.+?)\\}"; | |
private static final Pattern VARIABLE_PATTERN = Pattern.compile( VARIABLE ); | |
private Handler handler; | |
private Pattern uriTemplate; | |
private final List<String> variables = new ArrayList<String>(); | |
public RouteImpl() { | |
} | |
public RouteImpl( String uriTemplate, Handler handler ) { | |
setHandler( handler ); | |
setTemplate( uriTemplate ); | |
} | |
public void setTemplate( String uriTemplate ) { | |
this.uriTemplate = Pattern.compile( uriTemplate.replaceAll( VARIABLE, "(.+)" ) ); | |
Matcher m = VARIABLE_PATTERN.matcher( uriTemplate ); | |
while( m.find() ) { | |
variables.add( m.group( 1 ) ); | |
} | |
} | |
public void setHandler( Handler handler ) { | |
this.handler = handler; | |
} | |
public Handler getHandler() { | |
return handler; | |
} | |
public boolean matches( String uri, HttpServletRequest request ) { | |
final Matcher matcher = uriTemplate.matcher( uri ); | |
if( matcher.matches() ) { | |
for( int i = 0; i < variables.size(); i++ ) { | |
request.setAttribute( variables.get( i ), matcher.group( i + 1 ) ); | |
} | |
return true; | |
} | |
return false; | |
} | |
} |
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
package your.domain.routing; | |
import static org.junit.Assert.*; | |
import org.junit.Before; | |
import org.junit.Test; | |
import your.domain.WebTestCase; | |
import your.domain.rhigis.handler.Handler; | |
public class RouteImplTest extends WebTestCase { | |
private Handler handler; | |
@Before | |
public void setUp() { | |
super.setUp(); | |
handler = mock( Handler.class ); | |
} | |
@Test | |
public void testMatches() throws Exception { | |
replayWebMocks(); | |
assertTrue( new RouteImpl( "the/template", handler ).matches( "the/template", request ) ); | |
verifyWebMocks(); | |
} | |
@Test | |
public void testDoesNotMatch() throws Exception { | |
replayWebMocks(); | |
assertFalse( new RouteImpl( "the/template", handler ).matches( "the/other/template", request ) ); | |
verifyWebMocks(); | |
} | |
@Test | |
public void testMatchesWithVariable() throws Exception { | |
expectToSetRequestAttribute( "v1", "value" ); | |
replayWebMocks(); | |
assertTrue( new RouteImpl( "the/template/{v1}", handler ).matches( "the/template/value", request ) ); | |
verifyWebMocks(); | |
} | |
@Test | |
public void testMatchesWithTwoVariable() throws Exception { | |
expectToSetRequestAttribute( "v1", "value1" ); | |
expectToSetRequestAttribute( "v2", "value2" ); | |
replayWebMocks(); | |
assertTrue( new RouteImpl( "the/template/{v1}/and/{v2}", handler ).matches( "the/template/value1/and/value2", request ) ); | |
verifyWebMocks(); | |
} | |
@Test | |
public void testMatchesWithVariableAndStaticTextInTheSameNode() throws Exception { | |
expectToSetRequestAttribute( "policy-number", "12345" ); | |
replayWebMocks(); | |
assertTrue( new RouteImpl( "the/template/MP-{policy-number}", handler ).matches( "the/template/MP-12345", request ) ); | |
verifyWebMocks(); | |
} | |
@Test | |
public void testMatchesWithMultiplesOfVariableAndStaticTextInTheSameNode() throws Exception { | |
expectToSetRequestAttribute( "policy-symbol", "MP" ); | |
expectToSetRequestAttribute( "policy-number", "12345" ); | |
replayWebMocks(); | |
assertTrue( new RouteImpl( "the/template/{policy-symbol}-{policy-number}", handler ).matches( "the/template/MP-12345", request ) ); | |
verifyWebMocks(); | |
} | |
} |
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
package your.domain.routing; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import your.domain.handler.Handler; | |
public interface Router { | |
Handler NOT_FOUND = new Handler() { | |
public void doDelete( HttpServletRequest request, HttpServletResponse response ) throws Exception { | |
response.setStatus( HttpServletResponse.SC_NOT_FOUND ); | |
} | |
public void doGet( HttpServletRequest request, HttpServletResponse response ) throws Exception { | |
response.setStatus( HttpServletResponse.SC_NOT_FOUND ); | |
} | |
public void doPost( HttpServletRequest request, HttpServletResponse response ) throws Exception { | |
response.setStatus( HttpServletResponse.SC_NOT_FOUND ); | |
} | |
public void doPut( HttpServletRequest request, HttpServletResponse response ) throws Exception { | |
response.setStatus( HttpServletResponse.SC_NOT_FOUND ); | |
} | |
}; | |
Handler route( HttpServletRequest request ); | |
} |
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
<?xml version="1.0" encoding="UTF-8" ?> | |
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:p="http://www.springframework.org/schema/p" | |
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> | |
<bean id="router" class="your.domain.routing.FirstAvailableMatchRouter"> | |
<property name="routes"> | |
<list> | |
<bean | |
class="your.domain.routing.RouteImpl" | |
p:template="acres/crop/{crop-year}/{division}/{policy-symbol}-{policy-number}" | |
p:handler-ref="crop-acres-handler" /> | |
<bean | |
class="your.domain.routing.RouteImpl" | |
p:template="identify/high-risk/{x},{y}" | |
p:handler-ref="high-risk-identify-handler" /> | |
<bean | |
class="your.domain.routing.RouteImpl" | |
p:template="identify/storm-spottings/{x},{y}" | |
p:handler-ref="storm-spottings-identify-handler" /> | |
<bean | |
class="your.domain.routing.RouteImpl" | |
p:template="layer-filter/{layer}" | |
p:handler-ref="layer-filter-handler" /> | |
<bean | |
class="your.domain.routing.RouteImpl" | |
p:template="policy/{crop-year}/{division}/{policy-symbol}-{policy-number}/image" | |
p:handler-ref="policy-image-handler" /> | |
<bean | |
class="your.domain.routing.RouteImpl" | |
p:template="policy/{crop-year}/{division}/{policy-symbol}-{policy-number}/legend" | |
p:handler-ref="policy-legend-handler" /> | |
<bean | |
class="your.domain.routing.RouteImpl" | |
p:template="policy/{crop-year}/{division}/{policy-symbol}-{policy-number}" | |
p:handler-ref="policy-handler" /> | |
</list> | |
</property> | |
</bean> | |
<bean | |
id="crop-acres-handler" | |
class="your.domain.handler.CropAcresHandler" | |
parent="dao-factory-enabled" /> | |
<bean | |
id="high-risk-identify-handler" | |
class="your.domain.handler.HighRiskIdentifyHandler" | |
parent="dao-factory-enabled" | |
p:spatial-query-ref="spatial-query" /> | |
<bean | |
id="layer-filter-handler" | |
class="your.domain.handler.LayerFilterHandler" /> | |
<bean | |
id="policy-handler" | |
class="your.domain.handler.PolicyHandler" | |
parent="dao-factory-enabled" /> | |
<bean | |
id="policy-image-handler" | |
class="your.domain.handler.PolicyImageHandler" | |
p:mapFactory-ref="pocket-booklet-map-factory" /> | |
<bean | |
id="policy-legend-handler" | |
class="your.domain.handler.PolicyLegendHandler" | |
parent="dao-factory-enabled" /> | |
<bean | |
id="storm-spottings-identify-handler" | |
class="your.domain.handler.StormSpotterIdentifyHandler" | |
p:spatial-query-ref="spatial-query" | |
p:shape-factory-ref="storm-spotting-shape-factory" /> | |
</beans> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment