UNPKG

3.79 kBJavaScriptView Raw
1/*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15'use strict';
16
17const URIJS = require('urijs');
18
19const ModelUtils = require('../modelutil');
20
21const RESOURCE_SCHEME = 'resource';
22
23/**
24 * All the identifying properties of a resource.
25 * @private
26 * @class
27 * @memberof module:concerto-core
28 * @property {String} namespace
29 * @property {String} type
30 * @property {String} id
31 */
32class ResourceId {
33 /**
34 * <strong>Note: only for use by internal framework code.</strong>
35 * @param {String} namespace - Namespace containing the type.
36 * @param {String} type - Short type name.
37 * @param {String} id - Instance identifier.
38 * @private
39 */
40 constructor(namespace, type, id) {
41 if (!namespace) {
42 throw new Error('Missing namespace');
43 }
44 if (!type) {
45 throw new Error('Missing type');
46 }
47 if (!id) {
48 throw new Error('Missing id');
49 }
50
51 this.namespace = namespace;
52 this.type = type;
53 this.id = id;
54 }
55
56 /**
57 * Parse a URI into an identifier.
58 * <p>
59 * Three formats are allowable:
60 * <ol>
61 * <li>Valid resource URI argument: <em>resource:qualifiedTypeName#ID</em></li>
62 * <li>Valid resource URI argument with missing URI scheme: <em>qualifiedTypeName#ID</em></li>
63 * <li>URI argument containing only an ID, with legacy namespace and type arguments supplied.</li>
64 * </ol>
65 * @param {String} uri - Resource URI.
66 * @param {String} [legacyNamespace] - Namespace to use for legacy resource identifiers.
67 * @param {String} [legacyType] - Type to use for legacy resource identifiers.
68 * @return {Identifier} - An identifier.
69 * @throws {Error} - On an invalid resource URI.
70 */
71 static fromURI(uri, legacyNamespace, legacyType) {
72 let uriComponents;
73 try {
74 uriComponents = URIJS.parse(uri);
75 } catch (err){
76 throw new Error('Invalid URI: ' + uri);
77 }
78
79 const scheme = uriComponents.protocol;
80 // Accept legacy identifiers with missing URI scheme as valid
81 if (scheme && scheme !== RESOURCE_SCHEME) {
82 throw new Error('Invalid URI scheme: ' + uri);
83 }
84 if (uriComponents.username || uriComponents.password || uriComponents.port || uriComponents.query) {
85 throw new Error('Invalid resource URI format: ' + uri);
86 }
87
88 let namespace, type;
89 let id = uriComponents.fragment;
90 if (!id) {
91 // Legacy format where the whole path is the ID
92 namespace = legacyNamespace;
93 type = legacyType;
94 id = uriComponents.path;
95 } else {
96 const qualifiedType = uriComponents.path;
97 namespace = ModelUtils.getNamespace(qualifiedType);
98 type = ModelUtils.getShortName(qualifiedType);
99 }
100
101 return new ResourceId(namespace, type, decodeURIComponent(id));
102 }
103
104 /**
105 * URI representation of this identifier.
106 * @return {String} A URI.
107 */
108 toURI() {
109 const qualifiedType = ModelUtils.getFullyQualifiedName(this.namespace, this.type);
110 return RESOURCE_SCHEME + ':' + qualifiedType + '#' + encodeURI(this.id);
111 }
112
113}
114
115module.exports = ResourceId;