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 Camel does not use or 023 * 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 * 035 * <pre> 036 * URI u = new URI(UnsafeUriCharactersEncoder.encode(uri, true)); 037 * </pre> 038 * 039 * @param uri the uri 040 * 041 * @return <tt>null</tt> if not possible to parse, or an array[3] with scheme,path,query 042 */ 043 public static String[] parseUri(String uri) { 044 int schemeStart = 0; 045 int schemeEnd = 0; 046 int pathStart = 0; 047 int pathEnd = 0; 048 int queryStart = 0; 049 050 int len = uri.length(); 051 for (int i = 0; i < len; i++) { 052 char ch = uri.charAt(i); 053 if (ch > 128) { 054 // must be an ascii char 055 return null; 056 } 057 // must be a safe char 058 if (!UnsafeUriCharactersEncoder.isSafeFastParser(ch)) { 059 return null; 060 } 061 if (schemeEnd == 0) { 062 if (ch == ':') { 063 schemeEnd = i; 064 // skip colon 065 pathStart = i + 1; 066 } 067 } else if (pathEnd == 0) { 068 if (ch == '?') { 069 pathEnd = i; 070 // skip ? marker 071 queryStart = i + 1; 072 } 073 } 074 } 075 076 if (pathStart == 0 && schemeEnd != 0) { 077 // skip colon 078 pathStart = schemeEnd + 1; 079 } 080 // invalid if there is no path anyway 081 if (pathStart >= len) { 082 return null; 083 } 084 085 String scheme = null; 086 if (schemeEnd != 0) { 087 scheme = uri.substring(schemeStart, schemeEnd); 088 } 089 if (scheme == null) { 090 return null; 091 } 092 093 String path; 094 // skip two leading slashes 095 int next = pathStart + 1; 096 if (uri.charAt(pathStart) == '/' && next < len && uri.charAt(next) == '/') { 097 pathStart = pathStart + 2; 098 } 099 if (pathEnd != 0) { 100 path = uri.substring(pathStart, pathEnd); 101 } else { 102 path = uri.substring(pathStart); 103 } 104 105 String query = null; 106 if (queryStart != 0 && queryStart < len) { 107 query = uri.substring(queryStart); 108 } 109 110 return new String[] { scheme, path, query }; 111 } 112}