1/* 2 * Copyright (c) 2023 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 16import convertXml from '@ohos.convertxml'; 17import type { Features, Language, Feature, Changelog, Icon } from '@ohos/common/src/main/ets/const/update_const'; 18import { LogUtils } from '@ohos/common/src/main/ets/util/LogUtils'; 19 20let conv = new convertXml.ConvertXML(); 21 22let options: convertXml.ConvertOptions = { 23 trim: false, 24 declarationKey: '_declaration', 25 instructionKey: '_instruction', 26 attributesKey: '_attributes', 27 textKey: '_text', 28 cdataKey: '_cdata', 29 doctypeKey: '_doctype', 30 commentKey: '_comment', 31 parentKey: '_parent', 32 typeKey: '_type', 33 nameKey: '_name', 34 elementsKey: '_elements', 35}; 36 37let changelog: Changelog; 38 39/** 40 * Changelog解析工具 41 * 42 * @since 2022-06-06 43 */ 44namespace ChangelogParseUtils { 45 /** 46 * Changelog解析 47 * 48 * @param res 待解析的string 49 * @param callback 解析结果回调 50 */ 51 export function parseXml(res: string, callback: (data: Changelog) => void): void { 52 logInfo('read file parse start'); 53 changelog = { language: new Map() }; 54 if (!res) { 55 logError('res is null!'); 56 callback(null); 57 return; 58 } 59 let xmlResult: Object = conv.convert(res, options); 60 if (!xmlResult || !xmlResult['_elements'] || xmlResult['_elements'].length <= 0) { 61 logError('xmlResult is null! ' + JSON.stringify(xmlResult)); 62 callback(null); 63 return; 64 } 65 let root = xmlResult['_elements'][0]; 66 if (!root || !root['_elements'] || root['_elements'].length <= 0) { 67 logError('root is null! ' + JSON.stringify(root)); 68 callback(null); 69 return; 70 } 71 parseRoot(root); 72 logInfo('read file parse end'); 73 callback(changelog); 74 } 75 76 function parseRoot(root: any): void { 77 // 倒序解析,先解析Icon 78 let icons = {}; 79 logInfo('root length ' + root['_elements'].length); 80 for (let index = root['_elements'].length; index > 0; index--) { 81 let element = root['_elements'][index - 1]; 82 if (!element) { 83 logError('element is null! ' + JSON.stringify(element)); 84 continue; 85 } 86 if (element['_type'] === 'element' && element['_name'] === 'default-language') { 87 let attribute = element['_attributes']['name']; 88 logInfo('default-language :' + attribute); 89 changelog.defLanguage = attribute; 90 } 91 if (element['_type'] === 'element' && element['_name'] === 'displayType') { 92 let attribute = element['_elements']?.[0]?.['_text']; 93 logInfo('displayType :' + attribute); 94 changelog.displayType = attribute; 95 } 96 if (element['_type'] === 'element' && element['_name'] === 'icons') { 97 let iconsElement = element['_elements']; 98 parseIcons(iconsElement, icons); 99 } 100 parseLanguage(element, icons); 101 } 102 } 103 104 function parseLanguage(element: any, icons: Object): void { 105 let language: Language = { featuresArray: [] }; 106 if (element['_type'] === 'element' && element['_name'] === 'language') { 107 let attribute: string; 108 if (!element['_attributes']) { 109 logError('language is null :' + JSON.stringify(element['_attributes'])); 110 return; 111 } 112 attribute = element['_attributes']['name']; 113 let languageElement = element['_elements']; 114 language.language = attribute; 115 changelog.language.set(language.language, language); 116 117 if (!languageElement || languageElement.length <= 0) { 118 logError('features is null' + JSON.stringify(languageElement)); 119 return; 120 } 121 parseFeatures(languageElement, language, icons); 122 } 123 } 124 125 function parseIcons(iconsElement: any, icons: Object): void { 126 let icon: Icon; 127 for (let index = 0; index < iconsElement.length; index++) { 128 let iconElement = iconsElement[index]; 129 if (!iconElement) { 130 logError('iconElement is null :' + JSON.stringify(iconElement)); 131 continue; 132 } 133 if (iconElement['_type'] === 'element' && iconElement['_name'] === 'icon') { 134 icon = { 135 id: iconElement['_attributes']['id'], 136 pkg: iconElement['_attributes']['pkg'], 137 res: iconElement['_attributes']['res'], 138 }; 139 icons[icon.id] = icon; 140 } 141 } 142 } 143 144 function parseFeatures(languageElement: any, language: Language, icons: Object): void { 145 let features: Features; 146 for (let index = 0; index < languageElement.length; index++) { 147 let featuresElement = languageElement[index]; 148 if (!featuresElement) { 149 logInfo('featuresElement is null' + JSON.stringify(featuresElement)); 150 continue; 151 } 152 153 if (featuresElement['_type'] === 'element' && featuresElement['_name'] === 'features') { 154 let moduleString = featuresElement['_attributes']['module']; 155 let typeString = featuresElement['_attributes']['type']; 156 let id = featuresElement['_attributes']['id']; 157 let featureElement = featuresElement['_elements']; 158 let featureList: Feature[] = []; 159 features = { 160 title: moduleString, 161 id: id, 162 featureModuleType: typeString, 163 featureList: featureList, 164 icon: icons[id], 165 }; 166 language.featuresArray.push(features); 167 168 if (!featureElement || featureElement.length <= 0) { 169 logError('featureElement is null: ' + JSON.stringify(featureElement)); 170 continue; 171 } 172 parseFeature(featureElement, featureList); 173 } 174 } 175 } 176 177 function parseFeature(featureElement: any, featureList: Array<Feature>): void { 178 let feature: Feature; 179 for (let index = 0; index < featureElement.length; index++) { 180 let featureItem = featureElement[index]; 181 if (featureItem['_type'] !== 'element' || featureItem['_name'] !== 'feature') { 182 continue; 183 } 184 if (!featureItem) { 185 logError('featureItem is null: ' + JSON.stringify(featureItem)); 186 continue; 187 } 188 189 let title: string; 190 if (featureItem['_attributes']) { 191 title = featureItem['_attributes']['title']; 192 } 193 let content: string; 194 if (featureItem['_elements']) { 195 content = featureItem['_elements'][0]['_text']; 196 } 197 if (title) { 198 feature = { subTitle: title, contents: [] }; 199 featureList.push(feature); 200 } else { 201 if (!feature) { 202 feature = { subTitle: title, contents: [] }; 203 featureList.push(feature); 204 } 205 if (content) { 206 feature.contents.push(content); 207 } 208 } 209 } 210 } 211 212 function logInfo(message: string): void { 213 LogUtils.info('ChangelogParseUtils', message); 214 } 215 216 function logError(message: string): void { 217 LogUtils.error('ChangelogParseUtils', message); 218 } 219} 220 221export default ChangelogParseUtils;