@@ -471,11 +471,11 @@ private String canonicalize(boolean coordinatesOnly) {
471471 }
472472 purl .append ("/" );
473473 if (namespace != null ) {
474- purl .append (encodePath (namespace ));
474+ purl .append (encodePath (namespace , ":" ));
475475 purl .append ("/" );
476476 }
477477 if (name != null ) {
478- purl .append (percentEncode (name ));
478+ purl .append (percentEncode (name , ":" ));
479479 }
480480 if (version != null ) {
481481 purl .append ("@" ).append (percentEncode (version ));
@@ -486,36 +486,44 @@ private String canonicalize(boolean coordinatesOnly) {
486486 qualifiers .entrySet ().stream ().forEachOrdered (entry -> {
487487 purl .append (toLowerCase (entry .getKey ()));
488488 purl .append ("=" );
489- purl .append (percentEncode (entry .getValue ()));
489+ purl .append (percentEncode (entry .getValue (), ":/" ));
490490 purl .append ("&" );
491491 });
492492 purl .setLength (purl .length () - 1 );
493493 }
494494 if (subpath != null ) {
495- purl .append ("#" ).append (encodePath (subpath ));
495+ purl .append ("#" ).append (encodePath (subpath , "?#+&=" ));
496496 }
497497 }
498498 return purl .toString ();
499499 }
500500
501+ private String percentEncode (final String input , final Charset charset , final String charsToExclude ) {
502+ return uriEncode (input , charset , charsToExclude );
503+ }
504+
505+ private String percentEncode (final String input , final String charsToExclude ) {
506+ return percentEncode (input , StandardCharsets .UTF_8 , charsToExclude );
507+ }
508+
501509 /**
502510 * Encodes the input in conformance with RFC 3986.
503511 *
504512 * @param input the String to encode
505513 * @return an encoded String
506514 */
507515 private String percentEncode (final String input ) {
508- return uriEncode (input , StandardCharsets .UTF_8 );
516+ return percentEncode (input , StandardCharsets .UTF_8 , null );
509517 }
510518
511- private static String uriEncode (String source , Charset charset ) {
512- if (source == null || source .isEmpty () ) {
519+ private static String uriEncode (String source , Charset charset , String chars ) {
520+ if (source == null || source .length () == 0 ) {
513521 return source ;
514522 }
515523
516524 StringBuilder builder = new StringBuilder ();
517525 for (byte b : source .getBytes (charset )) {
518- if (isUnreserved (b )) {
526+ if (isUnreserved (b ) || chars != null && chars . indexOf ( b ) != - 1 ) {
519527 builder .append ((char ) b );
520528 }
521529 else {
0 commit comments