4
4
import java .net .URI ;
5
5
import java .net .URISyntaxException ;
6
6
import java .util .Objects ;
7
+ import java .util .function .IntPredicate ;
7
8
8
9
public class Did implements Serializable {
9
10
10
11
private static final long serialVersionUID = -3127318269811273712L ;
11
12
12
- public static final String SCHEME = "did" ;
13
+ /*
14
+ * method-char = %x61-7A / DIGIT
15
+ */
16
+ static final IntPredicate METHOD_CHAR = ch -> (0x61 <= ch && ch <= 0x7A ) || ('0' <= ch && ch <= '9' );
13
17
18
+ public static final String SCHEME = "did" ;
19
+
14
20
protected final String method ;
15
- protected final String version ;
16
- protected final String methodSpecificId ;
21
+ protected final String specificId ;
17
22
18
- protected Did (final String method , final String version , final String methodSpecificId ) {
23
+ protected Did (final String method , final String specificId ) {
19
24
this .method = method ;
20
- this .version = version ;
21
- this .methodSpecificId = methodSpecificId ;
25
+ this .specificId = specificId ;
22
26
}
23
27
24
28
public static boolean isDid (final URI uri ) {
@@ -29,29 +33,32 @@ public static boolean isDid(final URI uri) {
29
33
|| isNotBlank (uri .getHost ())
30
34
|| isNotBlank (uri .getPath ())
31
35
|| isNotBlank (uri .getQuery ())
32
- || isNotBlank (uri .getFragment ())
33
- ) {
34
- return false ;
35
- }
36
+ || isNotBlank (uri .getFragment ())) {
37
+ return false ;
38
+ }
36
39
37
- final String [] parts = uri .getSchemeSpecificPart ().split (":" );
40
+ final String [] parts = uri .getSchemeSpecificPart ().split (":" , 2 );
38
41
39
- return parts .length == 2 || parts .length == 3 ;
42
+ return parts .length == 2
43
+ && parts [0 ].length () > 0
44
+ && parts [1 ].length () > 0
45
+ && parts [0 ].codePoints ().allMatch (METHOD_CHAR )
46
+ ;
40
47
}
41
48
42
49
public static boolean isDid (final String uri ) {
43
50
44
- if (isBlank ( uri ) ) {
51
+ if (uri == null ) {
45
52
return false ;
46
53
}
47
54
48
- final String [] parts = uri .split (":" );
55
+ final String [] parts = uri .split (":" , 3 );
49
56
50
- return ( parts .length == 3 || parts . length == 4 )
57
+ return parts .length == 3
51
58
&& Did .SCHEME .equalsIgnoreCase (parts [0 ])
52
- && ! parts [parts . length - 1 ].contains ( "/" ) // path
53
- && ! parts [parts . length - 1 ]. contains ( "?" ) // query
54
- && ! parts [parts . length - 1 ].contains ( "#" ) // fragment
59
+ && parts [1 ].length () > 0
60
+ && parts [2 ]. length () > 0
61
+ && parts [1 ].codePoints (). allMatch ( METHOD_CHAR )
55
62
;
56
63
}
57
64
@@ -61,19 +68,21 @@ public static boolean isDid(final String uri) {
61
68
* @param uri The source URI to be transformed into DID
62
69
* @return The new DID
63
70
*
64
- * @throws NullPointerException
65
- * If {@code uri} is {@code null}
71
+ * @throws NullPointerException If {@code uri} is {@code null}
66
72
*
67
- * @throws IllegalArgumentException
68
- * If the given {@code uri} is not valid DID
73
+ * @throws IllegalArgumentException If the given {@code uri} is not valid DID
69
74
*/
70
75
public static Did from (final URI uri ) {
71
76
72
- if (! isDid ( uri ) ) {
73
- throw new IllegalArgumentException ("The URI [" + uri + "] is not valid DID key, does not start with 'did:' ." );
77
+ if (uri == null ) {
78
+ throw new IllegalArgumentException ("The DID must not be null ." );
74
79
}
75
80
76
- return from (uri , uri .getSchemeSpecificPart ().split (":" ), 3 );
81
+ if (!Did .SCHEME .equalsIgnoreCase (uri .getScheme ())) {
82
+ throw new IllegalArgumentException ("The URI [" + uri + "] is not valid DID, must start with 'did:' prefix." );
83
+ }
84
+
85
+ return from (uri , uri .getSchemeSpecificPart ().split (":" , 2 ));
77
86
}
78
87
79
88
/**
@@ -82,59 +91,58 @@ public static Did from(final URI uri) {
82
91
* @param uri The source URI to be transformed into DID
83
92
* @return The new DID
84
93
*
85
- * @throws NullPointerException
86
- * If {@code uri} is {@code null}
94
+ * @throws NullPointerException If {@code uri} is {@code null}
87
95
*
88
- * @throws IllegalArgumentException
89
- * If the given {@code uri} is not valid DID
96
+ * @throws IllegalArgumentException If the given {@code uri} is not valid DID
90
97
*/
91
98
public static Did from (final String uri ) {
99
+ if (uri == null || uri .length () == 0 ) {
100
+ throw new IllegalArgumentException ("The DID must not be null or blank string." );
101
+ }
92
102
93
- if (!isDid (uri )) {
94
- throw new IllegalArgumentException ("The URI [" + uri + "] is not valid DID key, does not start with 'did:'." );
103
+ final String [] parts = uri .split (":" , 3 );
104
+
105
+ if (parts .length != 3 ) {
106
+ throw new IllegalArgumentException ("The URI [" + uri + "] is not valid DID, must be in form 'did:method:method-specific-id'." );
95
107
}
96
108
97
- return from (uri , uri .split (":" ), 4 );
98
- }
109
+ if (!Did .SCHEME .equalsIgnoreCase (parts [0 ])) {
110
+ throw new IllegalArgumentException ("The URI [" + uri + "] is not valid DID, must start with 'did:' prefix." );
111
+ }
99
112
100
- protected static Did from (final Object uri , final String [] parts , int max ) {
113
+ return from (uri , new String [] { parts [1 ], parts [2 ] });
114
+ }
101
115
102
- if (parts .length < max - 1
103
- || parts .length > max
104
- || isBlank (parts [max - 3 ])
105
- || isBlank (parts [max - 2 ])
106
- ) {
116
+ protected static Did from (final Object uri , final String [] parts ) {
117
+ if (parts .length != 2 ) {
107
118
throw new IllegalArgumentException ("The URI [" + uri + "] is not valid DID, must be in form 'did:method:method-specific-id'." );
108
119
}
109
120
110
- String methodSpecificId = parts [ max - 2 ];
111
- String version = "1" ; // default DID version
112
-
113
- if ( parts . length == max ) {
114
- if ( isBlank ( parts [ max - 1 ])) {
115
- throw new IllegalArgumentException ( "The URI [" + uri + "] is not valid DID, must be in form 'did:method:method-specific-id'." );
116
- }
117
- version = parts [max - 2 ];
118
- methodSpecificId = parts [ max - 1 ] ;
121
+ // check method
122
+ if ( parts [ 0 ]. length () == 0
123
+ || ! parts [ 0 ]. codePoints (). allMatch ( METHOD_CHAR )) {
124
+ throw new IllegalArgumentException ( "The URI [" + uri + "] is not valid DID, method [" + parts [ 0 ] + "] syntax is blank or invalid." );
125
+ }
126
+
127
+ // check method specific id
128
+ if ( parts [1 ]. length () == 0 ) {
129
+ throw new IllegalArgumentException ( "The URI [" + uri + "] is not valid DID, method specific id [" + parts [ 1 ] + "] is blank." ) ;
119
130
}
120
131
121
- return new Did (parts [max - 3 ], version , methodSpecificId );
132
+ return new Did (parts [0 ], parts [ 1 ] );
122
133
}
134
+
123
135
public String getMethod () {
124
136
return method ;
125
137
}
126
138
127
- public String getVersion () {
128
- return version ;
129
- }
130
-
131
139
public String getMethodSpecificId () {
132
- return methodSpecificId ;
140
+ return specificId ;
133
141
}
134
142
135
143
public URI toUri () {
136
144
try {
137
- return new URI (SCHEME , method + ":" + methodSpecificId , null );
145
+ return new URI (SCHEME , method + ":" + specificId , null );
138
146
} catch (URISyntaxException e ) {
139
147
throw new IllegalStateException (e );
140
148
}
@@ -150,23 +158,17 @@ public DidUrl asDidUrl() {
150
158
151
159
@ Override
152
160
public String toString () {
153
- final StringBuilder builder = new StringBuilder ()
154
- .append (SCHEME )
155
- .append (':' )
156
- .append (method )
157
- .append (':' );
158
-
159
- if (!"1" .equals (version )) {
160
- builder
161
- .append (version )
162
- .append (':' );
163
- }
164
- return builder .append (methodSpecificId ).toString ();
161
+ return new StringBuilder ()
162
+ .append (SCHEME )
163
+ .append (':' )
164
+ .append (method )
165
+ .append (':' )
166
+ .append (specificId ).toString ();
165
167
}
166
168
167
169
@ Override
168
170
public int hashCode () {
169
- return Objects .hash (method , methodSpecificId , version );
171
+ return Objects .hash (method , specificId );
170
172
}
171
173
172
174
@ Override
@@ -181,16 +183,15 @@ public boolean equals(final Object obj) {
181
183
return false ;
182
184
}
183
185
Did other = (Did ) obj ;
184
- return Objects .equals (method , other .method ) && Objects .equals (methodSpecificId , other .methodSpecificId )
185
- && Objects . equals ( version , other . version );
186
+ return Objects .equals (method , other .method ) && Objects .equals (specificId , other .specificId );
187
+
186
188
}
187
-
189
+
188
190
static final boolean isNotBlank (String value ) {
189
191
return value != null && !value .trim ().isEmpty ();
190
192
}
191
193
192
194
static final boolean isBlank (String value ) {
193
195
return value == null || value .trim ().isEmpty ();
194
196
}
195
-
196
197
}
0 commit comments