blob: 11b4f49a3b29e1befae2edc6b4432e2a3b91c394 [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.juneau;
import static org.apache.juneau.internal.StringUtils.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
/**
* Represents a URL broken into authority/context-root/servlet-path/path-info parts.
*
* <p>
* A typical request against a URL takes the following form:
* <p class='bcode w800'>
* http://host:port/context-root/servlet-path/path-info
* | authority | context | resource | path |
* +--------------------------------------------------+
* </p>
*
* <p>
* This class allows you to convert URL strings to absolute (e.g. <js>"http://host:port/foo/bar"</js>) or root-relative
* (e.g. <js>"/foo/bar"</js>) URLs.
*/
@Bean
public class UriContext {
/**
* Default URI context.
*
* <p>
* No information about authority, servlet-root, context-root, or path-info is known.
*/
public static final UriContext DEFAULT = new UriContext();
@SuppressWarnings("javadoc")
public final String authority, contextRoot, servletPath, pathInfo, parentPath;
// Lazy-initialized fields.
private String aContextRoot, rContextRoot, aServletPath, rResource, aPathInfo, rPath;
/**
* Constructor.
*
* <p>
* Leading and trailing slashes are trimmed of all parameters.
*
* <p>
* Any parameter can be <jk>null</jk>. Blanks and nulls are equivalent.
*
* @param authority
* The authority portion of URL (e.g. <js>"http://hostname:port"</js>)
* @param contextRoot
* The context root of the application (e.g. <js>"/context-root"</js>, or <js>"context-root"</js>)
* @param servletPath
* The servlet path (e.g. <js>"/servlet-path"</js>, or <js>"servlet-path"</js>)
* @param pathInfo
* The path info (e.g. <js>"/path-info"</js>, or <js>"path-info"</js>)
*/
@Beanc
public UriContext(@Name("authority") String authority, @Name("contextRoot") String contextRoot, @Name("servletPath") String servletPath, @Name("pathInfo") String pathInfo) {
this.authority = nullIfEmpty(trimSlashes(authority));
this.contextRoot = nullIfEmpty(trimSlashes(contextRoot));
this.servletPath = nullIfEmpty(trimSlashes(servletPath));
this.pathInfo = nullIfEmpty(trimSlashes(pathInfo));
this.parentPath = this.pathInfo == null || this.pathInfo.indexOf('/') == -1 ? null
: this.pathInfo.substring(0, this.pathInfo.lastIndexOf('/'));
}
/**
* Default constructor.
*
* <p>
* All <jk>null</jk> values.
*/
public UriContext() {
this(null, null, null, null);
}
/**
* String constructor.
*
* <p>
* Input string is a JSON object with the following format:
* <js>{authority:'xxx',contextRoot:'xxx',servletPath:'xxx',pathInfo:'xxx'}</js>
*
* @param s
* The input string.
* <br>Example: <js>{authority:'http://localhost:10000',contextRoot:'/myContext',servletPath:'/myServlet',pathInfo:'/foo'}</js>
* @throws ParseException
* If input string is not a valid JSON object.
*/
public UriContext(String s) throws ParseException {
ObjectMap m = new ObjectMap(s);
this.authority = nullIfEmpty(trimSlashes(m.getString("authority")));
this.contextRoot = nullIfEmpty(trimSlashes(m.getString("contextRoot")));
this.servletPath = nullIfEmpty(trimSlashes(m.getString("servletPath")));
this.pathInfo = nullIfEmpty(trimSlashes(m.getString("pathInfo")));
this.parentPath = this.pathInfo == null || this.pathInfo.indexOf('/') == -1 ? null
: this.pathInfo.substring(0, this.pathInfo.lastIndexOf('/'));
}
/**
* Returns the absolute URI of just the authority portion of this URI context.
*
* <p>
* Example: <js>"http://hostname:port"</js>
*
* <p>
* If the authority is null/empty, returns <js>"/"</js>.
*
* @return
* The absolute URI of just the authority portion of this URI context.
* Never <jk>null</jk>.
*/
public String getAbsoluteAuthority() {
return authority == null ? "/" : authority;
}
/**
* Returns the absolute URI of the context-root portion of this URI context.
*
* <p>
* Example: <js>"http://hostname:port/context-root"</js>
*
* @return
* The absolute URI of the context-root portion of this URI context.
* Never <jk>null</jk>.
*/
public String getAbsoluteContextRoot() {
if (aContextRoot == null) {
if (authority == null)
aContextRoot = getRootRelativeContextRoot();
else
aContextRoot = (
contextRoot == null
? authority
: (authority + '/' + contextRoot)
);
}
return aContextRoot;
}
/**
* Returns the root-relative URI of the context portion of this URI context.
*
* <p>
* Example: <js>"/context-root"</js>
*
* @return
* The root-relative URI of the context portion of this URI context.
* Never <jk>null</jk>.
*/
public String getRootRelativeContextRoot() {
if (rContextRoot == null)
rContextRoot = contextRoot == null ? "/" : ('/' + contextRoot);
return rContextRoot;
}
/**
* Returns the absolute URI of the resource portion of this URI context.
*
* <p>
* Example: <js>"http://hostname:port/context-root/servlet-path"</js>
*
* @return
* The absolute URI of the resource portion of this URI context.
* Never <jk>null</jk>.
*/
public String getAbsoluteServletPath() {
if (aServletPath == null) {
if (authority == null)
aServletPath = getRootRelativeServletPath();
else {
if (contextRoot == null)
aServletPath = (
servletPath == null
? authority
: authority + '/' + servletPath
);
else
aServletPath = (
servletPath == null
? (authority + '/' + contextRoot)
: (authority + '/' + contextRoot + '/' + servletPath)
);
}
}
return aServletPath;
}
/**
* Returns the root-relative URI of the resource portion of this URI context.
*
* <p>
* Example: <js>"/context-root/servlet-path"</js>
*
* @return
* The root-relative URI of the resource portion of this URI context.
* Never <jk>null</jk>.
*/
public String getRootRelativeServletPath() {
if (rResource == null) {
if (contextRoot == null)
rResource = (
servletPath == null
? "/"
: ('/' + servletPath)
);
else
rResource = (
servletPath == null
? ('/' + contextRoot)
: ('/' + contextRoot + '/' + servletPath)
);
}
return rResource;
}
/**
* Returns the parent of the URL returned by {@link #getAbsoluteServletPath()}.
*
* @return The parent of the URL returned by {@link #getAbsoluteServletPath()}.
*/
public String getAbsoluteServletPathParent() {
return getParent(getAbsoluteServletPath());
}
/**
* Returns the parent of the URL returned by {@link #getRootRelativeServletPath()}.
*
* @return The parent of the URL returned by {@link #getRootRelativeServletPath()}.
*/
public String getRootRelativeServletPathParent() {
return getParent(getRootRelativeServletPath());
}
/**
* Returns the absolute URI of the path portion of this URI context.
*
* <p>
* Example: <js>"http://hostname:port/context-root/servlet-path/path-info"</js>
*
* @return
* The absolute URI of the path portion of this URI context.
* Never <jk>null</jk>.
*/
public String getAbsolutePathInfo() {
if (aPathInfo == null) {
if (authority == null)
aPathInfo = getRootRelativePathInfo();
else {
if (contextRoot == null) {
if (servletPath == null)
aPathInfo = (
pathInfo == null
? authority : (authority + '/' + pathInfo)
);
else
aPathInfo = (
pathInfo == null
? (authority + '/' + servletPath)
: (authority + '/' + servletPath + '/' + pathInfo)
);
} else {
if (servletPath == null)
aPathInfo = (
pathInfo == null
? authority + '/' + contextRoot
: (authority + '/' + contextRoot + '/' + pathInfo)
);
else
aPathInfo = (
pathInfo == null
? (authority + '/' + contextRoot + '/' + servletPath)
: (authority + '/' + contextRoot + '/' + servletPath + '/' + pathInfo)
);
}
}
}
return aPathInfo;
}
/**
* Returns the root-relative URI of the path portion of this URI context.
*
* <p>
* Example: <js>"/context-root/servlet-path/path-info"</js>
*
* @return
* The root-relative URI of the path portion of this URI context.
* Never <jk>null</jk>.
*/
public String getRootRelativePathInfo() {
if (rPath == null) {
if (contextRoot == null) {
if (servletPath == null)
rPath = (
pathInfo == null
? "/"
: ('/' + pathInfo)
);
else
rPath = (
pathInfo == null
? ('/' + servletPath)
: ('/' + servletPath + '/' + pathInfo)
);
} else {
if (servletPath == null)
rPath = (
pathInfo == null
? ('/' + contextRoot)
: ('/' + contextRoot + '/' + pathInfo)
);
else
rPath = (
pathInfo == null
? ('/' + contextRoot + '/' + servletPath)
: ('/' + contextRoot + '/' + servletPath + '/' + pathInfo)
);
}
}
return rPath;
}
/**
* Returns the parent of the URL returned by {@link #getAbsolutePathInfo()}.
*
* @return The parent of the URL returned by {@link #getAbsolutePathInfo()}.
*/
public String getAbsolutePathInfoParent() {
return getParent(getAbsolutePathInfo());
}
/**
* Returns the parent of the URL returned by {@link #getRootRelativePathInfo()}.
*
* @return The parent of the URL returned by {@link #getRootRelativePathInfo()}.
*/
public String getRootRelativePathInfoParent() {
return getParent(getRootRelativePathInfo());
}
private static String getParent(String uri) {
int i = uri.lastIndexOf('/');
if (i <= 1)
return "/";
return uri.substring(0, i);
}
@Override /* Object */
public String toString() {
return SimpleJsonSerializer.DEFAULT.toString(this);
}
}