| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#!/usr/bin/perl -w |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# Copyright (c) 2023-2025 Philipp Schafft |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# licensed under Artistic License 2.0 (see LICENSE file) |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
# ABSTRACT: format independent identifier object |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
package Data::Identifier; |
|
11
|
|
|
|
|
|
|
|
|
12
|
7
|
|
|
7
|
|
2000274
|
use v5.20; |
|
|
7
|
|
|
|
|
32
|
|
|
13
|
7
|
|
|
7
|
|
40
|
use strict; |
|
|
7
|
|
|
|
|
13
|
|
|
|
7
|
|
|
|
|
224
|
|
|
14
|
7
|
|
|
7
|
|
63
|
use warnings; |
|
|
7
|
|
|
|
|
13
|
|
|
|
7
|
|
|
|
|
523
|
|
|
15
|
|
|
|
|
|
|
|
|
16
|
7
|
|
|
7
|
|
43
|
use parent qw(Data::Identifier::Interface::Known Data::Identifier::Interface::Userdata); |
|
|
7
|
|
|
|
|
14
|
|
|
|
7
|
|
|
|
|
66
|
|
|
17
|
|
|
|
|
|
|
|
|
18
|
7
|
|
|
7
|
|
547
|
use Carp; |
|
|
7
|
|
|
|
|
14
|
|
|
|
7
|
|
|
|
|
497
|
|
|
19
|
7
|
|
|
7
|
|
13554
|
use Math::BigInt lib => 'GMP'; |
|
|
7
|
|
|
|
|
510100
|
|
|
|
7
|
|
|
|
|
97
|
|
|
20
|
7
|
|
|
7
|
|
302668
|
use URI; |
|
|
7
|
|
|
|
|
57481
|
|
|
|
7
|
|
|
|
|
3872
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
our $VERSION = v0.28; |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
use constant { |
|
25
|
7
|
|
|
|
|
1759
|
RE_UUID => qr/^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/, |
|
26
|
|
|
|
|
|
|
RE_OID => qr/^[0-2](?:\.(?:0|[1-9][0-9]*))+$/, |
|
27
|
|
|
|
|
|
|
RE_URI => qr/^[a-zA-Z][a-zA-Z0-9\+\.\-]+:/, |
|
28
|
|
|
|
|
|
|
RE_UINT => qr/^(?:0|[1-9][0-9]*)$/, |
|
29
|
|
|
|
|
|
|
RE_SINT => qr/^(?:0|-?[1-9][0-9]*)$/, |
|
30
|
|
|
|
|
|
|
RE_QID => qr/^[QPL][1-9][0-9]*$/, |
|
31
|
|
|
|
|
|
|
RE_DOI => qr/^10\.[1-9][0-9]+(?:\.[0-9]+)*\/./, |
|
32
|
|
|
|
|
|
|
RE_GTIN => qr/^[0-9]{8}(?:[0-9]{4,6})?$/, |
|
33
|
|
|
|
|
|
|
RE_UNICODE => qr/^U\+([0-9A-F]{4,7})$/, |
|
34
|
|
|
|
|
|
|
RE_SIMPLE_TAG => qr/^[^\p{upper case}\s]+$/, |
|
35
|
7
|
|
|
7
|
|
79
|
}; |
|
|
7
|
|
|
|
|
13
|
|
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
use constant { |
|
38
|
7
|
|
|
|
|
88040
|
WK_NULL => '00000000-0000-0000-0000-000000000000', # NULL, undef, ... |
|
39
|
|
|
|
|
|
|
WK_UUID => '8be115d2-dc2f-4a98-91e1-a6e3075cbc31', # uuid |
|
40
|
|
|
|
|
|
|
WK_OID => 'd08dc905-bbf6-4183-b219-67723c3c8374', # oid |
|
41
|
|
|
|
|
|
|
WK_URI => 'a8d1637d-af19-49e9-9ef8-6bc1fbcf6439', # uri |
|
42
|
|
|
|
|
|
|
WK_SID => 'f87a38cb-fd13-4e15-866c-e49901adbec5', # small-identifier |
|
43
|
|
|
|
|
|
|
WK_WD => 'ce7aae1e-a210-4214-926a-0ebca56d77e3', # wikidata-identifier |
|
44
|
|
|
|
|
|
|
WK_GTIN => '82d529be-0f00-4b4f-a43f-4a22de5f5312', # gtin |
|
45
|
|
|
|
|
|
|
WK_IBAN => 'b1418262-6bc9-459c-b4b0-a054d77db0ea', # iban |
|
46
|
|
|
|
|
|
|
WK_BIC => 'c8a3a132-f160-473c-b5f3-26a748f37e62', # bic |
|
47
|
|
|
|
|
|
|
WK_DOI => '931f155e-5a24-499b-9fbb-ed4efefe27fe', # doi |
|
48
|
|
|
|
|
|
|
WK_FC => 'd576b9d1-47d4-43ae-b7ec-bbea1fe009ba', # factgrid-identifier |
|
49
|
|
|
|
|
|
|
WK_UNICODE_CP => '5f167223-cc9c-4b2f-9928-9fe1b253b560', # unicode-code-point |
|
50
|
|
|
|
|
|
|
WK_SNI => '039e0bb7-5dd3-40ee-a98c-596ff6cce405', # sirtx-numerical-identifier |
|
51
|
|
|
|
|
|
|
WK_HDI => 'f8eb04ef-3b8a-402c-ad7c-1e6814cb1998', # host-defined-identifier |
|
52
|
|
|
|
|
|
|
WK_UDI => '05af99f9-4578-4b79-aabe-946d8e6f5888', # user-defined-identifier |
|
53
|
|
|
|
|
|
|
WK_CHAT0W => '2c7e15ed-aa2f-4e2f-9a1d-64df0c85875a', # chat-0-word-identifier |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
NS_WD => '9e10aca7-4a99-43ac-9368-6cbfa43636df', # Wikidata-namespace |
|
56
|
|
|
|
|
|
|
NS_FC => '6491f7a9-0b29-4ef1-992c-3681cea18182', # factgrid-namespace |
|
57
|
|
|
|
|
|
|
NS_INT => '5dd8ddbb-13a8-4d6c-9264-36e6dd6f9c99', # integer-namespace |
|
58
|
|
|
|
|
|
|
NS_DATE => 'fc43fbba-b959-4882-b4c8-90a288b7d416', # gregorian-date-namespace |
|
59
|
|
|
|
|
|
|
NS_GTIN => 'd95d8b1f-5091-4642-a6b0-a585313915f1', # gtin-namespace |
|
60
|
|
|
|
|
|
|
NS_UNICODE_CP => '132aa723-a373-48bf-a88d-69f1e00f00cf', # 'unicode-character-namespace' |
|
61
|
7
|
|
|
7
|
|
52
|
}; |
|
|
7
|
|
|
|
|
15
|
|
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# Features: |
|
64
|
|
|
|
|
|
|
my $enabled_oid = 1; |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
my %uuid_to_uriid_org = ( |
|
67
|
|
|
|
|
|
|
WK_UUID() => 'uuid', |
|
68
|
|
|
|
|
|
|
WK_OID() => 'oid', |
|
69
|
|
|
|
|
|
|
WK_URI() => 'uri', |
|
70
|
|
|
|
|
|
|
WK_SID() => 'sid', |
|
71
|
|
|
|
|
|
|
WK_GTIN() => 'gtin', |
|
72
|
|
|
|
|
|
|
WK_WD() => 'wikidata-identifier', |
|
73
|
|
|
|
|
|
|
); |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
my %uuid_org_to_uuid = map {$uuid_to_uriid_org{$_} => $_} keys %uuid_to_uriid_org; |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
my $well_known_uuid = __PACKAGE__->new(ise => WK_UUID, validate => RE_UUID); |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
my %well_known = ( |
|
80
|
|
|
|
|
|
|
uuid => $well_known_uuid, |
|
81
|
|
|
|
|
|
|
oid => __PACKAGE__->new($well_known_uuid => WK_OID, validate => RE_OID), |
|
82
|
|
|
|
|
|
|
uri => __PACKAGE__->new($well_known_uuid => WK_URI, validate => RE_URI), |
|
83
|
|
|
|
|
|
|
sid => __PACKAGE__->new($well_known_uuid => WK_SID, validate => RE_UINT), |
|
84
|
|
|
|
|
|
|
sni => __PACKAGE__->new($well_known_uuid => WK_SNI, validate => RE_UINT), |
|
85
|
|
|
|
|
|
|
wd => __PACKAGE__->new($well_known_uuid => WK_WD, validate => RE_QID, namespace => NS_WD, generate => 'id-based'), |
|
86
|
|
|
|
|
|
|
fc => __PACKAGE__->new($well_known_uuid => WK_FC, validate => RE_QID, namespace => NS_FC, generate => 'id-based'), |
|
87
|
|
|
|
|
|
|
gtin => __PACKAGE__->new($well_known_uuid => WK_GTIN, validate => RE_GTIN, namespace => NS_GTIN, generate => 'id-based'), |
|
88
|
|
|
|
|
|
|
iban => __PACKAGE__->new($well_known_uuid => WK_IBAN), |
|
89
|
|
|
|
|
|
|
bic => __PACKAGE__->new($well_known_uuid => WK_BIC), |
|
90
|
|
|
|
|
|
|
doi => __PACKAGE__->new($well_known_uuid => WK_DOI, validate => RE_DOI), |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# Unofficial, not part of public API: |
|
93
|
|
|
|
|
|
|
# Also used by Data::Identifier::Util! |
|
94
|
|
|
|
|
|
|
unicodecp => __PACKAGE__->new($well_known_uuid => WK_UNICODE_CP, validate => RE_UNICODE, namespace => NS_UNICODE_CP, generate => 'id-based'), |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
hdi => __PACKAGE__->new($well_known_uuid => WK_HDI, validate => RE_UINT), |
|
97
|
|
|
|
|
|
|
udi => __PACKAGE__->new($well_known_uuid => WK_UDI, validate => RE_UINT), |
|
98
|
|
|
|
|
|
|
null => __PACKAGE__->new($well_known_uuid => WK_NULL), |
|
99
|
|
|
|
|
|
|
); |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
my %registered; |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
$_->register foreach values %well_known; |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# Refill with sids: |
|
106
|
|
|
|
|
|
|
{ |
|
107
|
|
|
|
|
|
|
my %wk_sids = ( |
|
108
|
|
|
|
|
|
|
WK_NULL() => 0, # NULL |
|
109
|
|
|
|
|
|
|
'ddd60c5c-2934-404f-8f2d-fcb4da88b633' => 1, # also-shares-identifier |
|
110
|
|
|
|
|
|
|
WK_UUID() => 2, |
|
111
|
|
|
|
|
|
|
'bfae7574-3dae-425d-89b1-9c087c140c23' => 3, # tagname |
|
112
|
|
|
|
|
|
|
'7f265548-81dc-4280-9550-1bd0aa4bf748' => 4, # has-type |
|
113
|
|
|
|
|
|
|
WK_URI() => 5, |
|
114
|
|
|
|
|
|
|
WK_OID() => 6, |
|
115
|
|
|
|
|
|
|
# Unassigned: 7 |
|
116
|
|
|
|
|
|
|
'd0a4c6e2-ce2f-4d4c-b079-60065ac681f1' => 8, # language-tag-identifier |
|
117
|
|
|
|
|
|
|
WK_WD() => 9, |
|
118
|
|
|
|
|
|
|
'923b43ae-a50e-4db3-8655-ed931d0dd6d4' => 10, # specialises |
|
119
|
|
|
|
|
|
|
'eacbf914-52cf-4192-a42c-8ecd27c85ee1' => 11, # unicode-string |
|
120
|
|
|
|
|
|
|
'928d02b0-7143-4ec9-b5ac-9554f02d3fb1' => 12, # integer |
|
121
|
|
|
|
|
|
|
'dea3782c-6bcb-4ce9-8a39-f8dab399d75d' => 13, # unsigned-integer |
|
122
|
|
|
|
|
|
|
# Unassigned: 14, 15 |
|
123
|
|
|
|
|
|
|
'6ba648c2-3657-47c2-8541-9b73c3a9b2b4' => 16, # default-context |
|
124
|
|
|
|
|
|
|
'52a516d0-25d8-47c7-a6ba-80983e576c54' => 17, # proto-file |
|
125
|
|
|
|
|
|
|
'1cd4a6c6-0d7c-48d1-81e7-4e8d41fdb45d' => 18, # final-file-size |
|
126
|
|
|
|
|
|
|
'6085f87e-4797-4bb2-b23d-85ff7edc1da0' => 19, # text-fragment |
|
127
|
|
|
|
|
|
|
'4c9656eb-c130-42b7-9348-a1fee3f42050' => 20, # also-list-contains-also |
|
128
|
|
|
|
|
|
|
'298ef373-9731-491d-824d-b2836250e865' => 21, # proto-message |
|
129
|
|
|
|
|
|
|
'7be4d8c7-6a75-44cc-94f7-c87433307b26' => 22, # proto-entity |
|
130
|
|
|
|
|
|
|
'65bb36f2-b558-48af-8512-bca9150cca85' => 23, # proxy-type |
|
131
|
|
|
|
|
|
|
'a1c478b5-0a85-4b5b-96da-d250db14a67c' => 24, # flagged-as |
|
132
|
|
|
|
|
|
|
'59cfe520-ba32-48cc-b654-74f7a05779db' => 25, # marked-as |
|
133
|
|
|
|
|
|
|
'2bffc55d-7380-454e-bd53-c5acd525d692' => 26, # roaraudio-error-number |
|
134
|
|
|
|
|
|
|
WK_SID() => 27, |
|
135
|
|
|
|
|
|
|
'd2750351-aed7-4ade-aa80-c32436cc6030' => 28, # also-has-role |
|
136
|
|
|
|
|
|
|
'11d8962c-0a71-4d00-95ed-fa69182788a8' => 29, # also-has-comment |
|
137
|
|
|
|
|
|
|
'30710bdb-6418-42fb-96db-2278f3bfa17f' => 30, # also-has-description |
|
138
|
|
|
|
|
|
|
# Unassigned: 31 |
|
139
|
|
|
|
|
|
|
'448c50a8-c847-4bc7-856e-0db5fea8f23b' => 32, # final-file-encoding |
|
140
|
|
|
|
|
|
|
'79385945-0963-44aa-880a-bca4a42e9002' => 33, # final-file-hash |
|
141
|
|
|
|
|
|
|
'3fde5688-6e34-45e9-8f33-68f079b152c8' => 34, # SEEK_SET |
|
142
|
|
|
|
|
|
|
'bc598c52-642e-465b-b079-e9253cd6f190' => 35, # SEEK_CUR |
|
143
|
|
|
|
|
|
|
'06aff30f-70e8-48b4-8b20-9194d22fc460' => 36, # SEEK_END |
|
144
|
|
|
|
|
|
|
'59a5691a-6a19-4051-bc26-8db82c019df3' => 37, # inode |
|
145
|
|
|
|
|
|
|
WK_CHAT0W() => 112, # chat-0-word-identifier |
|
146
|
|
|
|
|
|
|
WK_SNI() => 113, # sirtx-numerical-identifier |
|
147
|
|
|
|
|
|
|
WK_GTIN() => 160, |
|
148
|
|
|
|
|
|
|
); |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
foreach my $ise (keys %wk_sids) { |
|
151
|
|
|
|
|
|
|
my $identifier = __PACKAGE__->new(ise => $ise); |
|
152
|
|
|
|
|
|
|
$identifier->{id_cache} //= {}; |
|
153
|
|
|
|
|
|
|
$identifier->{id_cache}->{WK_SID()} //= $wk_sids{$ise}; |
|
154
|
|
|
|
|
|
|
$identifier->register; # re-register |
|
155
|
|
|
|
|
|
|
} |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Refill with snis: |
|
159
|
|
|
|
|
|
|
{ |
|
160
|
|
|
|
|
|
|
my %wk_snis = ( |
|
161
|
|
|
|
|
|
|
WK_NULL() => 0, # NULL |
|
162
|
|
|
|
|
|
|
'039e0bb7-5dd3-40ee-a98c-596ff6cce405' => 10, # sirtx-numerical-identifier |
|
163
|
|
|
|
|
|
|
'f87a38cb-fd13-4e15-866c-e49901adbec5' => 115, # small-identifier |
|
164
|
|
|
|
|
|
|
'2bffc55d-7380-454e-bd53-c5acd525d692' => 116, # roaraudio-error-number |
|
165
|
|
|
|
|
|
|
WK_CHAT0W() => 118, # chat-0-word-identifier |
|
166
|
|
|
|
|
|
|
WK_UUID() => 119, |
|
167
|
|
|
|
|
|
|
WK_OID() => 120, |
|
168
|
|
|
|
|
|
|
WK_URI() => 121, |
|
169
|
|
|
|
|
|
|
WK_WD() => 123, |
|
170
|
|
|
|
|
|
|
); |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
foreach my $ise (keys %wk_snis) { |
|
173
|
|
|
|
|
|
|
my $identifier = __PACKAGE__->new(ise => $ise); |
|
174
|
|
|
|
|
|
|
$identifier->{id_cache} //= {}; |
|
175
|
|
|
|
|
|
|
$identifier->{id_cache}->{WK_SNI()} //= $wk_snis{$ise}; |
|
176
|
|
|
|
|
|
|
$identifier->register; # re-register |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
} |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# Update NULL: |
|
181
|
|
|
|
|
|
|
{ |
|
182
|
|
|
|
|
|
|
my $identifier = __PACKAGE__->new(uuid => WK_NULL); |
|
183
|
|
|
|
|
|
|
$identifier->{id_cache} //= {}; |
|
184
|
|
|
|
|
|
|
foreach my $type (WK_HDI, WK_CHAT0W) { |
|
185
|
|
|
|
|
|
|
$identifier->{id_cache}->{$type} //= 0; |
|
186
|
|
|
|
|
|
|
} |
|
187
|
|
|
|
|
|
|
$identifier->register; |
|
188
|
|
|
|
|
|
|
} |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# Some extra tags such as namespaces: |
|
191
|
|
|
|
|
|
|
foreach my $ise (NS_WD, NS_INT, NS_DATE) { |
|
192
|
|
|
|
|
|
|
my $identifier = __PACKAGE__->new(ise => $ise); |
|
193
|
|
|
|
|
|
|
$identifier->register; # re-register |
|
194
|
|
|
|
|
|
|
} |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
# Refill with displaynames |
|
197
|
|
|
|
|
|
|
{ |
|
198
|
|
|
|
|
|
|
my %displaynames = ( |
|
199
|
|
|
|
|
|
|
WK_NULL() => 'null', |
|
200
|
|
|
|
|
|
|
WK_UUID() => 'uuid', |
|
201
|
|
|
|
|
|
|
WK_OID() => 'oid', |
|
202
|
|
|
|
|
|
|
WK_URI() => 'uri', |
|
203
|
|
|
|
|
|
|
WK_SID() => 'small-identifier', |
|
204
|
|
|
|
|
|
|
WK_WD() => 'wikidata-identifier', |
|
205
|
|
|
|
|
|
|
WK_GTIN() => 'gtin', |
|
206
|
|
|
|
|
|
|
WK_IBAN() => 'iban', |
|
207
|
|
|
|
|
|
|
WK_BIC() => 'bic', |
|
208
|
|
|
|
|
|
|
WK_DOI() => 'doi', |
|
209
|
|
|
|
|
|
|
WK_FC() => 'factgrid-identifier', |
|
210
|
|
|
|
|
|
|
WK_UNICODE_CP() => 'unicode-code-point', |
|
211
|
|
|
|
|
|
|
WK_SNI() => 'sirtx-numerical-identifier', |
|
212
|
|
|
|
|
|
|
WK_HDI() => 'host-defined-identifier', |
|
213
|
|
|
|
|
|
|
WK_UDI() => 'user-defined-identifier', |
|
214
|
|
|
|
|
|
|
WK_CHAT0W() => 'chat-0-word-identifier', |
|
215
|
|
|
|
|
|
|
NS_WD() => 'Wikidata-namespace', |
|
216
|
|
|
|
|
|
|
NS_FC() => 'factgrid-namespace', |
|
217
|
|
|
|
|
|
|
NS_INT() => 'integer-namespace', |
|
218
|
|
|
|
|
|
|
NS_DATE() => 'gregorian-date-namespace', |
|
219
|
|
|
|
|
|
|
NS_UNICODE_CP() => 'unicode-character-namespace', |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
'ddd60c5c-2934-404f-8f2d-fcb4da88b633' => 'also-shares-identifier', |
|
222
|
|
|
|
|
|
|
'bfae7574-3dae-425d-89b1-9c087c140c23' => 'tagname', |
|
223
|
|
|
|
|
|
|
'7f265548-81dc-4280-9550-1bd0aa4bf748' => 'has-type', |
|
224
|
|
|
|
|
|
|
'd0a4c6e2-ce2f-4d4c-b079-60065ac681f1' => 'language-tag-identifier', |
|
225
|
|
|
|
|
|
|
'923b43ae-a50e-4db3-8655-ed931d0dd6d4' => 'specialises', |
|
226
|
|
|
|
|
|
|
'eacbf914-52cf-4192-a42c-8ecd27c85ee1' => 'unicode-string', |
|
227
|
|
|
|
|
|
|
'928d02b0-7143-4ec9-b5ac-9554f02d3fb1' => 'integer', |
|
228
|
|
|
|
|
|
|
'dea3782c-6bcb-4ce9-8a39-f8dab399d75d' => 'unsigned-integer', |
|
229
|
|
|
|
|
|
|
'6ba648c2-3657-47c2-8541-9b73c3a9b2b4' => 'default-context', |
|
230
|
|
|
|
|
|
|
'52a516d0-25d8-47c7-a6ba-80983e576c54' => 'proto-file', |
|
231
|
|
|
|
|
|
|
'1cd4a6c6-0d7c-48d1-81e7-4e8d41fdb45d' => 'final-file-size', |
|
232
|
|
|
|
|
|
|
'6085f87e-4797-4bb2-b23d-85ff7edc1da0' => 'text-fragment', |
|
233
|
|
|
|
|
|
|
'4c9656eb-c130-42b7-9348-a1fee3f42050' => 'also-list-contains-also', |
|
234
|
|
|
|
|
|
|
'298ef373-9731-491d-824d-b2836250e865' => 'proto-message', |
|
235
|
|
|
|
|
|
|
'7be4d8c7-6a75-44cc-94f7-c87433307b26' => 'proto-entity', |
|
236
|
|
|
|
|
|
|
'65bb36f2-b558-48af-8512-bca9150cca85' => 'proxy-type', |
|
237
|
|
|
|
|
|
|
'a1c478b5-0a85-4b5b-96da-d250db14a67c' => 'flagged-as', |
|
238
|
|
|
|
|
|
|
'59cfe520-ba32-48cc-b654-74f7a05779db' => 'marked-as', |
|
239
|
|
|
|
|
|
|
'2bffc55d-7380-454e-bd53-c5acd525d692' => 'roaraudio-error-number', |
|
240
|
|
|
|
|
|
|
'd2750351-aed7-4ade-aa80-c32436cc6030' => 'also-has-role', |
|
241
|
|
|
|
|
|
|
'11d8962c-0a71-4d00-95ed-fa69182788a8' => 'also-has-comment', |
|
242
|
|
|
|
|
|
|
'30710bdb-6418-42fb-96db-2278f3bfa17f' => 'also-has-description', |
|
243
|
|
|
|
|
|
|
'448c50a8-c847-4bc7-856e-0db5fea8f23b' => 'final-file-encoding', |
|
244
|
|
|
|
|
|
|
'79385945-0963-44aa-880a-bca4a42e9002' => 'final-file-hash', |
|
245
|
|
|
|
|
|
|
'3fde5688-6e34-45e9-8f33-68f079b152c8' => 'SEEK_SET', |
|
246
|
|
|
|
|
|
|
'bc598c52-642e-465b-b079-e9253cd6f190' => 'SEEK_CUR', |
|
247
|
|
|
|
|
|
|
'06aff30f-70e8-48b4-8b20-9194d22fc460' => 'SEEK_END', |
|
248
|
|
|
|
|
|
|
'59a5691a-6a19-4051-bc26-8db82c019df3' => 'inode', |
|
249
|
|
|
|
|
|
|
'53863a15-68d4-448d-bd69-a9b19289a191' => 'unsigned-integer-generator', |
|
250
|
|
|
|
|
|
|
'e8aa9e01-8d37-4b4b-8899-42ca0a2a906f' => 'signed-integer-generator', |
|
251
|
|
|
|
|
|
|
'd74f8c35-bcb8-465c-9a77-01010e8ed25c' => 'unicode-character-generator', |
|
252
|
|
|
|
|
|
|
'55febcc4-6655-4397-ae3d-2353b5856b34' => 'rgb-colour-generator', |
|
253
|
|
|
|
|
|
|
'97b7f241-e1c5-4f02-ae3c-8e31e501e1dc' => 'date-generator', |
|
254
|
|
|
|
|
|
|
'19659233-0a22-412c-bdf1-8ee9f8fc4086' => 'multiplicity-generator', |
|
255
|
|
|
|
|
|
|
'5ec197c3-1406-467c-96c7-4b1a6ec2c5c9' => 'minimum-multiplicity-generator', |
|
256
|
|
|
|
|
|
|
); |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
foreach my $ise (keys %displaynames) { |
|
259
|
|
|
|
|
|
|
my $identifier = __PACKAGE__->new(ise => $ise); |
|
260
|
|
|
|
|
|
|
$identifier->{displayname} //= $displaynames{$ise}; |
|
261
|
|
|
|
|
|
|
$identifier->register; # re-register |
|
262
|
|
|
|
|
|
|
} |
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
{ |
|
266
|
|
|
|
|
|
|
# ISE -> namespace |
|
267
|
|
|
|
|
|
|
my %namespaces_uint = ( |
|
268
|
|
|
|
|
|
|
'4a7fc2e2-854b-42ec-b24f-c7fece371865' => 'ac59062c-6ba2-44de-9f54-09e28f2c0b5c', # e621-post-identifier: e621-post-namespace |
|
269
|
|
|
|
|
|
|
'a0a4fae2-be6f-4a51-8326-6110ba845a16' => '69b7ff38-ca78-43a8-b9ea-66cb02312eef', # e621-pool-identifier: e621-pool-namespace |
|
270
|
|
|
|
|
|
|
'6e3590b6-2a0c-4850-a71f-8ba196a52280' => 'b96e5d94-0767-40fa-9864-5977eb507ae0', # danbooru2chanjp-post-identifier: danbooru2chanjp-post-namespace |
|
271
|
|
|
|
|
|
|
); |
|
272
|
|
|
|
|
|
|
my %namespaces_sint = ( |
|
273
|
|
|
|
|
|
|
'2bffc55d-7380-454e-bd53-c5acd525d692' => '744eaf4e-ae93-44d8-9ab5-744105222da6', # roaraudio-error-number: roaraudio-error-namespace |
|
274
|
|
|
|
|
|
|
); |
|
275
|
|
|
|
|
|
|
my %namespaces_simple_tag = ( |
|
276
|
|
|
|
|
|
|
'6fe0dbf0-624b-48b3-b558-0394c14bad6a' => '3623de4d-0dd4-4236-946a-2613467d50f1', # e621tag: e621tag-namespace |
|
277
|
|
|
|
|
|
|
'c5632c60-5da2-41af-8b60-75810b622756' => '93f2c36b-8cb6-4f2c-924b-98188f224235', # danbooru2chanjp-tag: danbooru2chanjp-tag-namespace |
|
278
|
|
|
|
|
|
|
); |
|
279
|
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
foreach my $ise (keys %namespaces_uint) { |
|
281
|
|
|
|
|
|
|
my $identifier = __PACKAGE__->new(ise => $ise); |
|
282
|
|
|
|
|
|
|
$identifier->{namespace} //= __PACKAGE__->new(ise => $namespaces_uint{$ise}); |
|
283
|
|
|
|
|
|
|
$identifier->{validate} //= RE_UINT; |
|
284
|
|
|
|
|
|
|
$identifier->{generate} //= 'id-based'; |
|
285
|
|
|
|
|
|
|
$identifier->register; # re-register |
|
286
|
|
|
|
|
|
|
} |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
foreach my $ise (keys %namespaces_sint) { |
|
289
|
|
|
|
|
|
|
my $identifier = __PACKAGE__->new(ise => $ise); |
|
290
|
|
|
|
|
|
|
$identifier->{namespace} //= __PACKAGE__->new(ise => $namespaces_sint{$ise}); |
|
291
|
|
|
|
|
|
|
$identifier->{validate} //= RE_SINT; |
|
292
|
|
|
|
|
|
|
$identifier->{generate} //= 'id-based'; |
|
293
|
|
|
|
|
|
|
$identifier->register; # re-register |
|
294
|
|
|
|
|
|
|
} |
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
foreach my $ise (keys %namespaces_simple_tag) { |
|
297
|
|
|
|
|
|
|
my $identifier = __PACKAGE__->new(ise => $ise); |
|
298
|
|
|
|
|
|
|
$identifier->{namespace} //= __PACKAGE__->new(ise => $namespaces_simple_tag{$ise}); |
|
299
|
|
|
|
|
|
|
$identifier->{validate} //= RE_SIMPLE_TAG; |
|
300
|
|
|
|
|
|
|
$identifier->{generate} //= 'id-based'; |
|
301
|
|
|
|
|
|
|
$identifier->register; # re-register |
|
302
|
|
|
|
|
|
|
} |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
# validate => RE_QID, namespace => NS_FC, generate => 'id-based' |
|
305
|
|
|
|
|
|
|
} |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
# Call this after after we loaded all our stuff and before anyone else will register stuff: |
|
308
|
|
|
|
|
|
|
__PACKAGE__->_known_provider('wellknown'); |
|
309
|
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub new { |
|
312
|
1113
|
|
|
1113
|
1
|
11605
|
my ($pkg, $type, $id, %opts) = @_; |
|
313
|
1113
|
|
|
|
|
2044
|
my $self = bless {}; |
|
314
|
|
|
|
|
|
|
|
|
315
|
1113
|
50
|
|
|
|
2198
|
croak 'No type given' unless defined $type; |
|
316
|
1113
|
50
|
|
|
|
1941
|
croak 'No id given' unless defined $id; |
|
317
|
|
|
|
|
|
|
|
|
318
|
1113
|
100
|
100
|
|
|
4618
|
if (!ref($type) && $type eq 'from') { |
|
319
|
55
|
50
|
|
|
|
105
|
if (ref($id)) { |
|
320
|
0
|
|
|
|
|
0
|
my $from = $id; |
|
321
|
0
|
0
|
0
|
|
|
0
|
if ($id->isa('Data::Identifier')) { |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
322
|
0
|
0
|
|
|
|
0
|
if (scalar(keys %opts)) { |
|
323
|
0
|
|
|
|
|
0
|
$type = $id->type; |
|
324
|
0
|
|
|
|
|
0
|
$id = $id->id; |
|
325
|
|
|
|
|
|
|
} else { |
|
326
|
0
|
|
|
|
|
0
|
return $id; |
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
} elsif ($id->isa('URI')) { |
|
329
|
0
|
|
|
|
|
0
|
$type = 'uri'; |
|
330
|
|
|
|
|
|
|
} elsif ($id->isa('Mojo::URL')) { |
|
331
|
0
|
|
|
|
|
0
|
$type = 'uri'; |
|
332
|
0
|
|
|
|
|
0
|
$id = $id->to_string; |
|
333
|
|
|
|
|
|
|
} elsif ($id->isa('Data::URIID::Result')) { |
|
334
|
0
|
|
0
|
0
|
|
0
|
$opts{displayname} //= sub { return $from->attribute('displayname', default => undef) }; |
|
|
0
|
|
|
|
|
0
|
|
|
335
|
0
|
|
|
|
|
0
|
$type = $id->id_type; |
|
336
|
0
|
|
|
|
|
0
|
$id = $id->id; |
|
337
|
|
|
|
|
|
|
} elsif ($id->isa('Data::URIID::Base') || $id->isa('Data::URIID::Colour') || $id->isa('Data::URIID::Service')) { |
|
338
|
|
|
|
|
|
|
#$opts{displayname} //= $id->name if $id->isa('Data::URIID::Service'); |
|
339
|
0
|
|
0
|
|
|
0
|
$opts{displayname} //= $id->displayname(default => undef, no_defaults => 1); |
|
340
|
0
|
|
|
|
|
0
|
$type = 'ise'; |
|
341
|
0
|
|
|
|
|
0
|
$id = $id->ise; |
|
342
|
|
|
|
|
|
|
} elsif ($id->isa('Data::TagDB::Tag')) { |
|
343
|
0
|
|
0
|
0
|
|
0
|
$opts{displayname} //= sub { $from->displayname }; |
|
|
0
|
|
|
|
|
0
|
|
|
344
|
0
|
|
|
|
|
0
|
$type = 'ise'; |
|
345
|
0
|
|
|
|
|
0
|
$id = $id->ise; |
|
346
|
|
|
|
|
|
|
} elsif ($id->isa('File::FStore::File') || $id->isa('File::FStore::Adder') || $id->isa('File::FStore::Base')) { |
|
347
|
0
|
|
|
|
|
0
|
$type = 'ise'; |
|
348
|
0
|
|
|
|
|
0
|
$id = $id->contentise; |
|
349
|
|
|
|
|
|
|
} elsif ($id->isa('SIRTX::Datecode')) { |
|
350
|
0
|
|
|
|
|
0
|
$id = $id->as('Data::Identifier'); |
|
351
|
0
|
0
|
|
|
|
0
|
unless (scalar(keys %opts)) { |
|
352
|
0
|
|
|
|
|
0
|
return $id->as('Data::Identifier'); |
|
353
|
|
|
|
|
|
|
} |
|
354
|
0
|
|
|
|
|
0
|
$type = $id->type; |
|
355
|
0
|
|
|
|
|
0
|
$id = $id->id; |
|
356
|
|
|
|
|
|
|
} elsif ($id->isa('Business::ISBN')) { |
|
357
|
0
|
|
|
|
|
0
|
$type = $well_known{gtin}; |
|
358
|
0
|
|
|
|
|
0
|
$id = $id->as_isbn13->as_string([]); |
|
359
|
|
|
|
|
|
|
} elsif ($id->isa('Data::Identifier::Interface::Simple')) { |
|
360
|
|
|
|
|
|
|
# TODO: We cannot call $id->as('Data::Identifier') here as much as that would be fun, |
|
361
|
|
|
|
|
|
|
# as this might in turn call exactly this code again resulting in a deep recursion. |
|
362
|
|
|
|
|
|
|
# A future version might come up with some trick here. |
|
363
|
0
|
|
|
|
|
0
|
$type = 'ise'; |
|
364
|
0
|
|
|
|
|
0
|
$id = $id->ise; |
|
365
|
|
|
|
|
|
|
} else { |
|
366
|
0
|
|
|
|
|
0
|
croak 'Unsupported input data'; |
|
367
|
|
|
|
|
|
|
} |
|
368
|
|
|
|
|
|
|
} else { |
|
369
|
|
|
|
|
|
|
# If it's not a ref, try as ise. |
|
370
|
55
|
|
|
|
|
71
|
$type = 'ise'; |
|
371
|
|
|
|
|
|
|
} |
|
372
|
|
|
|
|
|
|
} |
|
373
|
|
|
|
|
|
|
|
|
374
|
1113
|
100
|
100
|
|
|
3356
|
if (!ref($type) && $type eq 'ise') { |
|
375
|
881
|
50
|
|
|
|
1519
|
croak 'Undefined identifier but type is ISE' unless defined $id; |
|
376
|
|
|
|
|
|
|
|
|
377
|
881
|
50
|
|
|
|
5071
|
if ($id =~ /^[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$/) { # allow less normalised form than RE_UUID |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
378
|
881
|
|
|
|
|
1296
|
$type = $well_known_uuid; |
|
379
|
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
# For bootstrap only. |
|
381
|
881
|
100
|
66
|
|
|
2138
|
if (!defined($type) && $id eq '8be115d2-dc2f-4a98-91e1-a6e3075cbc31') { |
|
382
|
7
|
|
|
|
|
197
|
$self->{type} = $well_known_uuid = $type = $self; |
|
383
|
7
|
|
|
|
|
27
|
$self->{id} = $id; |
|
384
|
|
|
|
|
|
|
} |
|
385
|
|
|
|
|
|
|
} elsif ($id =~ RE_OID) { |
|
386
|
0
|
|
|
|
|
0
|
$type = 'oid'; |
|
387
|
|
|
|
|
|
|
} elsif ($id =~ RE_URI) { |
|
388
|
0
|
|
|
|
|
0
|
$type = 'uri'; |
|
389
|
|
|
|
|
|
|
} else { |
|
390
|
0
|
|
|
|
|
0
|
croak 'Not a valid ISE identifier'; |
|
391
|
|
|
|
|
|
|
} |
|
392
|
|
|
|
|
|
|
} |
|
393
|
|
|
|
|
|
|
|
|
394
|
1113
|
100
|
|
|
|
2097
|
unless (ref $type) { |
|
395
|
133
|
100
|
|
|
|
417
|
if ($type =~ /^[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$/) { # allow less normalised form than RE_UUID |
|
|
|
100
|
|
|
|
|
|
|
396
|
6
|
|
|
|
|
14
|
$type = $pkg->new(uuid => $type); |
|
397
|
6
|
|
|
|
|
12
|
$type->register; |
|
398
|
|
|
|
|
|
|
} elsif ($type eq 'wellknown') { |
|
399
|
8
|
|
|
|
|
19
|
$self = $well_known{$id}; |
|
400
|
8
|
50
|
|
|
|
20
|
croak 'Unknown well-known' unless defined $self; |
|
401
|
8
|
|
|
|
|
27
|
return $self; |
|
402
|
|
|
|
|
|
|
} else { |
|
403
|
119
|
|
|
|
|
227
|
$type = $well_known{$type}; |
|
404
|
|
|
|
|
|
|
} |
|
405
|
125
|
50
|
|
|
|
252
|
croak 'Unknown type name' unless defined $type; |
|
406
|
|
|
|
|
|
|
} |
|
407
|
|
|
|
|
|
|
|
|
408
|
1105
|
50
|
|
|
|
3257
|
croak 'Not a valid type' unless $type->isa(__PACKAGE__); |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
# we normalise URIs first as they may then normalised again |
|
411
|
1105
|
100
|
100
|
|
|
3466
|
if ($type == ($well_known{uri} // 0)) { |
|
412
|
3
|
|
|
|
|
8
|
my $uri = $id.''; # force stringification |
|
413
|
|
|
|
|
|
|
|
|
414
|
3
|
100
|
|
|
|
44
|
if ($uri =~ m#^urn:uuid:([0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12})$#) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
415
|
1
|
|
|
|
|
2
|
$id = $1; |
|
416
|
1
|
|
|
|
|
2
|
$type = $well_known_uuid; |
|
417
|
|
|
|
|
|
|
} elsif ($uri =~ m#^urn:oid:([0-2](?:\.(?:0|[1-9][0-9]*))+)$#) { |
|
418
|
0
|
|
|
|
|
0
|
$id = $1; |
|
419
|
0
|
|
|
|
|
0
|
$type = $well_known{oid}; |
|
420
|
|
|
|
|
|
|
} elsif ($uri =~ m#^https?://www\.wikidata\.org/entity/([QPL][1-9][0-9]*)$#) { |
|
421
|
0
|
|
|
|
|
0
|
$id = $1; |
|
422
|
0
|
|
|
|
|
0
|
$type = $well_known{wd}; |
|
423
|
|
|
|
|
|
|
} elsif ($uri =~ m#^https?://doi\.org/(10\..+)$#) { |
|
424
|
0
|
|
|
|
|
0
|
$id = $1; |
|
425
|
0
|
|
|
|
|
0
|
$type = $well_known{doi}; |
|
426
|
|
|
|
|
|
|
} elsif ($uri =~ m#^https?://uriid\.org/([^/]+)/[^/]+#) { |
|
427
|
2
|
|
|
|
|
9
|
my $ptype = $1; |
|
428
|
2
|
50
|
66
|
|
|
19
|
if (defined($uuid_org_to_uuid{$ptype}) || $ptype =~ RE_UUID) { |
|
429
|
2
|
|
|
|
|
14
|
my $u = URI->new($uri); |
|
430
|
2
|
|
|
|
|
13260
|
my @path_segments = $u->path_segments; |
|
431
|
2
|
50
|
33
|
|
|
213
|
if (scalar(@path_segments) == 3 && $path_segments[0] eq '') { |
|
432
|
2
|
|
66
|
|
|
23
|
$type = $pkg->new(uuid => ($uuid_org_to_uuid{$path_segments[1]} // $path_segments[1])); |
|
433
|
2
|
|
|
|
|
21
|
$id = $path_segments[2]; |
|
434
|
|
|
|
|
|
|
} |
|
435
|
|
|
|
|
|
|
} |
|
436
|
|
|
|
|
|
|
} |
|
437
|
|
|
|
|
|
|
} |
|
438
|
|
|
|
|
|
|
|
|
439
|
1105
|
100
|
50
|
|
|
2651
|
if ($type == ($well_known_uuid // 0)) { |
|
|
|
100
|
50
|
|
|
|
|
|
440
|
1025
|
|
|
|
|
1967
|
$id = lc($id); # normalise |
|
441
|
|
|
|
|
|
|
} elsif ($type == ($well_known{oid} // 0)) { |
|
442
|
1
|
50
|
|
|
|
7
|
if ($id =~ /^2\.25\.([1-9][0-9]*)$/) { |
|
443
|
1
|
|
|
|
|
7
|
my $hex = Math::BigInt->new($1)->as_hex; |
|
444
|
1
|
|
|
|
|
809
|
$hex =~ s/^0x//; |
|
445
|
1
|
|
|
|
|
6
|
$hex = ('0' x (32 - length($hex))) . $hex; |
|
446
|
1
|
|
|
|
|
16
|
$hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12})$/$1-$2-$3-$4-$5/; |
|
447
|
1
|
|
|
|
|
3
|
$type = $well_known_uuid; |
|
448
|
1
|
|
|
|
|
3
|
$id = $hex; |
|
449
|
|
|
|
|
|
|
} |
|
450
|
|
|
|
|
|
|
} |
|
451
|
|
|
|
|
|
|
|
|
452
|
1105
|
100
|
|
|
|
3235
|
if (defined(my $v = $registered{$type->uuid}{$id})) { |
|
453
|
552
|
|
|
|
|
1617
|
return $v; |
|
454
|
|
|
|
|
|
|
} |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
|
|
457
|
553
|
100
|
|
|
|
1205
|
if (defined $type->{validate}) { |
|
458
|
544
|
50
|
|
|
|
6260
|
croak 'Identifier did not validate against type' unless $id =~ $type->{validate}; |
|
459
|
|
|
|
|
|
|
} |
|
460
|
|
|
|
|
|
|
|
|
461
|
553
|
|
|
|
|
1343
|
$self->{type} = $type; |
|
462
|
553
|
|
|
|
|
952
|
$self->{id} = $id; |
|
463
|
|
|
|
|
|
|
|
|
464
|
553
|
|
|
|
|
1005
|
foreach my $key (qw(validate namespace generator request generate displayname)) { |
|
465
|
3318
|
100
|
|
|
|
6146
|
next unless defined $opts{$key}; |
|
466
|
164
|
|
66
|
|
|
554
|
$self->{$key} //= $opts{$key}; |
|
467
|
|
|
|
|
|
|
} |
|
468
|
|
|
|
|
|
|
|
|
469
|
553
|
|
|
|
|
759
|
foreach my $key (qw(namespace generator)) { |
|
470
|
1106
|
100
|
|
|
|
2447
|
if (defined(my $v = $self->{$key})) { |
|
471
|
31
|
50
|
|
|
|
75
|
unless (ref $v) { |
|
472
|
31
|
|
|
|
|
114
|
$self->{$key} = $pkg->new(from => $v); |
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
} |
|
475
|
|
|
|
|
|
|
} |
|
476
|
|
|
|
|
|
|
|
|
477
|
553
|
|
|
|
|
1739
|
return bless $self; |
|
478
|
|
|
|
|
|
|
} |
|
479
|
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
#@returns __PACKAGE__ |
|
482
|
|
|
|
|
|
|
sub random { |
|
483
|
0
|
|
|
0
|
1
|
0
|
my ($pkg, %opts) = @_; |
|
484
|
0
|
|
0
|
|
|
0
|
my $type = $opts{type} // 'uuid'; |
|
485
|
|
|
|
|
|
|
|
|
486
|
0
|
0
|
|
|
|
0
|
if (ref $type) { |
|
487
|
0
|
0
|
|
|
|
0
|
if ($type == $well_known_uuid) { |
|
488
|
0
|
|
|
|
|
0
|
$type = 'uuid'; |
|
489
|
|
|
|
|
|
|
} else { |
|
490
|
0
|
|
|
|
|
0
|
croak 'Invalid/Unsupported type'; |
|
491
|
|
|
|
|
|
|
} |
|
492
|
|
|
|
|
|
|
} |
|
493
|
|
|
|
|
|
|
|
|
494
|
0
|
0
|
0
|
|
|
0
|
if ($type ne 'ise' && $type ne 'uuid') { |
|
495
|
0
|
|
|
|
|
0
|
croak 'Invalid/Unsupported type'; |
|
496
|
|
|
|
|
|
|
} |
|
497
|
|
|
|
|
|
|
|
|
498
|
0
|
|
|
|
|
0
|
require Data::Identifier::Generate; |
|
499
|
0
|
|
|
|
|
0
|
my $uuid = Data::Identifier::Generate->_random(%opts{'sources'}); |
|
500
|
0
|
|
|
|
|
0
|
return $pkg->new(uuid => $uuid, %opts{'displayname'}); |
|
501
|
|
|
|
|
|
|
} |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
#@deprecated |
|
506
|
|
|
|
|
|
|
sub wellknown { |
|
507
|
0
|
|
|
0
|
1
|
0
|
my ($pkg, @args) = @_; |
|
508
|
0
|
|
|
|
|
0
|
return $pkg->known('wellknown', @args); |
|
509
|
|
|
|
|
|
|
} |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
#@returns __PACKAGE__ |
|
513
|
|
|
|
|
|
|
sub type { |
|
514
|
46
|
|
|
46
|
1
|
2958
|
my ($self) = @_; |
|
515
|
46
|
|
|
|
|
118
|
return $self->{type}; |
|
516
|
|
|
|
|
|
|
} |
|
517
|
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
sub id { |
|
521
|
25
|
|
|
25
|
1
|
25
|
my ($self) = @_; |
|
522
|
25
|
|
|
|
|
64
|
return $self->{id}; |
|
523
|
|
|
|
|
|
|
} |
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
sub uuid { |
|
527
|
7208
|
|
|
7208
|
1
|
23998
|
my ($self, %opts) = @_; |
|
528
|
|
|
|
|
|
|
|
|
529
|
7208
|
50
|
100
|
|
|
38660
|
return $self->{id_cache}{WK_UUID()} if !$opts{no_defaults} && defined($self->{id_cache}) && defined($self->{id_cache}{WK_UUID()}); |
|
|
|
|
66
|
|
|
|
|
|
530
|
|
|
|
|
|
|
|
|
531
|
7208
|
100
|
|
|
|
13935
|
if ($self->{type} == $well_known_uuid) { |
|
532
|
7181
|
|
|
|
|
30213
|
return $self->{id}; |
|
533
|
|
|
|
|
|
|
} |
|
534
|
|
|
|
|
|
|
|
|
535
|
27
|
100
|
|
|
|
47
|
unless ($opts{no_defaults}) { |
|
536
|
|
|
|
|
|
|
# Try to generate a UUID and recheck cache: |
|
537
|
3
|
|
|
|
|
8
|
$self->_generate; |
|
538
|
3
|
50
|
33
|
|
|
22
|
return $self->{id_cache}{WK_UUID()} if defined($self->{id_cache}) && defined($self->{id_cache}{WK_UUID()}); |
|
539
|
|
|
|
|
|
|
} |
|
540
|
|
|
|
|
|
|
|
|
541
|
24
|
50
|
|
|
|
96
|
return $opts{default} if exists $opts{default}; |
|
542
|
0
|
|
|
|
|
0
|
croak 'Identifier has no valid UUID'; |
|
543
|
|
|
|
|
|
|
} |
|
544
|
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
sub oid { |
|
546
|
916
|
|
|
916
|
1
|
1593
|
my ($self, %opts) = @_; |
|
547
|
916
|
|
|
|
|
1284
|
my $type = $well_known{oid}; |
|
548
|
|
|
|
|
|
|
|
|
549
|
916
|
100
|
66
|
|
|
4723
|
return $self->{id_cache}{WK_OID()} if !$opts{no_defaults} && defined($self->{id_cache}) && defined($self->{id_cache}{WK_OID()}); |
|
|
|
|
100
|
|
|
|
|
|
550
|
|
|
|
|
|
|
|
|
551
|
428
|
50
|
|
|
|
912
|
if ($self->{type} == $type) { |
|
552
|
0
|
|
|
|
|
0
|
return $self->{id}; |
|
553
|
|
|
|
|
|
|
} |
|
554
|
|
|
|
|
|
|
|
|
555
|
428
|
50
|
|
|
|
892
|
unless ($opts{no_defaults}) { |
|
556
|
428
|
50
|
|
|
|
786
|
if (defined(my $uuid = $self->uuid(default => undef))) { |
|
557
|
428
|
|
|
|
|
2544
|
return $self->{id_cache}{WK_OID()} = sprintf('2.25.%s', Math::BigInt->new('0x'.$uuid =~ tr/-//dr)); |
|
558
|
|
|
|
|
|
|
} |
|
559
|
|
|
|
|
|
|
} |
|
560
|
|
|
|
|
|
|
|
|
561
|
0
|
0
|
|
|
|
0
|
return $opts{default} if exists $opts{default}; |
|
562
|
0
|
|
|
|
|
0
|
croak 'Identifier has no valid OID'; |
|
563
|
|
|
|
|
|
|
} |
|
564
|
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
sub uri { |
|
566
|
917
|
|
|
917
|
1
|
1940
|
my ($self, %opts) = @_; |
|
567
|
917
|
|
|
|
|
1376
|
my $type = $well_known{uri}; |
|
568
|
|
|
|
|
|
|
|
|
569
|
917
|
100
|
66
|
|
|
5735
|
if (!$opts{no_defaults} && !defined($opts{style}) && defined($self->{id_cache}) && defined($self->{id_cache}{WK_URI()})) { |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
570
|
488
|
|
|
|
|
1355
|
return $self->{id_cache}{WK_URI()}; |
|
571
|
|
|
|
|
|
|
} |
|
572
|
|
|
|
|
|
|
|
|
573
|
429
|
50
|
|
|
|
978
|
if ($self->{type} == $type) { |
|
574
|
0
|
|
|
|
|
0
|
return $self->{id}; |
|
575
|
|
|
|
|
|
|
} |
|
576
|
|
|
|
|
|
|
|
|
577
|
429
|
|
100
|
|
|
1883
|
$opts{style} //= 'urn'; |
|
578
|
|
|
|
|
|
|
|
|
579
|
429
|
50
|
|
|
|
772
|
unless ($opts{no_defaults}) { |
|
580
|
429
|
50
|
66
|
|
|
1828
|
if ($self->{type} == $well_known{wd}) { |
|
|
|
50
|
33
|
|
|
|
|
|
|
|
100
|
33
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
581
|
0
|
|
|
|
|
0
|
return $self->{id_cache}{WK_URI()} = sprintf('http://www.wikidata.org/entity/%s', $self->{id}); |
|
582
|
|
|
|
|
|
|
} elsif ($self->{type} == $well_known{doi}) { |
|
583
|
0
|
|
|
|
|
0
|
return $self->{id_cache}{WK_URI()} = sprintf('https://doi.org/%s', $self->{id}); |
|
584
|
|
|
|
|
|
|
} elsif (defined(my $uuid = $self->uuid(default => undef)) && $opts{style} eq 'urn') { |
|
585
|
428
|
|
|
|
|
1940
|
return $self->{id_cache}{WK_URI()} = sprintf('urn:uuid:%s', $uuid); |
|
586
|
|
|
|
|
|
|
} elsif ($enabled_oid && defined(my $oid = $self->oid(default => undef)) && $opts{style} eq 'urn') { |
|
587
|
0
|
|
|
|
|
0
|
return $self->{id_cache}{WK_URI()} = sprintf('urn:oid:%s', $oid); |
|
588
|
|
|
|
|
|
|
} else { |
|
589
|
1
|
|
|
|
|
886
|
my $u = URI->new("https://uriid.org/"); |
|
590
|
1
|
|
|
|
|
13899
|
my $type_uuid = $self->{type}->uuid; |
|
591
|
1
|
|
33
|
|
|
13
|
$u->path_segments('', $uuid_to_uriid_org{$type_uuid} // $type_uuid, $self->{id}); |
|
592
|
1
|
|
|
|
|
218
|
return $self->{id_cache}{WK_URI()} = $u; |
|
593
|
|
|
|
|
|
|
} |
|
594
|
|
|
|
|
|
|
} |
|
595
|
|
|
|
|
|
|
|
|
596
|
0
|
0
|
|
|
|
0
|
return $opts{default} if exists $opts{default}; |
|
597
|
0
|
|
|
|
|
0
|
croak 'Identifier has no valid URI'; |
|
598
|
|
|
|
|
|
|
} |
|
599
|
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
sub sid { |
|
601
|
919
|
|
|
919
|
1
|
1712
|
my ($self, %opts) = @_; |
|
602
|
919
|
|
|
|
|
1300
|
my $type = $well_known{sid}; |
|
603
|
919
|
100
|
66
|
|
|
3906
|
return $self->{id_cache}{WK_SID()} if defined($self->{id_cache}) && defined($self->{id_cache}{WK_SID()}); |
|
604
|
294
|
50
|
|
|
|
764
|
if ($self->{type} == $type) { |
|
605
|
0
|
|
|
|
|
0
|
return $self->{id}; |
|
606
|
|
|
|
|
|
|
} |
|
607
|
|
|
|
|
|
|
|
|
608
|
294
|
50
|
|
|
|
1102
|
return $opts{default} if exists $opts{default}; |
|
609
|
0
|
|
|
|
|
0
|
croak 'Identifier has no valid SID'; |
|
610
|
|
|
|
|
|
|
} |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
sub ise { |
|
615
|
22
|
|
|
22
|
1
|
43
|
my ($self, %opts) = @_; |
|
616
|
22
|
|
|
|
|
41
|
my $type = $self->{type}; |
|
617
|
22
|
|
|
|
|
35
|
my $have_default = exists $opts{default}; |
|
618
|
22
|
|
|
|
|
83
|
my $default = delete $opts{default}; |
|
619
|
22
|
|
|
|
|
28
|
my $value; |
|
620
|
|
|
|
|
|
|
|
|
621
|
22
|
50
|
33
|
|
|
88
|
if ($type == $well_known{uuid} || $type == $well_known{oid} || $type == $well_known{uri}) { |
|
|
|
|
33
|
|
|
|
|
|
622
|
22
|
|
|
|
|
43
|
$value = $self->{id}; |
|
623
|
|
|
|
|
|
|
} else { |
|
624
|
0
|
|
|
|
|
0
|
$opts{default} = undef; |
|
625
|
0
|
|
0
|
|
|
0
|
$value = $self->uuid(%opts) // $self->oid(%opts) // $self->uri(%opts); |
|
|
|
|
0
|
|
|
|
|
|
626
|
|
|
|
|
|
|
} |
|
627
|
|
|
|
|
|
|
|
|
628
|
22
|
50
|
|
|
|
112
|
return $value if defined $value; |
|
629
|
0
|
0
|
|
|
|
0
|
return $default if $have_default; |
|
630
|
0
|
|
|
|
|
0
|
croak 'Identifier has no valid ISE'; |
|
631
|
|
|
|
|
|
|
} |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
sub as { |
|
635
|
128
|
|
|
128
|
1
|
245
|
my ($self, $as, %opts) = @_; |
|
636
|
|
|
|
|
|
|
|
|
637
|
128
|
100
|
66
|
|
|
252
|
$as = $opts{rawtype} if $as eq 'raw' && defined($opts{rawtype}); |
|
638
|
|
|
|
|
|
|
|
|
639
|
128
|
100
|
66
|
|
|
143
|
if (ref($as) && eval {$as->isa(__PACKAGE__)}) { |
|
|
6
|
|
|
|
|
16
|
|
|
640
|
6
|
|
|
|
|
11
|
my $type_uuid = $as->uuid; |
|
641
|
6
|
|
|
|
|
9
|
my $next_type; |
|
642
|
|
|
|
|
|
|
|
|
643
|
6
|
50
|
|
|
|
16
|
return $self->id if $self->type->eq($as); |
|
644
|
|
|
|
|
|
|
|
|
645
|
6
|
|
|
|
|
11
|
foreach my $test (qw(uuid oid uri sid)) { |
|
646
|
24
|
100
|
|
|
|
38
|
if ($as == $well_known{$test}) { |
|
647
|
3
|
|
|
|
|
3
|
$next_type = $test; |
|
648
|
3
|
|
|
|
|
3
|
last; |
|
649
|
|
|
|
|
|
|
} |
|
650
|
|
|
|
|
|
|
} |
|
651
|
|
|
|
|
|
|
|
|
652
|
6
|
100
|
|
|
|
11
|
if (defined $next_type) { |
|
653
|
3
|
0
|
33
|
|
|
9
|
return $self->{id_cache}{$type_uuid} if !$opts{no_defaults} && defined($self->{id_cache}) && defined($self->{id_cache}{$type_uuid}); |
|
|
|
|
33
|
|
|
|
|
|
654
|
3
|
|
|
|
|
7
|
$as = $next_type; |
|
655
|
|
|
|
|
|
|
} else { |
|
656
|
3
|
50
|
33
|
|
|
26
|
return $self->{id_cache}{$type_uuid} if defined($self->{id_cache}) && defined($self->{id_cache}{$type_uuid}); |
|
657
|
0
|
0
|
|
|
|
0
|
return $opts{default} if exists $opts{default}; |
|
658
|
0
|
|
|
|
|
0
|
croak 'Unknown/Unsupported as: '.$as; |
|
659
|
|
|
|
|
|
|
} |
|
660
|
|
|
|
|
|
|
} |
|
661
|
|
|
|
|
|
|
|
|
662
|
125
|
100
|
66
|
|
|
241
|
return $self if ($as =~ /^[A-Z]/ || $as =~ /::/) && eval {$self->isa($as)}; |
|
|
122
|
|
66
|
|
|
423
|
|
|
663
|
|
|
|
|
|
|
|
|
664
|
3
|
50
|
|
|
|
55
|
if ($self->isa('Data::Identifier::Interface::Subobjects')) { |
|
665
|
0
|
|
|
|
|
0
|
require Data::Identifier::Interface::Subobjects; # Is this required? |
|
666
|
0
|
|
0
|
|
|
0
|
$opts{$_} //= $self->so_get($_, default => undef) foreach Data::Identifier::Interface::Subobjects->KEYS; |
|
667
|
|
|
|
|
|
|
} |
|
668
|
|
|
|
|
|
|
|
|
669
|
3
|
50
|
|
|
|
12
|
if (defined(my $so = $opts{so})) { |
|
670
|
0
|
|
|
|
|
0
|
require Data::Identifier::Interface::Subobjects; # Is this required? |
|
671
|
0
|
|
0
|
|
|
0
|
$opts{$_} //= $so->so_get($_, default => undef) foreach Data::Identifier::Interface::Subobjects->KEYS; |
|
672
|
|
|
|
|
|
|
} |
|
673
|
|
|
|
|
|
|
|
|
674
|
3
|
50
|
|
|
|
4
|
$self = __PACKAGE__->new(from => $self) unless eval {$self->isa(__PACKAGE__)}; |
|
|
3
|
|
|
|
|
12
|
|
|
675
|
|
|
|
|
|
|
|
|
676
|
3
|
50
|
33
|
|
|
29
|
if ($as eq 'uuid' || $as eq 'oid' || $as eq 'uri' || $as eq 'sid' || $as eq 'ise') { |
|
|
|
0
|
33
|
|
|
|
|
|
|
|
0
|
33
|
|
|
|
|
|
|
|
0
|
33
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
677
|
3
|
|
|
|
|
11
|
my $func = $self->can($as); |
|
678
|
3
|
|
|
|
|
9
|
return $self->$func(%opts); |
|
679
|
|
|
|
|
|
|
} elsif ($as eq __PACKAGE__) { |
|
680
|
0
|
|
|
|
|
0
|
return $self; |
|
681
|
|
|
|
|
|
|
} elsif ($as eq 'URI') { |
|
682
|
0
|
|
|
|
|
0
|
my $had_default = exists $opts{default}; |
|
683
|
0
|
|
|
|
|
0
|
my $default = delete $opts{default}; |
|
684
|
0
|
|
|
|
|
0
|
my $val = $self->uri(%opts, default => undef); |
|
685
|
|
|
|
|
|
|
|
|
686
|
0
|
0
|
|
|
|
0
|
return URI->new($val) if defined $val; |
|
687
|
0
|
0
|
|
|
|
0
|
if ($had_default) { |
|
688
|
0
|
0
|
|
|
|
0
|
return $default if ref $default; |
|
689
|
0
|
|
|
|
|
0
|
return URI->new($default); |
|
690
|
|
|
|
|
|
|
} |
|
691
|
0
|
|
|
|
|
0
|
croak 'No value for URI'; |
|
692
|
|
|
|
|
|
|
} elsif ($as eq 'Mojo::URL') { |
|
693
|
0
|
|
|
|
|
0
|
my $had_default = exists $opts{default}; |
|
694
|
0
|
|
|
|
|
0
|
my $default = delete $opts{default}; |
|
695
|
0
|
|
|
|
|
0
|
my $val = $self->uri(%opts, default => undef); |
|
696
|
|
|
|
|
|
|
|
|
697
|
0
|
|
|
|
|
0
|
require Mojo::URL; |
|
698
|
|
|
|
|
|
|
|
|
699
|
0
|
0
|
|
|
|
0
|
return Mojo::URL->new($val) if defined $val; |
|
700
|
0
|
0
|
|
|
|
0
|
if ($had_default) { |
|
701
|
0
|
0
|
|
|
|
0
|
return $default if ref $default; |
|
702
|
0
|
|
|
|
|
0
|
return Mojo::URL->new($default); |
|
703
|
|
|
|
|
|
|
} |
|
704
|
0
|
|
|
|
|
0
|
croak 'No value for URI'; |
|
705
|
|
|
|
|
|
|
} elsif ($as eq 'Data::URIID::Result' && defined($opts{extractor})) { |
|
706
|
0
|
|
|
|
|
0
|
return $opts{extractor}->lookup($self->type->uuid => $self->id); |
|
707
|
|
|
|
|
|
|
} elsif ($as eq 'Data::URIID::Service' && defined($opts{extractor})) { |
|
708
|
0
|
|
|
|
|
0
|
return $opts{extractor}->service($self->uuid); |
|
709
|
|
|
|
|
|
|
} elsif ($as eq 'SIRTX::Datecode' && eval { |
|
710
|
0
|
|
|
|
|
0
|
require SIRTX::Datecode; |
|
711
|
0
|
|
|
|
|
0
|
SIRTX::Datecode->VERSION(v0.03); |
|
712
|
0
|
|
|
|
|
0
|
1; |
|
713
|
|
|
|
|
|
|
}) { |
|
714
|
0
|
|
|
|
|
0
|
return SIRTX::Datecode->new(from => $self); |
|
715
|
|
|
|
|
|
|
} elsif ($as eq 'Data::URIID::Colour' && eval { |
|
716
|
0
|
|
|
|
|
0
|
require Data::URIID; |
|
717
|
0
|
|
|
|
|
0
|
require Data::URIID::Colour; |
|
718
|
0
|
|
|
|
|
0
|
Data::URIID::Colour->VERSION(v0.14); |
|
719
|
0
|
|
|
|
|
0
|
1; |
|
720
|
|
|
|
|
|
|
}) { |
|
721
|
0
|
|
|
|
|
0
|
return Data::URIID::Colour->new(from => $self, %opts{qw(extractor db fii store)}); |
|
722
|
|
|
|
|
|
|
} elsif ($as eq 'Data::TagDB::Tag' && defined($opts{db})) { |
|
723
|
0
|
0
|
|
|
|
0
|
if ($opts{autocreate}) { |
|
724
|
0
|
|
|
|
|
0
|
return $opts{db}->create_tag($self); |
|
725
|
|
|
|
|
|
|
} else { |
|
726
|
0
|
|
|
|
|
0
|
return $opts{db}->tag_by_id($self); |
|
727
|
|
|
|
|
|
|
} |
|
728
|
|
|
|
|
|
|
} elsif ($as eq 'File::FStore::File' && defined($opts{store})) { |
|
729
|
0
|
|
|
|
|
0
|
return scalar($opts{store}->query(ise => $self)); |
|
730
|
|
|
|
|
|
|
} elsif ($as eq 'Business::ISBN' && $self->type->eq('gtin')) { |
|
731
|
0
|
|
|
|
|
0
|
require Business::ISBN; |
|
732
|
0
|
|
|
|
|
0
|
my $val = Business::ISBN->new($self->id); |
|
733
|
0
|
0
|
0
|
|
|
0
|
return $val if defined($val) && $val->is_valid; |
|
734
|
|
|
|
|
|
|
} |
|
735
|
|
|
|
|
|
|
|
|
736
|
0
|
0
|
|
|
|
0
|
return $opts{default} if exists $opts{default}; |
|
737
|
0
|
|
|
|
|
0
|
croak 'Unknown/Unsupported as: '.$as; |
|
738
|
|
|
|
|
|
|
} |
|
739
|
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
sub eq { |
|
742
|
41
|
|
|
41
|
1
|
64
|
my ($self, $other) = @_; |
|
743
|
|
|
|
|
|
|
|
|
744
|
41
|
|
|
|
|
48
|
foreach my $e ($self, $other) { |
|
745
|
82
|
100
|
66
|
|
|
120
|
if (defined($e) && !scalar(eval {$e->isa(__PACKAGE__)})) { |
|
|
82
|
|
|
|
|
222
|
|
|
746
|
4
|
50
|
|
|
|
26
|
if (defined $well_known{$e}) { |
|
747
|
0
|
|
|
|
|
0
|
$e = $well_known{$e} |
|
748
|
|
|
|
|
|
|
} else { |
|
749
|
4
|
|
|
|
|
8
|
$e = Data::Identifier->new(from => $e); |
|
750
|
|
|
|
|
|
|
} |
|
751
|
|
|
|
|
|
|
} |
|
752
|
|
|
|
|
|
|
} |
|
753
|
|
|
|
|
|
|
|
|
754
|
41
|
50
|
|
|
|
54
|
if (defined($self)) { |
|
755
|
41
|
50
|
|
|
|
50
|
return undef unless defined $other; |
|
756
|
41
|
100
|
|
|
|
138
|
return 1 if $self == $other; |
|
757
|
11
|
50
|
|
|
|
17
|
return undef unless $self->type->eq($other->type); |
|
758
|
11
|
|
|
|
|
34
|
return $self->id eq $other->id; |
|
759
|
|
|
|
|
|
|
} else { |
|
760
|
0
|
|
|
|
|
0
|
return !defined($other); |
|
761
|
|
|
|
|
|
|
} |
|
762
|
|
|
|
|
|
|
} |
|
763
|
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
sub cmp { |
|
766
|
0
|
|
|
0
|
1
|
0
|
my ($self, $other) = @_; |
|
767
|
|
|
|
|
|
|
|
|
768
|
0
|
|
|
|
|
0
|
foreach my $e ($self, $other) { |
|
769
|
0
|
0
|
0
|
|
|
0
|
if (defined($e) && !scalar(eval {$e->isa(__PACKAGE__)})) { |
|
|
0
|
|
|
|
|
0
|
|
|
770
|
0
|
0
|
|
|
|
0
|
if (defined $well_known{$e}) { |
|
771
|
0
|
|
|
|
|
0
|
$e = $well_known{$e} |
|
772
|
|
|
|
|
|
|
} else { |
|
773
|
0
|
|
|
|
|
0
|
$e = Data::Identifier->new(from => $e); |
|
774
|
|
|
|
|
|
|
} |
|
775
|
|
|
|
|
|
|
} |
|
776
|
|
|
|
|
|
|
} |
|
777
|
|
|
|
|
|
|
|
|
778
|
0
|
0
|
|
|
|
0
|
if (defined($self)) { |
|
779
|
0
|
0
|
|
|
|
0
|
return undef unless defined $other; |
|
780
|
0
|
0
|
|
|
|
0
|
return 0 if $self == $other; |
|
781
|
0
|
0
|
|
|
|
0
|
if ((my $r = $self->type->cmp($other->type)) != 0) { |
|
782
|
0
|
|
|
|
|
0
|
return $r; |
|
783
|
|
|
|
|
|
|
} |
|
784
|
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
{ |
|
786
|
0
|
|
|
|
|
0
|
my $self_id = $self->id; |
|
|
0
|
|
|
|
|
0
|
|
|
787
|
0
|
|
|
|
|
0
|
my $other_id = $other->id; |
|
788
|
|
|
|
|
|
|
|
|
789
|
0
|
0
|
0
|
|
|
0
|
if ((my ($sa, $sb) = $self_id =~ /^([^0-9]*)([0-9]+)$/) && (my ($oa, $ob) = $other_id =~ /^([^0-9]*)([0-9]+)$/)) { |
|
790
|
0
|
|
|
|
|
0
|
my $r = $sa cmp $oa; |
|
791
|
0
|
0
|
|
|
|
0
|
return $r if $r; |
|
792
|
0
|
|
|
|
|
0
|
return $sb <=> $ob; |
|
793
|
|
|
|
|
|
|
} |
|
794
|
|
|
|
|
|
|
|
|
795
|
0
|
|
|
|
|
0
|
return $self_id cmp $other_id; |
|
796
|
|
|
|
|
|
|
} |
|
797
|
|
|
|
|
|
|
} else { |
|
798
|
0
|
|
|
|
|
0
|
return !defined($other); |
|
799
|
|
|
|
|
|
|
} |
|
800
|
|
|
|
|
|
|
} |
|
801
|
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
#@returns __PACKAGE__ |
|
804
|
|
|
|
|
|
|
sub namespace { |
|
805
|
3
|
|
|
3
|
1
|
4
|
my ($self, %opts) = @_; |
|
806
|
3
|
|
|
|
|
44
|
my $has_default = exists $opts{default}; |
|
807
|
3
|
|
|
|
|
4
|
my $default = delete $opts{default}; |
|
808
|
|
|
|
|
|
|
|
|
809
|
3
|
|
|
|
|
8
|
delete $opts{no_defaults}; |
|
810
|
|
|
|
|
|
|
|
|
811
|
3
|
50
|
|
|
|
5
|
croak 'Stray options passed' if scalar keys %opts; |
|
812
|
|
|
|
|
|
|
|
|
813
|
3
|
50
|
|
|
|
12
|
return $self->{namespace} if defined $self->{namespace}; |
|
814
|
|
|
|
|
|
|
|
|
815
|
0
|
0
|
|
|
|
0
|
return $default if $has_default; |
|
816
|
|
|
|
|
|
|
|
|
817
|
0
|
|
|
|
|
0
|
croak 'No namespace'; |
|
818
|
|
|
|
|
|
|
} |
|
819
|
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
#@returns __PACKAGE__ |
|
822
|
|
|
|
|
|
|
sub generator { |
|
823
|
0
|
|
|
0
|
1
|
0
|
my ($self, %opts) = @_; |
|
824
|
0
|
|
|
|
|
0
|
my $has_default = exists $opts{default}; |
|
825
|
0
|
|
|
|
|
0
|
my $default = delete $opts{default}; |
|
826
|
|
|
|
|
|
|
|
|
827
|
0
|
|
|
|
|
0
|
delete $opts{no_defaults}; |
|
828
|
|
|
|
|
|
|
|
|
829
|
0
|
0
|
|
|
|
0
|
croak 'Stray options passed' if scalar keys %opts; |
|
830
|
|
|
|
|
|
|
|
|
831
|
0
|
0
|
|
|
|
0
|
return $self->{generator} if defined $self->{generator}; |
|
832
|
|
|
|
|
|
|
|
|
833
|
0
|
0
|
|
|
|
0
|
return $default if $has_default; |
|
834
|
|
|
|
|
|
|
|
|
835
|
0
|
|
|
|
|
0
|
croak 'No generator'; |
|
836
|
|
|
|
|
|
|
} |
|
837
|
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
sub request { |
|
840
|
0
|
|
|
0
|
1
|
0
|
my ($self, %opts) = @_; |
|
841
|
0
|
|
|
|
|
0
|
my $has_default = exists $opts{default}; |
|
842
|
0
|
|
|
|
|
0
|
my $default = delete $opts{default}; |
|
843
|
|
|
|
|
|
|
|
|
844
|
0
|
|
|
|
|
0
|
delete $opts{no_defaults}; |
|
845
|
|
|
|
|
|
|
|
|
846
|
0
|
0
|
|
|
|
0
|
croak 'Stray options passed' if scalar keys %opts; |
|
847
|
|
|
|
|
|
|
|
|
848
|
0
|
0
|
|
|
|
0
|
return $self->{request} if defined $self->{request}; |
|
849
|
|
|
|
|
|
|
|
|
850
|
0
|
0
|
|
|
|
0
|
return $default if $has_default; |
|
851
|
|
|
|
|
|
|
|
|
852
|
0
|
|
|
|
|
0
|
croak 'No request'; |
|
853
|
|
|
|
|
|
|
} |
|
854
|
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
#@returns __PACKAGE__ |
|
857
|
|
|
|
|
|
|
sub register { |
|
858
|
909
|
|
|
909
|
1
|
1473
|
my ($self) = @_; |
|
859
|
909
|
|
|
|
|
1738
|
$registered{$self->{type}->uuid}{$self->{id}} = $self; |
|
860
|
|
|
|
|
|
|
|
|
861
|
909
|
|
|
|
|
1543
|
foreach my $type_name (qw(uuid oid uri sid)) { |
|
862
|
3636
|
|
50
|
|
|
10365
|
my $f = $self->can($type_name) || next; |
|
863
|
3636
|
|
100
|
|
|
6030
|
my $v = $self->$f(default => undef) // next; |
|
864
|
3342
|
|
|
|
|
362672
|
$registered{$well_known{$type_name}->uuid}{$v} = $self; |
|
865
|
|
|
|
|
|
|
} |
|
866
|
|
|
|
|
|
|
|
|
867
|
909
|
|
|
|
|
1401
|
foreach my $extra (WK_SNI()) { |
|
868
|
909
|
|
100
|
|
|
2010
|
my $v = $self->{id_cache}{$extra} // next; |
|
869
|
154
|
|
|
|
|
385
|
$registered{$extra}{$v} = $self; |
|
870
|
|
|
|
|
|
|
} |
|
871
|
|
|
|
|
|
|
|
|
872
|
909
|
|
|
|
|
1809
|
return $self; |
|
873
|
|
|
|
|
|
|
} |
|
874
|
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
sub displayname { |
|
878
|
13
|
|
|
13
|
1
|
33
|
my ($self, %opts) = @_; |
|
879
|
|
|
|
|
|
|
|
|
880
|
13
|
50
|
|
|
|
47
|
if (defined(my $displayname = $self->{displayname})) { |
|
881
|
13
|
50
|
|
|
|
27
|
$displayname = $self->$displayname() if ref $displayname; |
|
882
|
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
# recheck and return as any of the above conversions could result in $displayname becoming invalid. |
|
884
|
13
|
50
|
33
|
|
|
98
|
return $displayname if defined($displayname) && length($displayname); |
|
885
|
|
|
|
|
|
|
} |
|
886
|
|
|
|
|
|
|
|
|
887
|
0
|
0
|
|
|
|
0
|
return $self->id.'' unless $opts{no_defaults}; # force stringification. |
|
888
|
0
|
0
|
|
|
|
0
|
return $opts{default} if exists $opts{default}; |
|
889
|
0
|
|
|
|
|
0
|
croak 'No value for displayname'; |
|
890
|
|
|
|
|
|
|
} |
|
891
|
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
|
|
893
|
0
|
|
|
0
|
1
|
0
|
sub displaycolour { my ($self, %opts) = @_; return $opts{default}; } |
|
|
0
|
|
|
|
|
0
|
|
|
894
|
0
|
|
|
0
|
1
|
0
|
sub icontext { my ($self, %opts) = @_; return $opts{default}; } |
|
|
0
|
|
|
|
|
0
|
|
|
895
|
0
|
|
|
0
|
1
|
0
|
sub description { my ($self, %opts) = @_; return $opts{default}; } |
|
|
0
|
|
|
|
|
0
|
|
|
896
|
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
# ---- Private helpers ---- |
|
898
|
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
sub import { |
|
900
|
15
|
|
|
15
|
|
1044
|
my ($pkg, $opts) = @_; |
|
901
|
15
|
50
|
|
|
|
8683
|
return unless defined $opts; |
|
902
|
0
|
0
|
|
|
|
0
|
croak 'Bad options' unless ref($opts) eq 'HASH'; |
|
903
|
|
|
|
|
|
|
|
|
904
|
0
|
0
|
|
|
|
0
|
if (defined(my $disable = $opts->{disable})) { |
|
905
|
0
|
0
|
|
|
|
0
|
$disable = [split /\s*,\s*/, $disable] unless ref $disable; |
|
906
|
0
|
|
|
|
|
0
|
foreach my $to_disable (@{$disable}) { |
|
|
0
|
|
|
|
|
0
|
|
|
907
|
0
|
0
|
|
|
|
0
|
if ($to_disable eq 'oid') { |
|
908
|
0
|
|
|
|
|
0
|
$enabled_oid = undef; |
|
909
|
0
|
|
|
|
|
0
|
undef *oid; |
|
910
|
|
|
|
|
|
|
} else { |
|
911
|
0
|
|
|
|
|
0
|
croak 'Unknown feature: '.$to_disable; |
|
912
|
|
|
|
|
|
|
} |
|
913
|
|
|
|
|
|
|
} |
|
914
|
|
|
|
|
|
|
} |
|
915
|
|
|
|
|
|
|
} |
|
916
|
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
sub _generate { |
|
918
|
3
|
|
|
3
|
|
4
|
my ($self) = @_; |
|
919
|
3
|
50
|
|
|
|
8
|
unless (exists $self->{_generate}) { |
|
920
|
3
|
|
|
|
|
6
|
my __PACKAGE__ $type = $self->type; |
|
921
|
|
|
|
|
|
|
|
|
922
|
3
|
50
|
|
|
|
8
|
if (defined(my $generate = $type->{generate})) { |
|
923
|
3
|
50
|
|
|
|
4
|
unless (ref $generate) { |
|
924
|
3
|
|
|
|
|
12
|
$self->{generate} = $generate = {style => $generate}; |
|
925
|
|
|
|
|
|
|
} |
|
926
|
|
|
|
|
|
|
|
|
927
|
3
|
|
50
|
|
|
12
|
$self->{id_cache} //= {}; |
|
928
|
|
|
|
|
|
|
|
|
929
|
3
|
50
|
|
|
|
3
|
if (defined(my __PACKAGE__ $ns = eval {$type->namespace->uuid})) { |
|
|
3
|
|
|
|
|
7
|
|
|
930
|
3
|
|
|
|
|
4
|
my $style = $generate->{style}; |
|
931
|
3
|
|
|
|
|
3
|
my $input; |
|
932
|
|
|
|
|
|
|
|
|
933
|
3
|
50
|
|
|
|
5
|
if ($style eq 'id-based') { |
|
934
|
3
|
|
|
|
|
6
|
$input = lc($self->id); |
|
935
|
|
|
|
|
|
|
} else { |
|
936
|
0
|
|
|
|
|
0
|
croak 'Unsupported generator style'; |
|
937
|
|
|
|
|
|
|
} |
|
938
|
|
|
|
|
|
|
|
|
939
|
3
|
50
|
|
|
|
5
|
if (defined $input) { |
|
940
|
3
|
|
|
|
|
16
|
require Data::Identifier::Generate; |
|
941
|
3
|
|
|
|
|
18
|
$self->{id_cache}{WK_UUID()} = Data::Identifier::Generate->_uuid_v5($ns, $input); |
|
942
|
|
|
|
|
|
|
} |
|
943
|
|
|
|
|
|
|
} |
|
944
|
|
|
|
|
|
|
} |
|
945
|
|
|
|
|
|
|
} |
|
946
|
3
|
|
|
|
|
8
|
$self->{_generate} = undef; |
|
947
|
|
|
|
|
|
|
} |
|
948
|
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
sub _known_provider { |
|
950
|
9
|
|
|
9
|
|
34
|
my ($pkg, $class, %opts) = @_; |
|
951
|
9
|
50
|
|
|
|
48
|
croak 'Unsupported options passed' if scalar(keys %opts); |
|
952
|
|
|
|
|
|
|
|
|
953
|
9
|
100
|
33
|
|
|
84
|
if ($class eq 'wellknown') { |
|
|
|
50
|
|
|
|
|
|
|
954
|
8
|
|
|
|
|
18
|
state $wellknown = do { |
|
955
|
7
|
|
|
|
|
41
|
my %hash = map{$_ => $_} values(%well_known), map {values %{$_}} values(%registered); |
|
|
1708
|
|
|
|
|
3664
|
|
|
|
35
|
|
|
|
|
49
|
|
|
|
35
|
|
|
|
|
681
|
|
|
956
|
7
|
|
|
|
|
369
|
[values %hash]; |
|
957
|
|
|
|
|
|
|
}; |
|
958
|
|
|
|
|
|
|
|
|
959
|
8
|
|
|
|
|
32
|
return ($wellknown, rawtype => __PACKAGE__); |
|
960
|
|
|
|
|
|
|
} elsif ($class eq 'registered' || $class eq ':all') { |
|
961
|
1
|
|
|
|
|
6
|
my %hash = map{$_ => $_} values(%well_known), map {values %{$_}} values(%registered); |
|
|
244
|
|
|
|
|
452
|
|
|
|
5
|
|
|
|
|
7
|
|
|
|
5
|
|
|
|
|
85
|
|
|
962
|
1
|
|
|
|
|
48
|
return ([values %hash], rawtype => __PACKAGE__); |
|
963
|
|
|
|
|
|
|
} |
|
964
|
|
|
|
|
|
|
|
|
965
|
0
|
|
|
|
|
|
croak 'Unsupported class'; |
|
966
|
|
|
|
|
|
|
} |
|
967
|
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
1; |
|
969
|
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
__END__ |