001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.util; 018 019/** 020 * A Camel specific URI parser that parses endpoint URIs in a quasi syntax that Camel uses. 021 * 022 * The {@link java.net.URI} is much slower and parses endpoint URIs into additional parts which 023 * Camel does not use or need. 024 */ 025public final class CamelURIParser { 026 027 private CamelURIParser() { 028 } 029 030 /** 031 * Parses the URI. 032 * 033 * If this parser cannot parse the uri then <tt>null</tt> is returned. And instead the follow code can be used: 034 * <pre> 035 * URI u = new URI(UnsafeUriCharactersEncoder.encode(uri, true)); 036 * </pre> 037 * 038 * @param uri the uri 039 * 040 * @return <tt>null</tt> if not possible to parse, or an array[3] with scheme,path,query 041 */ 042 public static String[] parseUri(String uri) { 043 int schemeStart = 0; 044 int schemeEnd = 0; 045 int pathStart = 0; 046 int pathEnd = 0; 047 int queryStart = 0; 048 049 int len = uri.length(); 050 for (int i = 0; i < len; i++) { 051 char ch = uri.charAt(i); 052 if (ch > 128) { 053 // must be an ascii char 054 return null; 055 } 056 // must be a safe char 057 if (!UnsafeUriCharactersEncoder.isSafeFastParser(ch)) { 058 return null; 059 } 060 if (schemeEnd == 0) { 061 if (ch == ':') { 062 schemeEnd = i; 063 // skip colon 064 pathStart = i + 1; 065 } 066 } else if (pathEnd == 0) { 067 if (ch == '?') { 068 pathEnd = i; 069 // skip ? marker 070 queryStart = i + 1; 071 } 072 } 073 } 074 075 if (pathStart == 0 && schemeEnd != 0) { 076 // skip colon 077 pathStart = schemeEnd + 1; 078 } 079 // invalid if there is no path anyway 080 if (pathStart >= len) { 081 return null; 082 } 083 084 String scheme = null; 085 if (schemeEnd != 0) { 086 scheme = uri.substring(schemeStart, schemeEnd); 087 } 088 if (scheme == null) { 089 return null; 090 } 091 092 String path; 093 // skip two leading slashes 094 int next = pathStart + 1; 095 if (uri.charAt(pathStart) == '/' && next < len && uri.charAt(next) == '/') { 096 pathStart = pathStart + 2; 097 } 098 if (pathEnd != 0) { 099 path = uri.substring(pathStart, pathEnd); 100 } else { 101 path = uri.substring(pathStart); 102 } 103 104 String query = null; 105 if (queryStart != 0 && queryStart < len) { 106 query = uri.substring(queryStart); 107 } 108 109 return new String[]{scheme, path, query}; 110 } 111}