Add a constructor to Dsn that take a URI

Add a constructor the Dsn that takes a URI.

This change also removes some fields of the Dsn class
that are redundant, and add a final specifier to any
fields that can be.
This is not as simple since `extractProtocolInfo` really returns 2 items or 2 `null``s.

Actually, is it valid to have no `scheme` on a DSN? I think we can throw an exception earlier.

`new Dsn("publicKey:secretKey@host/9");` – this parses with `"publicKey"` as the `scheme`.