@@ -28,6 +28,8 @@ public class PostgreSQLURLParser extends AbstractURLParser {
2828
2929 private static final int DEFAULT_PORT = 5432 ;
3030 private static final String DB_TYPE = "PostgreSQL" ;
31+ private static final String URL_PARAMS_HOST_KEY = "host" ;
32+ private static final String URL_PARAMS_PORT_KEY = "port" ;
3133
3234 public PostgreSQLURLParser (String url ) {
3335 super (url );
@@ -37,15 +39,29 @@ public PostgreSQLURLParser(String url) {
3739 protected URLLocation fetchDatabaseHostsIndexRange () {
3840 int hostLabelStartIndex = url .indexOf ("//" );
3941 int hostLabelEndIndex = url .indexOf ("/" , hostLabelStartIndex + 2 );
42+ if (hostLabelEndIndex == -1 ) {
43+ hostLabelEndIndex = url .length ();
44+ }
4045 return new URLLocation (hostLabelStartIndex + 2 , hostLabelEndIndex );
4146 }
4247
4348 @ Override
4449 protected URLLocation fetchDatabaseNameIndexRange () {
45- int databaseStartTag = url .lastIndexOf ("/" );
46- int databaseEndTag = url .indexOf ("?" , databaseStartTag );
50+ int databaseLabelStartIndex = url .indexOf ("//" );
51+ int databaseStartTag = url .indexOf ("/" , databaseLabelStartIndex + 2 );
52+ int databaseEndTag = url .indexOf ("?" , databaseLabelStartIndex + 2 );
53+ if (databaseEndTag < databaseStartTag && databaseEndTag != -1 ) {
54+ //database parse fail
55+ return new URLLocation (0 , 0 );
56+ }
57+ if (databaseStartTag == -1 ) {
58+ //database empty
59+ return new URLLocation (0 , 0 );
60+ }
4761 if (databaseEndTag == -1 ) {
4862 databaseEndTag = url .length ();
63+ } else {
64+ databaseStartTag = url .substring (0 , databaseEndTag ).lastIndexOf ("/" );
4965 }
5066 return new URLLocation (databaseStartTag + 1 , databaseEndTag );
5167 }
@@ -58,21 +74,88 @@ public ConnectionInfo parse() {
5874 if (hostSegment .length > 1 ) {
5975 StringBuilder sb = new StringBuilder ();
6076 for (String host : hostSegment ) {
61- if (host .split (":" ).length == 1 ) {
62- sb .append (host + ":" + DEFAULT_PORT + "," );
77+ if (host .substring ( host . indexOf ( "]" ) + 1 ). split (":" ).length == 1 ) {
78+ sb .append (host ). append ( ":" ). append ( DEFAULT_PORT ). append ( "," );
6379 } else {
64- sb .append (host + "," );
80+ sb .append (host ). append ( "," );
6581 }
6682 }
67- return new ConnectionInfo (ComponentsDefine .POSTGRESQL_DRIVER , DB_TYPE , sb .toString (), fetchDatabaseNameFromURL ());
83+ return new ConnectionInfo (
84+ ComponentsDefine .POSTGRESQL_DRIVER , DB_TYPE , sb .substring (0 , sb .length () - 1 ),
85+ fetchDatabaseNameFromURL ()
86+ );
6887 } else {
69- String [] hostAndPort = hostSegment [0 ].split (":" );
88+ String [] hostAndPort = getSingleHostAndPort (hostSegment [0 ]);
89+ return new ConnectionInfo (
90+ ComponentsDefine .POSTGRESQL_DRIVER , DB_TYPE , hostAndPort [0 ], Integer .valueOf (hostAndPort [1 ]),
91+ fetchDatabaseNameFromURL ()
92+ );
93+ }
94+ }
95+
96+ /**
97+ * check the URI if IPv6 pattern matched(enclosed in square brackets, like [2001:db8::1234])
98+ */
99+ private boolean isIpv6Url (String hosts ) {
100+ return hosts .contains ("[" ) && url .contains ("]" );
101+ }
102+
103+ /**
104+ * parse the URL of a single host port and add it from the URL parameters
105+ */
106+ private String [] getSingleHostAndPort (String hostSegment ) {
107+ String host = "" ;
108+ String port = "" ;
109+ if (!isIpv6Url (hostSegment )) {
110+ String [] hostAndPort = hostSegment .split (":" );
111+ host = hostAndPort [0 ];
70112 if (hostAndPort .length != 1 ) {
71- return new ConnectionInfo (ComponentsDefine .POSTGRESQL_DRIVER , DB_TYPE , hostAndPort [0 ], Integer .valueOf (hostAndPort [1 ]), fetchDatabaseNameFromURL ());
113+ port = hostAndPort [1 ];
114+ }
115+ } else {
116+ host = hostSegment .substring (0 , hostSegment .indexOf ("]" ) + 1 );
117+ String [] ports = hostSegment .substring (hostSegment .indexOf ("]" ) + 1 ).split (":" );
118+ if (ports .length != 1 ) {
119+ port = ports [1 ];
120+ }
121+ }
122+ if (host .isEmpty ()) {
123+ String additionalHost = fetchFromUrlParams (URL_PARAMS_HOST_KEY );
124+ if (additionalHost != null ) {
125+ host = additionalHost ;
126+ }
127+ }
128+ if (port .isEmpty ()) {
129+ String additionalPort = fetchFromUrlParams (URL_PARAMS_PORT_KEY );
130+ if (additionalPort != null ) {
131+ port = additionalPort ;
72132 } else {
73- return new ConnectionInfo ( ComponentsDefine . POSTGRESQL_DRIVER , DB_TYPE , hostAndPort [ 0 ], DEFAULT_PORT , fetchDatabaseNameFromURL () );
133+ port = String . valueOf ( DEFAULT_PORT );
74134 }
75135 }
136+ return new String [] {
137+ host ,
138+ port
139+ };
76140 }
77141
142+ /**
143+ * fetch value from url parameters with specific key
144+ */
145+ private String fetchFromUrlParams (String key ) {
146+ int databaseAdditionalParamIndex = url .indexOf ("?" );
147+ if (databaseAdditionalParamIndex == -1 ) {
148+ return null ;
149+ }
150+ String [] paramArr = url .substring (databaseAdditionalParamIndex + 1 ).split ("&" );
151+ for (final String pair : paramArr ) {
152+ if (pair .contains (key )) {
153+ String [] paramsPair = pair .split ("=" );
154+ if (paramsPair .length != 1 ) {
155+ return paramsPair [1 ];
156+ }
157+ }
158+ }
159+ return null ;
160+ }
78161}
0 commit comments