1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16interface NativeXmlPullParser {
17  new(value: object, strEncoding?: string): NativeXmlPullParser;
18  parse(options: object): void;
19  parseXml(options: object): boolean;
20  XmlPullParserError(): string;
21}
22
23interface NativeXMLSerializer {
24  new(value: object, strEncoding?: string): NativeXMLSerializer;
25  setAttributes(name: string, value: string): void;
26  addEmptyElement(name: string): void;
27  setDeclaration(): void;
28  startElement(name: string): void;
29  endElement(): void;
30  setNamespace(prefix: string, namespace: string): void;
31  setComment(text: string): void;
32  setCDATA(text: string): void;
33  setText(text: string): void;
34  setDocType(text: string): void;
35  XmlSerializerError(): string;
36}
37
38interface Xml {
39  XmlSerializer: NativeXMLSerializer;
40  XmlPullParser: NativeXmlPullParser;
41}
42const ARGUMENT_LENGTH_TWO = 2;
43const TypeErrorCode = 401;
44class BusinessError extends Error {
45  code: number;
46  constructor(msg: string) {
47    super(msg);
48    this.name = 'BusinessError';
49    this.code = TypeErrorCode;
50  }
51}
52
53declare function requireInternal(s: string): Xml;
54const XML = requireInternal('xml');
55class XmlSerializer {
56  xmlSerializerClass: NativeXMLSerializer;
57  constructor(obj: object, inputStr: string) {
58    if (typeof obj !== 'object') {
59      throw new BusinessError(`Parameter error.The type of ${obj} must be object`);
60    }
61    if (arguments.length === 1 ||
62        (arguments.length === ARGUMENT_LENGTH_TWO && (typeof inputStr === 'undefined' || inputStr === null))) {
63      const inputType: string = 'utf-8';
64      this.xmlSerializerClass = new XML.XmlSerializer(obj, inputType);
65    } else if (arguments.length === ARGUMENT_LENGTH_TWO && (typeof inputStr === 'string' && inputStr.length !== 0)) {
66      let strTemp: string = inputStr;
67      if (strTemp.toLowerCase() !== 'utf-8') {
68        throw new BusinessError('Parameter error.Just support utf-8');
69      }
70      this.xmlSerializerClass = new XML.XmlSerializer(obj, inputStr);
71    } else {
72      throw new BusinessError(`Parameter error.The type of ${inputStr} must be string`);
73    }
74    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
75    if (errStr.length !== 0) {
76      throw new BusinessError(errStr);
77    }
78  }
79
80  setAttributes(name: string, value: string): void {
81    if (typeof name !== 'string') {
82      throw new BusinessError(`Parameter error.The type of ${name} must be string`);
83    }
84    if (name.length === 0) {
85      throw new BusinessError(`Parameter error. Parameter cannot be empty`);
86    }
87    if (typeof value !== 'string') {
88      throw new BusinessError(`Parameter error.The type of ${value} must be string`);
89    }
90
91    this.xmlSerializerClass.setAttributes(name, value);
92    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
93    if (errStr.length !== 0) {
94      throw new BusinessError(errStr);
95    }
96  }
97
98  addEmptyElement(name: string): void {
99    if (typeof name !== 'string') {
100      throw new BusinessError(`Parameter error.The type of ${name} must be string`);
101    }
102    if (name.length === 0) {
103      throw new BusinessError(`Parameter error. Parameter cannot be empty`);
104    }
105
106    this.xmlSerializerClass.addEmptyElement(name);
107    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
108    if (errStr.length !== 0) {
109      throw new BusinessError(errStr);
110    }
111  }
112
113  setDeclaration(): void {
114    this.xmlSerializerClass.setDeclaration();
115    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
116    if (errStr.length !== 0) {
117      throw new BusinessError(errStr);
118    }
119  }
120
121  startElement(name: string): void {
122    if (typeof name !== 'string') {
123      throw new BusinessError(`Parameter error.The type of ${name} must be string`);
124    }
125    if (name.length === 0) {
126      throw new BusinessError(`Parameter error. Parameter cannot be empty`);
127    }
128    this.xmlSerializerClass.startElement(name);
129    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
130    if (errStr.length !== 0) {
131      throw new BusinessError(errStr);
132    }
133  }
134
135  endElement(): void {
136    this.xmlSerializerClass.endElement();
137    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
138    if (errStr.length !== 0) {
139      throw new BusinessError(errStr);
140    }
141  }
142
143  setNamespace(prefix: string, ns: string): void {
144    if (typeof prefix !== 'string') {
145      throw new BusinessError(`Parameter error.The type of ${prefix} must be string`);
146    }
147    if (prefix.length === 0) {
148      throw new BusinessError(`Parameter error. Parameter cannot be empty`);
149    }
150    if (typeof ns !== 'string' || ns.length === 0) {
151      throw new BusinessError(`Parameter error.The type of ${ns} must be string`);
152    }
153    this.xmlSerializerClass.setNamespace(prefix, ns);
154    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
155    if (errStr.length !== 0) {
156      throw new BusinessError(errStr);
157    }
158  }
159
160  setComment(text: string): void {
161    if (typeof text !== 'string') {
162      let error = new BusinessError(`Parameter error.The type of ${text} must be string`);
163      throw error;
164    }
165    if (text.length === 0) {
166      throw new BusinessError(`Parameter error. Parameter cannot be empty`);
167    }
168    this.xmlSerializerClass.setComment(text);
169    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
170    if (errStr.length !== 0) {
171      throw new BusinessError(errStr);
172    }
173  }
174
175  setCDATA(text: string): void {
176    if (typeof text !== 'string') {
177      throw new BusinessError(`Parameter error.The type of ${text} must be string`);
178    }
179    if (text.length === 0) {
180      throw new BusinessError(`Parameter error. Parameter cannot be empty`);
181    }
182    this.xmlSerializerClass.setCDATA(text);
183    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
184    if (errStr.length !== 0) {
185      throw new BusinessError(errStr);
186    }
187  }
188
189  setText(text: string): void {
190    if (typeof text !== 'string') {
191      throw new BusinessError(`Parameter error.The type of ${text} must be string`);
192    }
193    if (text.length === 0) {
194      throw new BusinessError(`Parameter error. Parameter cannot be empty`);
195    }
196    this.xmlSerializerClass.setText(text);
197    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
198    if (errStr.length !== 0) {
199      throw new BusinessError(errStr);
200    }
201  }
202
203  setDocType(text: string): void {
204    if (typeof text !== 'string') {
205      throw new BusinessError(`Parameter error.The type of ${text} must be string`);
206    }
207    if (text.length === 0) {
208      throw new BusinessError(`Parameter error. Parameter cannot be empty`);
209    }
210    this.xmlSerializerClass.setDocType(text);
211    let errStr: string = this.xmlSerializerClass.XmlSerializerError();
212    if (errStr.length !== 0) {
213      throw new BusinessError(errStr);
214    }
215  }
216}
217
218class XmlPullParser {
219  xmlPullParserClass: NativeXmlPullParser;
220  constructor(obj: object, inputStr: string) {
221    if (typeof obj !== 'object') {
222      throw new BusinessError(`Parameter error.The type of ${obj} must be object`);
223    }
224    if (arguments.length === 1 ||
225        (arguments.length === ARGUMENT_LENGTH_TWO && (typeof inputStr === 'undefined' || inputStr === null))) {
226      let str: string = 'utf-8';
227      this.xmlPullParserClass = new XML.XmlPullParser(obj, str);
228    } else if (arguments.length === ARGUMENT_LENGTH_TWO && (typeof inputStr ===
229      'string' && inputStr.length !== 0)) {
230      let strTemp: string = inputStr;
231      if (strTemp.toLowerCase() !== 'utf-8') {
232        throw new BusinessError('Parameter error.Just support utf-8');
233      }
234      this.xmlPullParserClass = new XML.XmlPullParser(obj, inputStr);
235    } else {
236      throw new BusinessError(`Parameter error.The type of ${inputStr} must be string`);
237    }
238    let errStr: string = this.xmlPullParserClass.XmlPullParserError();
239    if (errStr.length !== 0) {
240      throw new BusinessError(errStr);
241    }
242  }
243  parse(options: object): void {
244    if (typeof options !== 'object') {
245      throw new BusinessError(`Parameter error.The type of ${options} must be object`);
246    }
247    this.xmlPullParserClass.parse(options);
248    let errStr: string = this.xmlPullParserClass.XmlPullParserError();
249    if (errStr.length !== 0) {
250      throw new BusinessError(errStr);
251    }
252  }
253
254  parseXml(options: object): void {
255    if (typeof options !== 'object') {
256      throw new BusinessError(`Parameter error.The type of ${options} must be object`);
257    }
258    if (this.xmlPullParserClass.parseXml(options)) {
259      let errStr: string = this.xmlPullParserClass.XmlPullParserError();
260      throw new BusinessError(errStr);
261    }
262  }
263}
264
265enum EventType {
266  START_DOCUMENT,
267  END_DOCUMENT,
268  START_TAG,
269  END_TAG,
270  TEXT,
271  CDSECT,
272  COMMENT,
273  DOCDECL,
274  INSTRUCTION,
275  ENTITY_REFERENCE,
276  WHITESPACE
277}
278
279export default {
280  XmlSerializer: XmlSerializer,
281  XmlPullParser: XmlPullParser,
282  EventType,
283};
284