Skip to content

Commit

Permalink
Refactoring to support reverse variable matching for issue #2
Browse files Browse the repository at this point in the history
  • Loading branch information
damnhandy committed Aug 4, 2013
1 parent 2b403b1 commit 33c81a7
Show file tree
Hide file tree
Showing 14 changed files with 366 additions and 63 deletions.
54 changes: 40 additions & 14 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.oss</groupId>
Expand Down Expand Up @@ -173,6 +174,25 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
<dependencies>
<dependency>
<groupId>lt.velykis.maven.skins</groupId>
<artifactId>reflow-velocity-tools</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Reflow skin requires Velocity >= 1.7 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<!-- Markdown support for writing website content -->
<groupId>org.apache.maven.doxia</groupId>
<artifactId>doxia-module-markdown</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
<configuration>

<reportPlugins>
Expand Down Expand Up @@ -245,8 +265,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>

Expand Down Expand Up @@ -287,7 +307,7 @@
<version>2.9.1</version>
<configuration>
<aggregate>true</aggregate>
<source>1.6</source>
<source>1.7</source>
<encoding>UTF-8</encoding>
<maxmemory>1g</maxmemory>
<links>
Expand Down Expand Up @@ -383,36 +403,36 @@
<version>4.11</version>
<scope>test</scope>
</dependency>


<!-- JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>14.0.1</version>
<scope>test</scope>
</dependency>

<!-- Async HTTP Client -->
<dependency>
Expand All @@ -427,6 +447,12 @@
<version>4.2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.abdera</groupId>
<artifactId>abdera-i18n</artifactId>
<version>1.1.3</version>
<type>bundle</type>
</dependency>
</dependencies>


Expand Down
62 changes: 50 additions & 12 deletions src/main/java/com/damnhandy/uri/template/Expression.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public class Expression extends UriTemplateComponent
*/
private static final Pattern VARNAME_REGEX = Pattern.compile("([\\w\\_\\.]|%[A-Fa-f0-9]{2})+");
/**
* A regex quoted string that matches the expression. For example:
* A regex quoted string that matches the expression for replacement in the
* expansion process. For example:
* <pre>
* \Q{?query,number}\E
* </pre>
Expand All @@ -69,12 +70,20 @@ public class Expression extends UriTemplateComponent
*/
private Operator op;


/**
* The character position where this expression occurs in the URI template
*/
private final int location;
/**
* The the parsed {@link VarSpec} instances found in the expression.
*/
private List<VarSpec> varSpecs;

/**
* The Patter that would be used to reverse match this expression
*/
private Pattern matchPattern;


/**
* Creates a new {@link Builder} to create a simple expression according
Expand Down Expand Up @@ -255,10 +264,11 @@ public static Builder continuation(VarSpec...varSpec)
* @param op
* @param varSpecs
*/
public Expression(final String rawExpression, int startPosition) throws MalformedUriTemplateException
public Expression(final String rawExpression, final int startPosition) throws MalformedUriTemplateException
{
super(startPosition);
this.parseRawExpression(rawExpression);
this.location = startPosition;
this.parseRawExpression(rawExpression);
}

/**
Expand All @@ -275,6 +285,8 @@ public Expression(final Operator op, final List<VarSpec> varSpecs)
this.op = op;
this.varSpecs = varSpecs;
this.replacementPattern = Pattern.quote(toString());
this.matchPattern = buildMatchingPattern();
this.location = 0;
}

/**
Expand All @@ -292,7 +304,14 @@ private void parseRawExpression(String rawExpression) throws MalformedUriTemplat
String firstChar = token.substring(0, 1);
if (UriTemplate.containsOperator(firstChar))
{
operator = Operator.fromOpCode(firstChar);
try
{
operator = Operator.fromOpCode(firstChar);
}
catch (IllegalOperatorException e)
{
throw new MalformedUriTemplateException("Invalid operator" , this.location, e);
}
token = token.substring(1, token.length());
}
String[] varspecStrings = token.split(",");
Expand All @@ -315,7 +334,7 @@ private void parseRawExpression(String rawExpression) throws MalformedUriTemplat
}
catch (NumberFormatException e)
{
throw new MalformedUriTemplateException("The prefix value for "+ pair[0]+ " was not a number", e);
throw new MalformedUriTemplateException("The prefix value for "+ pair[0]+ " was not a number", this.location, e);
}
}

Expand Down Expand Up @@ -350,26 +369,45 @@ private void validateVarname(String varname) throws MalformedUriTemplateExceptio
Matcher matcher = VARNAME_REGEX.matcher(varname);
if(!matcher.matches())
{
throw new MalformedUriTemplateException("The variable name "+varname+" contains invalid characters");
throw new MalformedUriTemplateException("The variable name "+varname+" contains invalid characters", this.location);
}

if(varname.contains(" "))
{
throw new MalformedUriTemplateException("The variable name "+varname+" cannot contain spaces (leading or trailing)");
throw new MalformedUriTemplateException("The variable name "+varname+" cannot contain spaces (leading or trailing)", this.location);
}
}


/**
*
*
* @return
*/
private Pattern buildMatchingPattern()
{
StringBuilder b = new StringBuilder();
for(VarSpec v : getVarSpecs())
{
b.append("(?<").append(v.getVariableName()).append(">[^\\/]+)");
}
return Pattern.compile(b.toString());
}

/**
* Returns a string that contains a regular expression that matches the
* URI template expression.
*
*
* @return
*/
public String buildMatchingPattern()
@Override
public Pattern getMatchPattern()
{
StringBuilder builder = new StringBuilder();
return builder.toString();
if(this.matchPattern == null)
{
this.matchPattern = buildMatchingPattern();
}
return this.matchPattern;
}
/**
* Get the replacementToken.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
*
*
*/
package com.damnhandy.uri.template;

/**
* A IllegalOperatorException.
*
* @author <a href="[email protected]">Ryan J. McDonough</a>
* @version $Revision: 1.1 $
*/
public class IllegalOperatorException extends Exception
{

/** The serialVersionUID */
private static final long serialVersionUID = 7874128076415224267L;


/**
* Create a new IllegalOperatorException.
*
* @param message
*/
public IllegalOperatorException(String message)
{
super(message);
}

}
13 changes: 12 additions & 1 deletion src/main/java/com/damnhandy/uri/template/Literal.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/
package com.damnhandy.uri.template;

import java.util.regex.Pattern;

/**
* Represents the non-expression parts of a URI Template
*
Expand All @@ -16,9 +18,11 @@ public class Literal extends UriTemplateComponent

/** The serialVersionUID */
private static final long serialVersionUID = 6011009312823496878L;

private final String value;

private final Pattern matchPattern;

/**
* Create a new Literal.
*
Expand All @@ -27,6 +31,7 @@ public Literal(final String value, int startPosition)
{
super(startPosition);
this.value = value;
this.matchPattern = Pattern.compile(Pattern.quote(getValue()));
}

@Override
Expand All @@ -41,4 +46,10 @@ public String toString()
return value;
}

@Override
public Pattern getMatchPattern()
{
return this.matchPattern;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

/**
* Raised when the the template processor encounters an issue parsing the URI template string. It indicates
* the template contains an expression that is malformed.
* the either the template itself is malformed, or an expression within the template is malformed.
*
* @author <a href="[email protected]">Ryan J. McDonough</a>
* @version $Revision: 1.1 $
Expand All @@ -29,25 +29,32 @@ public class MalformedUriTemplateException extends Exception
/** The serialVersionUID */
private static final long serialVersionUID = 5883174281977078450L;

private int location;
/**
* Create a new UriTemplateParseException.
*
* @param message
* @param cause
*/
public MalformedUriTemplateException(String message, Throwable cause)
public MalformedUriTemplateException(String message, int location, Throwable cause)
{
super(message, cause);
this.location = location;
}

/**
* Create a new UriTemplateParseException.
*
* @param message
*/
public MalformedUriTemplateException(String message)
public MalformedUriTemplateException(String message, int location)
{
super(message);
this.location = location;
}

public int getLocation()
{
return this.location;
}
}
Loading

1 comment on commit 33c81a7

@lalloni
Copy link

@lalloni lalloni commented on 33c81a7 Aug 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to see advances in this direction!

Please sign in to comment.