Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended AddressBuilder in order to support "Scheme Sepcific Parts". #124

Merged
merged 1 commit into from Sep 15, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions addressbuilder/src/main/java/org/ocpsoft/urlbuilder/Address.java
Expand Up @@ -78,6 +78,16 @@ public interface Address
*/
boolean isSchemeSet();

/**
* Get the scheme section of this {@link Address}, or null if no scheme specific part is set.
*/
String getSchemeSpecificPart();

/**
* Return <code>true</code> if this {@link Address} has a scheme specific part section, otherwise return <code>false</code>.
*/
boolean isSchemeSpecificPartSet();

/**
* Get the query section of this {@link Address}, or <code>null</code> if no query is set.
*/
Expand Down
Expand Up @@ -35,6 +35,7 @@ public class AddressBuilder
{
private volatile Address address;
protected volatile CharSequence scheme;
protected volatile CharSequence schemeSpecificPart;
protected volatile CharSequence domain;
protected volatile Integer port;
protected volatile CharSequence path;
Expand Down Expand Up @@ -69,14 +70,20 @@ protected Address build()
* Create a new {@link Address} from the given fully encoded URL. Improperly formatted or encoded URLs are not
* parse-able and will result in an exception.
*
* @see http://en.wikipedia.org/wiki/URI_scheme
* @throws IllegalArgumentException when the input URL or URL fragment is not valid.
*/
public static Address create(String url) throws IllegalArgumentException
{
try {
URI u = new URI(url);
return AddressBuilder.begin().scheme(u.getScheme()).domain(u.getHost()).port(u.getPort())
.pathEncoded(u.getRawPath()).queryLiteral(u.getRawQuery()).anchor(u.getRawFragment()).build();
String scheme = u.getScheme();
String host = u.getHost();
if(scheme != null && host == null)
return AddressBuilder.begin().scheme(u.getScheme()).schemeSpecificPart(u.getRawSchemeSpecificPart()).build();
else
return AddressBuilder.begin().scheme(scheme).domain(host).port(u.getPort())
.pathEncoded(u.getRawPath()).queryLiteral(u.getRawQuery()).anchor(u.getRawFragment()).build();
}
catch (URISyntaxException e) {
throw new IllegalArgumentException(
Expand All @@ -94,6 +101,15 @@ AddressBuilderScheme scheme(CharSequence scheme)
return new AddressBuilderScheme(this);
}

/**
* Set the scheme section of this {@link Address}.
*/
AddressBuilderSchemeSpecificPart schemeSpecificPart(CharSequence schemeSpecificPart)
{
this.schemeSpecificPart = schemeSpecificPart;
return new AddressBuilderSchemeSpecificPart(this);
}

/**
* Set the domain section of this {@link Address}.
*/
Expand Down
Expand Up @@ -45,6 +45,14 @@ public AddressBuilderDomain domain(CharSequence host)
return parent.domain(host);
}

/**
* Set the scheme specific part section of this {@link Address}.
*/
public AddressBuilderSchemeSpecificPart schemeSpecificPart(CharSequence schemeSpecificPart)
{
return parent.schemeSpecificPart(schemeSpecificPart);
}

/**
* Set the port section of this {@link Address}.
*/
Expand Down
@@ -0,0 +1,46 @@
/*
* Copyright 2013 <a href="mailto:fabmars@gmail.com">Fabien Marsaudz</a>
*
* 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 org.ocpsoft.urlbuilder;

/**
* An {@link Address} with a scheme specific part section.
*
* @author <a href="mailto:fabmars@gmail.com">Fabien Marsaud</a>
*/
public class AddressBuilderSchemeSpecificPart
{
private AddressBuilder parent;

AddressBuilderSchemeSpecificPart(AddressBuilder parent)
{
this.parent = parent;
}

/**
* Generate an {@link Address} representing the current state of this {@link AddressBuilder}.
*/
public Address build()
{
return parent.build();
}

@Override
public String toString()
{
return parent.toString();
}

}
Expand Up @@ -30,6 +30,7 @@
class AddressResult implements Address
{
private final String protocol;
private final String schemeSpecificPart;
private final String host;
private final Integer port;
private final String path;
Expand All @@ -44,6 +45,11 @@ public AddressResult(AddressBuilder parent)
else
protocol = null;

if (isSet(parent.schemeSpecificPart))
schemeSpecificPart = parameterize(parent.parameters, parent.schemeSpecificPart, false).toString();
else
schemeSpecificPart = null;

if (isSet(parent.domain))
host = parameterize(parent.parameters, parent.domain).toString();
else
Expand Down Expand Up @@ -117,20 +123,27 @@ public String toString()
if (isSchemeSet())
result.append(getScheme()).append(":");

if (isDomainSet())
result.append("//").append(getDomain());

if (isPortSet())
result.append(":").append(getPort());

if (isPathSet())
result.append(getPath());

if (isQuerySet())
result.append('?').append(getQuery());

if (isAnchorSet())
result.append('#').append(getAnchor());
if (isSchemeSpecificPartSet())
{
result.append(getSchemeSpecificPart());
}
else
{
if (isDomainSet())
result.append("//").append(getDomain());

if (isPortSet())
result.append(":").append(getPort());

if (isPathSet())
result.append(getPath());

if (isQuerySet())
result.append('?').append(getQuery());

if (isAnchorSet())
result.append('#').append(getAnchor());
}

this.result = result;
}
Expand All @@ -139,6 +152,11 @@ public String toString()
}

private CharSequence parameterize(Map<CharSequence, Parameter> parameters, CharSequence sequence)
{
return parameterize(parameters, sequence, true);
}

private CharSequence parameterize(Map<CharSequence, Parameter> parameters, CharSequence sequence, boolean encodeSequence)
{
StringBuilder result = new StringBuilder();
int cursor = 0;
Expand All @@ -148,7 +166,11 @@ private CharSequence parameterize(Map<CharSequence, Parameter> parameters, CharS
switch (sequence.charAt(cursor))
{
case '{':
result.append(Encoder.path(sequence.subSequence(lastEnd, cursor)));
CharSequence subSequence = sequence.subSequence(lastEnd, cursor);
if(encodeSequence)
subSequence = Encoder.path(subSequence);

result.append(subSequence);

int startPos = cursor;
CapturingGroup group = ParseTools.balancedCapture(sequence, startPos, sequence.length() - 1,
Expand All @@ -175,7 +197,13 @@ private CharSequence parameterize(Map<CharSequence, Parameter> parameters, CharS
}

if (cursor >= lastEnd)
result.append(Encoder.path(sequence.subSequence(lastEnd, cursor)));
{
CharSequence subSequence = sequence.subSequence(lastEnd, cursor);
if(encodeSequence)
subSequence = Encoder.path(subSequence);

result.append(subSequence);
}
return result;
}

Expand Down Expand Up @@ -269,6 +297,18 @@ public boolean isSchemeSet()
return isSet(protocol);
}

@Override
public String getSchemeSpecificPart()
{
return schemeSpecificPart;
}

@Override
public boolean isSchemeSpecificPartSet()
{
return isSet(schemeSpecificPart);
}

@Override
public String getQuery()
{
Expand Down
Expand Up @@ -251,4 +251,24 @@ public void testCreateSchemalessUrl()

}

@Test
public void testBuildSchemeSpecificPart()
{
Assert.assertEquals("mailto:contact@ocpsoft.org?subject=Howdy Lincoln!",
AddressBuilder.begin()
.scheme("mailto")
.schemeSpecificPart("contact@ocpsoft.org?subject=Howdy Lincoln!")
.toString());
}

@Test
public void testBuildSchemeSpecificPartResult()
{
Assert.assertEquals("mailto:contact@ocpsoft.org?subject=Howdy Lincoln!",
AddressBuilder.begin()
.scheme("mailto")
.schemeSpecificPart("contact@ocpsoft.org?subject=Howdy Lincoln!")
.build().toString());
}

}