blob: ec8ce55f8d62f3edb3bc7011ba8b9374023cd6ee [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.knox.gateway.util.urltemplate;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class Builder {
private String original;
private boolean literal;
private boolean hasScheme;
private Scheme scheme;
private boolean hasAuthority;
private boolean isAuthorityOnly;
private Username username;
private Password password;
private Host host;
private Port port;
private boolean isAbsolute;
private boolean isDirectory;
private List<Path> path;
private boolean hasQuery;
private LinkedHashMap<String,Query> query;
private Query extra;
private boolean hasFragment;
private Fragment fragment;
public Builder() {
this( (String)null );
}
public Builder( String original ) {
this.original = original;
this.literal = false;
this.hasScheme = false;
this.scheme = null;
this.hasAuthority = false;
this.isAuthorityOnly = false;
this.username = null;
this.password = null;
this.host = null;
this.port = null;
this.isAbsolute = false;
this.isDirectory = false;
this.path = new ArrayList<>();
this.hasQuery = false;
this.query = new LinkedHashMap<>();
this.extra = null;
this.hasFragment = false;
this.fragment = null;
}
public Builder( Template template ) {
this.hasScheme = template.hasScheme();
this.scheme = copyScheme( template.getScheme() );
this.hasAuthority = template.hasAuthority();
this.isAuthorityOnly = template.isAuthorityOnly();
this.username = copyUsername( template.getUsername() );
this.password = copyPassword( template.getPassword() );
this.host = copyHost( template.getHost() );
this.port = copyPort( template.getPort() );
this.isAbsolute = template.isAbsolute();
this.isDirectory = template.isDirectory();
this.path = copyPath( template.getPath() );
this.hasQuery = template.hasQuery();
this.query = copyQuery( template.getQuery() );
this.extra = copyExtra( template.getExtra() );
this.hasFragment = template.hasFragment();
this.fragment = copyFragment( template.getFragment() );
}
private Scheme copyScheme( Scheme orig ) {
Scheme copy = null;
if( orig != null ) {
copy = new Scheme( orig );
}
return copy;
}
private Username copyUsername( Username orig ) {
Username copy = null;
if( orig != null ) {
copy = new Username( orig );
}
return copy;
}
private Password copyPassword( Password orig ) {
Password copy = null;
if( orig != null ) {
copy = new Password( orig );
}
return copy;
}
private Host copyHost( Host orig ) {
Host copy = null;
if( orig != null ) {
copy = new Host( orig );
}
return copy;
}
private Port copyPort( Port orig ) {
Port copy = null;
if( orig != null ) {
copy = new Port( orig );
}
return copy;
}
private Query copyExtra( Query orig ) {
Query copy = null;
if( orig != null ) {
copy = new Query( orig );
}
return copy;
}
private List<Path> copyPath( List<Path> orig ) {
List<Path> copy = new ArrayList<>();
if( orig != null ) {
for( Path path : orig ) {
copy.add( new Path( path ) );
}
}
return copy;
}
private Fragment copyFragment( Fragment orig ) {
Fragment copy = null;
if( orig != null ) {
copy = new Fragment( orig );
}
return copy;
}
private LinkedHashMap<String, Query> copyQuery( Map<String, Query> orig ) {
LinkedHashMap<String,Query> copy = new LinkedHashMap<>();
if( orig != null ) {
for( Map.Entry<String,Query> entry : orig.entrySet() ) {
copy.put( entry.getKey(), new Query( entry.getValue() ) );
}
}
return copy;
}
public Template build() {
return new Template(
original,
scheme, hasScheme,
username, password, host, port, hasAuthority, isAuthorityOnly,
path, isAbsolute, isDirectory,
query, extra, hasQuery,
fragment, hasFragment );
}
public boolean isLiteral() {
return literal;
}
public void setLiteral( boolean literal ) {
this.literal = literal;
}
public String getOriginal() {
return original;
}
public boolean getHasScheme() {
return this.hasScheme;
}
public void setHasScheme( boolean hasScheme ) {
this.hasScheme = hasScheme;
if( !hasScheme ) {
scheme = null;
}
}
public Scheme getScheme() {
return this.scheme;
}
public void setScheme( String paramName, String valuePattern, boolean literal ) {
this.scheme = new Scheme( paramName, valuePattern, literal );
setHasScheme( true );
}
void setScheme( Token t ) {
this.scheme = new Scheme( t );
setHasScheme( true );
}
public boolean getHasAuthority() {
return hasAuthority;
}
public void setHasAuthority( boolean hasAuthority ) {
this.hasAuthority = hasAuthority;
}
public boolean getIsAuthorityOnly() {
return isAuthorityOnly;
}
public void setIsAuthorityOnly( boolean isAuthorityOnly ) {
this.isAuthorityOnly = isAuthorityOnly;
}
public Username getUsername() {
return username;
}
public void setUsername( String paramName, String valuePattern, boolean literal ) {
setHasAuthority( true );
username = new Username( new Token( paramName, valuePattern, literal ) );
}
void setUsername( Token token ) {
setHasAuthority( true );
username = new Username( token );
}
public Password getPassword() {
return password;
}
public void setPassword( String paramName, String valuePattern, boolean literal ) {
setHasAuthority( true );
password = new Password( paramName, valuePattern, literal );
}
void setPassword( Token token ) {
setHasAuthority( true );
password = new Password( token );
}
public Host getHost() {
return host;
}
public void setHost( String paramName, String valuePattern, boolean literal ) {
setHost( new Token( paramName, valuePattern, literal ) );
}
void setHost( Token token ) {
setHasAuthority( true );
host = new Host( token );
}
public Port getPort() {
return port;
}
public void setPort( String paramName, String valuePattern, boolean literal ) {
setPort( new Token( paramName, valuePattern, literal ) );
}
void setPort( Token token ) {
setHasAuthority( true );
port = new Port( token );
}
public boolean getIsAbsolute() {
return isAbsolute;
}
public Builder setIsAbsolute( boolean isAbsolute ) {
this.isAbsolute = isAbsolute;
return this;
}
public boolean getIsDirectory() {
return isDirectory;
}
public Builder setIsDirectory( boolean isDirectory ) {
this.isDirectory = isDirectory;
return this;
}
public List<Path> getPath() {
return path;
}
public Builder addPath( String paramName, String valuePattern, boolean literal ) {
Path segment = new Path( paramName, valuePattern, literal );
path.add( segment );
return this;
}
Builder addPath( Token token ) {
Path segment = new Path( token );
path.add( segment );
return this;
}
public boolean getHasQuery() {
return hasQuery;
}
public Builder setHasQuery( boolean hasQuery ) {
this.hasQuery = hasQuery;
return this;
}
public Map<String,Query> getQuery() {
return this.query;
}
public Builder addQuery( String queryName, String paramName, String valuePattern, boolean literal ) {
if( Segment.STAR_PATTERN.equals( queryName ) || Segment.GLOB_PATTERN.equals( queryName ) ) {
if( extra == null ) {
Query segment = new Query( queryName, paramName, valuePattern, literal );
extra = segment;
} else {
// Can't have two extras: ?{*}&{**}
//TODO throw new URISyntaxException()? because
}
} else {
Query segment = query.get( queryName );
if( segment == null ) {
segment = new Query( queryName, paramName, valuePattern, literal );
query.put( queryName, segment );
} else {
// Can't have two queryParam names for the same query name: ?query={param1}&query={param2} in a template.
// Should probably throw an exception in this case. However, you can have this in a valid URL.
// This causes a problem with how templates are used for both URLs and Templates.
// For a template only the first parameter name will be used.
segment.addValue( new Token( queryName, valuePattern, literal ) );
}
}
return this;
}
Builder addQuery( String queryName, Token token ) {
if( Segment.STAR_PATTERN.equals( queryName ) || Segment.GLOB_PATTERN.equals( queryName ) ) {
if( extra == null ) {
Query segment = new Query( queryName, token );
extra = segment;
} else {
// Can't have two extras: ?{*}&{**}
//TODO throw new URISyntaxException()? because
}
} else {
Query segment = query.get( queryName );
if( segment == null ) {
segment = new Query( queryName, token );
query.put( queryName, segment );
} else {
// Can't have two queryParam names for the same query name: ?query={param1}&query={param2} in a template.
// Should probably throw an exception in this case. However, you can have this in a valid URL.
// This causes a problem with how templates are used for both URLs and Templates.
// For a template only the first parameter name will be used.
segment.addValue( token );
}
}
return this;
}
public boolean getHasFragment() {
return hasFragment;
}
public void setHasFragment( boolean hasFragment ) {
this.hasFragment = hasFragment;
}
public Fragment getFragment() {
return fragment;
}
public void setFragment( String paramName, String valuePattern ) {
setHasFragment( true );
this.fragment = new Fragment( paramName, valuePattern, literal );
}
void setFragment( Token t ) {
setHasFragment( true );
this.fragment = new Fragment( t );
}
}