src/main/java/org/wymiwyg/commons/util/URI.java
private void initialize(URI p_base, String p_uriSpec)
		throws MalformedURIException {
		if (p_base == null && (p_uriSpec == null || p_uriSpec.length() == 0)) {
			throw new RelativeURIException("Cannot initialize URI with empty parameters.");
		}

		// just make a copy of the base if spec is empty
		if (p_uriSpec == null || p_uriSpec.length() == 0) {
			initialize(p_base);
			return;
		}

		String uriSpec = p_uriSpec;
		int uriSpecLen = uriSpec.length();
		int index = 0;

		// Check for scheme, which must be before '/', '?' or '#'. Also handle
		// names with DOS drive letters ('D:'), so 1-character schemes are not
		// allowed.
		int colonIdx = uriSpec.indexOf(':');
		int slashIdx = uriSpec.indexOf('/');
		int queryIdx = uriSpec.indexOf('?');
		int fragmentIdx = uriSpec.indexOf('#');

		if ((colonIdx < 2)
			|| (colonIdx > slashIdx && slashIdx != -1)
			|| (colonIdx > queryIdx && queryIdx != -1)
			|| (colonIdx > fragmentIdx && fragmentIdx != -1)) {
			// We need to do the relative URI algorithm:

			// jjc: the spec says:
			// 'URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]'
			// My understanding is that if there is only the fragment
			// then this is a relative URI.
			if (p_base == null // del jjc: && fragmentIdx != 0
			) {
				// Nothing to be relative against.
				throw new RelativeURIException("No scheme found in URI." + p_uriSpec );
			} else {
				if ((!p_base.isGenericURI()) && fragmentIdx != 0)
					// Can't be relative against opaque URI (except using the #frag).
					throw new MalformedURIException("Cannot apply relative URI to an opaque URI");
			}
		} else {
			initializeScheme(uriSpec);
			index = m_scheme.length() + 1;
		}

		// two slashes means generic URI syntax, so we get the authority
		if (((index + 1) < uriSpecLen)
			&& (uriSpec.substring(index).startsWith("//"))) {
			index += 2;
			int startPos = index;

			// get authority - everything up to path, query or fragment
			char testChar = '\0';
			while (index < uriSpecLen) {
				testChar = uriSpec.charAt(index);
				if (testChar == '/' || testChar == '?' || testChar == '#') {
					break;
				}
				index++;
			}

			// if we found authority, parse it out, otherwise we set the
			// host to empty string
			if (index > startPos) {
				initializeAuthority(uriSpec.substring(startPos, index));
			} else {
				m_host = "";
			}
		}

		initializePath(uriSpec.substring(index));

		// Resolve relative URI to base URI - see RFC 2396 Section 5.2
		// In some cases, it might make more sense to throw an exception
		// (when scheme is specified is the string spec and the base URI
		// is also specified, for example), but we're just following the
		// RFC specifications
		if (p_base != null) {

			// check to see if this is the current doc - RFC 2396 5.2 #2
			// note that this is slightly different from the RFC spec in that
			// we don't include the check for query string being null
			// - this handles cases where the urispec is just a query
			// string or a fragment (e.g. "?y" or "#s") -
			// see <http://www.ics.uci.edu/~fielding/url/test1.html> which
			// identified this as a bug in the RFC
			if (m_path.length() == 0 && m_scheme == null && m_host == null) {
				m_scheme = p_base.getScheme();
				m_userinfo = p_base.getUserinfo();
				m_host = p_base.getHost();
				m_port = p_base.m_port;
				n_port = p_base.getPort();
				m_path = p_base.getPath();

				if (m_queryString == null) {
					m_queryString = p_base.getQueryString();
				}
				return;
			}

			// check for scheme - RFC 2396 5.2 #3
			// if we found a scheme, it means absolute URI, so we're done
			if (m_scheme == null) {
				m_scheme = p_base.getScheme();
			} else {
				return;
			}

			// check for authority - RFC 2396 5.2 #4
			// if we found a host, then we've got a network path, so we're done
			if (m_host == null) {
				m_userinfo = p_base.getUserinfo();
				m_host = p_base.getHost();
				m_port = p_base.m_port;
				n_port = p_base.getPort();
			} else {
				return;
			}

			// check for absolute path - RFC 2396 5.2 #5
			if (m_path.length() > 0 && m_path.startsWith("/")) {
				return;
			}

			// if we get to this point, we need to resolve relative path
			// RFC 2396 5.2 #6
				String path = // jjc new String();
	"/"; // jjc ins
			String basePath = p_base.getPath();

			// 6a - get all but the last segment of the base URI path
			if (basePath != null) {
				int lastSlash = basePath.lastIndexOf('/');
				if (lastSlash != -1) {
					path = basePath.substring(0, lastSlash + 1);
				}
			}

			// 6b - append the relative URI path
			path = path.concat(m_path);

			// 6c - remove all "./" where "." is a complete path segment
			index = -1;
			while ((index = path.indexOf("/./")) != -1) {
				path =
					path.substring(0, index + 1).concat(
						path.substring(index + 3));
			}

			// 6d - remove "." if path ends with "." as a complete path segment
			if (path.endsWith("/.")) {
				path = path.substring(0, path.length() - 1);
			}

			// 6e - remove all "<segment>/../" where "<segment>" is a complete
			// path segment not equal to ".."
			index = 1;
			int segIndex = -1;

			while ((index = path.indexOf("/../", index)) > 0) {
				segIndex = path.lastIndexOf('/', index - 1);
				if (segIndex != -1
					&& !path.substring(segIndex + 1, index).equals("..")) {
					path =
						path.substring(0, segIndex).concat(
							path.substring(index + 3));
					index = segIndex;
				} else {
					index += 4;
				}
			}

			// 6f - remove ending "<segment>/.." where "<segment>" is a
			// complete path segment
			if (path.endsWith("/..")) {
				index = path.length() - 3;
				segIndex = path.lastIndexOf('/', index - 1);
				if (segIndex != -1
					&& !path.substring(segIndex + 1, index).equals("..")) {
					path = path.substring(0, segIndex + 1);
				}
			}

			m_path = path;
		}
	}
private void initialize(URI p_base, String p_uriSpec)
		throws MalformedURIException {
		if (p_base == null && (p_uriSpec == null || p_uriSpec.length() == 0)) {
			throw new RelativeURIException("Cannot initialize URI with empty parameters.");
		}

		// just make a copy of the base if spec is empty
		if (p_uriSpec == null || p_uriSpec.length() == 0) {
			initialize(p_base);
			return;
		}

		String uriSpec = p_uriSpec;
		int uriSpecLen = uriSpec.length();
		int index = 0;

		// Check for scheme, which must be before '/', '?' or '#'. Also handle
		// names with DOS drive letters ('D:'), so 1-character schemes are not
		// allowed.
		int colonIdx = uriSpec.indexOf(':');
		int slashIdx = uriSpec.indexOf('/');
		int queryIdx = uriSpec.indexOf('?');
		int fragmentIdx = uriSpec.indexOf('#');

		if ((colonIdx < 2)
			|| (colonIdx > slashIdx && slashIdx != -1)
			|| (colonIdx > queryIdx && queryIdx != -1)
			|| (colonIdx > fragmentIdx && fragmentIdx != -1)) {
			// We need to do the relative URI algorithm:

			// jjc: the spec says:
			// 'URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]'
			// My understanding is that if there is only the fragment
			// then this is a relative URI.
			if (p_base == null // del jjc: && fragmentIdx != 0
			) {
				// Nothing to be relative against.
				throw new RelativeURIException("No scheme found in URI." + p_uriSpec );
			} else {
				if ((!p_base.isGenericURI()) && fragmentIdx != 0)
					// Can't be relative against opaque URI (except using the #frag).
					throw new MalformedURIException("Cannot apply relative URI to an opaque URI");
			}
		} else {
			initializeScheme(uriSpec);
			index = m_scheme.length() + 1;
		}

		// two slashes means generic URI syntax, so we get the authority
		if (((index + 1) < uriSpecLen)
			&& (uriSpec.substring(index).startsWith("//"))) {
			index += 2;
			int startPos = index;

			// get authority - everything up to path, query or fragment
			char testChar = '\0';
			while (index < uriSpecLen) {
				testChar = uriSpec.charAt(index);
				if (testChar == '/' || testChar == '?' || testChar == '#') {
					break;
				}
				index++;
			}

			// if we found authority, parse it out, otherwise we set the
			// host to empty string
			if (index > startPos) {
				initializeAuthority(uriSpec.substring(startPos, index));
			} else {
				m_host = "";
			}
		}

		initializePath(uriSpec.substring(index));

		// Resolve relative URI to base URI - see RFC 2396 Section 5.2
		// In some cases, it might make more sense to throw an exception
		// (when scheme is specified is the string spec and the base URI
		// is also specified, for example), but we're just following the
		// RFC specifications
		if (p_base != null) {

			// check to see if this is the current doc - RFC 2396 5.2 #2
			// note that this is slightly different from the RFC spec in that
			// we don't include the check for query string being null
			// - this handles cases where the urispec is just a query
			// string or a fragment (e.g. "?y" or "#s") -
			// see <http://www.ics.uci.edu/~fielding/url/test1.html> which
			// identified this as a bug in the RFC
			if (m_path.length() == 0 && m_scheme == null && m_host == null) {
				m_scheme = p_base.getScheme();
				m_userinfo = p_base.getUserinfo();
				m_host = p_base.getHost();
				m_port = p_base.m_port;
				n_port = p_base.getPort();
				m_path = p_base.getPath();

				if (m_queryString == null) {
					m_queryString = p_base.getQueryString();
				}
				return;
			}

			// check for scheme - RFC 2396 5.2 #3
			// if we found a scheme, it means absolute URI, so we're done
			if (m_scheme == null) {
				m_scheme = p_base.getScheme();
			} else {
				return;
			}

			// check for authority - RFC 2396 5.2 #4
			// if we found a host, then we've got a network path, so we're done
			if (m_host == null) {
				m_userinfo = p_base.getUserinfo();
				m_host = p_base.getHost();
				m_port = p_base.m_port;
				n_port = p_base.getPort();
			} else {
				return;
			}

			// check for absolute path - RFC 2396 5.2 #5
			if (m_path.length() > 0 && m_path.startsWith("/")) {
				return;
			}

			// if we get to this point, we need to resolve relative path
			// RFC 2396 5.2 #6
				String path = // jjc new String();
	"/"; // jjc ins
			String basePath = p_base.getPath();

			// 6a - get all but the last segment of the base URI path
			if (basePath != null) {
				int lastSlash = basePath.lastIndexOf('/');
				if (lastSlash != -1) {
					path = basePath.substring(0, lastSlash + 1);
				}
			}

			// 6b - append the relative URI path
			path = path.concat(m_path);

			// 6c - remove all "./" where "." is a complete path segment
			index = -1;
			while ((index = path.indexOf("/./")) != -1) {
				path =
					path.substring(0, index + 1).concat(
						path.substring(index + 3));
			}

			// 6d - remove "." if path ends with "." as a complete path segment
			if (path.endsWith("/.")) {
				path = path.substring(0, path.length() - 1);
			}

			// 6e - remove all "<segment>/../" where "<segment>" is a complete
			// path segment not equal to ".."
			index = 1;
			int segIndex = -1;

			while ((index = path.indexOf("/../", index)) > 0) {
				segIndex = path.lastIndexOf('/', index - 1);
				if (segIndex != -1
					&& !path.substring(segIndex + 1, index).equals("..")) {
					path =
						path.substring(0, segIndex).concat(
							path.substring(index + 3));
					index = segIndex;
				} else {
					index += 4;
				}
			}

			// 6f - remove ending "<segment>/.." where "<segment>" is a
			// complete path segment
			if (path.endsWith("/..")) {
				index = path.length() - 3;
				segIndex = path.lastIndexOf('/', index - 1);
				if (segIndex != -1
					&& !path.substring(segIndex + 1, index).equals("..")) {
					path = path.substring(0, segIndex + 1);
				}
			}

			m_path = path;
		}
	}
private void initialize ( URI p_base , String p_uriSpec ) throws MalformedURIException { if ( p_base == null && ( p_uriSpec == null || p_uriSpec . length ( ) == 0 ) ) { throw new RelativeURIException ( "Cannot initialize URI with empty parameters." ) ; } // just make a copy of the base if spec is empty
 if ( p_uriSpec == null || p_uriSpec . length ( ) == 0 ) { initialize ( p_base ) ; return ; } String uriSpec = p_uriSpec ; int uriSpecLen = uriSpec . length ( ) ; int index = 0 ; // Check for scheme, which must be before '/', '?' or '#'. Also handle
 // names with DOS drive letters ('D:'), so 1-character schemes are not
 // allowed.
 int colonIdx = uriSpec . indexOf ( ' ' ) ; int slashIdx = uriSpec . indexOf ( ' ' ) ; int queryIdx = uriSpec . indexOf ( ' ' ) ; int fragmentIdx = uriSpec . indexOf ( ' ' ) ; if ( ( colonIdx < 2 ) || ( colonIdx > slashIdx && slashIdx != - 1 ) || ( colonIdx > queryIdx && queryIdx != - 1 ) || ( colonIdx > fragmentIdx && fragmentIdx != - 1 ) ) { // We need to do the relative URI algorithm:
 // jjc: the spec says:
 // 'URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]'
 // My understanding is that if there is only the fragment
 // then this is a relative URI.
 if ( p_base == null // del jjc: && fragmentIdx != 0
 ) { // Nothing to be relative against.
 throw new RelativeURIException ( "No scheme found in URI." + p_uriSpec ) ; } else { if ( ( ! p_base . isGenericURI ( ) ) && fragmentIdx != 0 ) // Can't be relative against opaque URI (except using the #frag).
 throw new MalformedURIException ( "Cannot apply relative URI to an opaque URI" ) ; } } else { initializeScheme ( uriSpec ) ; index = m_scheme . length ( ) + 1 ; } // two slashes means generic URI syntax, so we get the authority
 if ( ( ( index + 1 ) < uriSpecLen ) && ( uriSpec . substring ( index ) . startsWith ( "//" ) ) ) { index += 2 ; int startPos = index ; // get authority - everything up to path, query or fragment
 char testChar = ' ' ; while ( index < uriSpecLen ) { testChar = uriSpec . charAt ( index ) ; if ( testChar == ' ' || testChar == ' ' || testChar == ' ' ) { break ; } index ++ ; } // if we found authority, parse it out, otherwise we set the
 // host to empty string
 if ( index > startPos ) { initializeAuthority ( uriSpec . substring ( startPos , index ) ) ; } else { m_host = "" ; } } initializePath ( uriSpec . substring ( index ) ) ; // Resolve relative URI to base URI - see RFC 2396 Section 5.2
 // In some cases, it might make more sense to throw an exception
 // (when scheme is specified is the string spec and the base URI
 // is also specified, for example), but we're just following the
 // RFC specifications
 if ( p_base != null ) { // check to see if this is the current doc - RFC 2396 5.2 #2
 // note that this is slightly different from the RFC spec in that
 // we don't include the check for query string being null
 // - this handles cases where the urispec is just a query
 // string or a fragment (e.g. "?y" or "#s") -
 // see <http://www.ics.uci.edu/~fielding/url/test1.html> which
 // identified this as a bug in the RFC
 if ( m_path . length ( ) == 0 && m_scheme == null && m_host == null ) { m_scheme = p_base . getScheme ( ) ; m_userinfo = p_base . getUserinfo ( ) ; m_host = p_base . getHost ( ) ; m_port = p_base . m_port ; n_port = p_base . getPort ( ) ; m_path = p_base . getPath ( ) ; if ( m_queryString == null ) { m_queryString = p_base . getQueryString ( ) ; } return ; } // check for scheme - RFC 2396 5.2 #3
 // if we found a scheme, it means absolute URI, so we're done
 if ( m_scheme == null ) { m_scheme = p_base . getScheme ( ) ; } else { return ; } // check for authority - RFC 2396 5.2 #4
 // if we found a host, then we've got a network path, so we're done
 if ( m_host == null ) { m_userinfo = p_base . getUserinfo ( ) ; m_host = p_base . getHost ( ) ; m_port = p_base . m_port ; n_port = p_base . getPort ( ) ; } else { return ; } // check for absolute path - RFC 2396 5.2 #5
 if ( m_path . length ( ) > 0 && m_path . startsWith ( "/" ) ) { return ; } // if we get to this point, we need to resolve relative path
 // RFC 2396 5.2 #6
 String path = // jjc new String();
 "/" ; // jjc ins
 String basePath = p_base . getPath ( ) ; // 6a - get all but the last segment of the base URI path
 if ( basePath != null ) { int lastSlash = basePath . lastIndexOf ( ' ' ) ; if ( lastSlash != - 1 ) { path = basePath . substring ( 0 , lastSlash + 1 ) ; } } // 6b - append the relative URI path
 path = path . concat ( m_path ) ; // 6c - remove all "./" where "." is a complete path segment
 index = - 1 ; while ( ( index = path . indexOf ( "/./" ) ) != - 1 ) { path = path . substring ( 0 , index + 1 ) . concat ( path . substring ( index + 3 ) ) ; } // 6d - remove "." if path ends with "." as a complete path segment
 if ( path . endsWith ( "/." ) ) { path = path . substring ( 0 , path . length ( ) - 1 ) ; } // 6e - remove all "<segment>/../" where "<segment>" is a complete
 // path segment not equal to ".."
 index = 1 ; int segIndex = - 1 ; while ( ( index = path . indexOf ( "/../" , index ) ) > 0 ) { segIndex = path . lastIndexOf ( ' ' , index - 1 ) ; if ( segIndex != - 1 && ! path . substring ( segIndex + 1 , index ) . equals ( ".." ) ) { path = path . substring ( 0 , segIndex ) . concat ( path . substring ( index + 3 ) ) ; index = segIndex ; } else { index += 4 ; } } // 6f - remove ending "<segment>/.." where "<segment>" is a
 // complete path segment
 if ( path . endsWith ( "/.." ) ) { index = path . length ( ) - 3 ; segIndex = path . lastIndexOf ( ' ' , index - 1 ) ; if ( segIndex != - 1 && ! path . substring ( segIndex + 1 , index ) . equals ( ".." ) ) { path = path . substring ( 0 , segIndex + 1 ) ; } } m_path = path ; } }
Initializes this URI from a base URI and a URI specification string.
See RFC 2396 Section 4 and Appendix B for specifications on parsing
the URI and Section 5 for specifications on resolving relative URIs
and relative paths.

@param p_base the base URI (may be null if p_uriSpec is an absolute
URI)
@param p_uriSpec the URI spec string which may be an absolute or
relative URI (can only be null/empty if p_base
is not null)

@exception MalformedURIException if p_base is null and p_uriSpec
is not an absolute URI or if
p_uriSpec violates syntax rules
Initializes this URI from a base URI and a URI specification string . See RFC 2396 Section 4 and Appendix B for specifications on parsing the URI and Section 5 for specifications on resolving relative URIs and relative paths .