Skip to content

Commit

Permalink
[FEATURE] manifestCreator: enrich manifest with supportedLocales in i…
Browse files Browse the repository at this point in the history
…18n (for libraries) (#547)

manifestCreator: i18n section v22

With app descriptor v22 (1.21.0) the i18n sections in the manifest can be an object
with:
* bundleUrl
* supportedLocales
This change reads the provided properties files and automatically creates the supportedLocales
array based on this information.
  • Loading branch information
tobiasso85 committed Jan 14, 2021
1 parent 03241c0 commit 8102034
Show file tree
Hide file tree
Showing 12 changed files with 558 additions and 76 deletions.
108 changes: 98 additions & 10 deletions lib/processors/manifestCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const APP_DESCRIPTOR_V3_SECTION_SAP_APP = new Version("1.2.0");
const APP_DESCRIPTOR_V3_OTHER_SECTIONS = new Version("1.1.0");
const APP_DESCRIPTOR_V5 = new Version("1.4.0");
const APP_DESCRIPTOR_V10 = new Version("1.9.0");
const APP_DESCRIPTOR_V22 = new Version("1.21.0");

// namespaces used in .library files
const XMLNS_UILIB = "http://www.sap.com/sap.ui.library.xsd";
Expand Down Expand Up @@ -114,6 +115,7 @@ class Library {
parser.parseString(content, (err, xml) => {
if ( err ) {
reject(err);
return;
}
resolve(new Library(xml.library));
});
Expand All @@ -123,13 +125,30 @@ class Library {


class LibraryBundle {
/**
*
* @param {string} prefix
* @param {module:@ui5/fs.Resource[]} resources
*/
constructor(prefix, resources) {
this.prefix = prefix;
this.resources = resources.filter((res) => res.getPath().startsWith(prefix));
}

/**
*
* @param {string} name
* @returns {module:@ui5/fs.Resource}
*/
findResource(name) {
return this.resources.find((res) => res.getPath() === this.prefix + name);
}

/**
*
* @param {RegExp} pattern
* @returns {module:@ui5/fs.Resource[]}
*/
getResources(pattern) {
return this.resources.filter((res) => pattern == null || pattern.test(res.getPath()));
}
Expand All @@ -144,6 +163,13 @@ async function createManifest(libraryResource, libBundle, descriptorVersion, _in

// collect information from library.js file
const libraryJSInfo = await analyzeLibraryJS(libBundle.findResource("library.js"));
const includeSupportedLocalesInformation = descriptorVersion.compare(APP_DESCRIPTOR_V22) >= 0;
/**
* cache for supported locales
*
* @see createI18nSection
*/
const i18nToSupportedLocales = new Map();

const manifestAppData = library.getAppData("manifest", XMLNS_MANIFEST);
const sapFioriAppData = findChild(manifestAppData, "sap.fiori");
Expand Down Expand Up @@ -322,13 +348,18 @@ async function createManifest(libraryResource, libBundle, descriptorVersion, _in

return osComponents.length > 0 ? osComponents : undefined;
}

const i18nText = getChildTextContent(manifestAppData, "i18n");
let i18n;
if (typeof i18nText === "string") {
i18n = createI18nSection(i18nText, i18nToSupportedLocales);
log.verbose(`sap.app/i18n taken from .library appData: '%s'`, i18nText);
}
const sapApp = {
_version: sectionVersion(APP_DESCRIPTOR_V3_SECTION_SAP_APP),
id: library.getName(),
type: "library",
embeds: await findEmbeddedComponents(),
i18n: getChildTextContent(manifestAppData, "i18n"),
i18n,
applicationVersion: {
version: isValid(library.getVersion()) ? library.getVersion() : getProjectVersion()
},
Expand Down Expand Up @@ -456,25 +487,24 @@ async function createManifest(libraryResource, libBundle, descriptorVersion, _in
// - from .library/appData/manifest/sap.ui5/library/i18n
// - from library resources (if "messagebundle.properties" exists)
function i18n() {
const i18nElement = findChild(libraryAppData, "i18n");
if ( i18nElement ) {
const i18n = i18nElement._;
let i18n = getChildTextContent(libraryAppData, "i18n");
if ( typeof i18n === "string") {
if ( i18n === "false" ) {
return false;
} else if ( i18n === "true" ) {
return "messagebundle.properties";
} else {
return i18n;
i18n = "messagebundle.properties";
}
// log.verbose(" sap.ui5/library/i18n property taken from .library appData: '%s'", library.i18n);
} else {
if ( libBundle.findResource("messagebundle.properties") != null ) {
// log.verbose(" sap.ui5/library/i18n property determined from resources: '%s'", library.i18n);
return "messagebundle.properties";
i18n = "messagebundle.properties";
} else {
// i18n not defined and no messagebundle.properties
return false;
}
}
return createI18nSection(i18n, i18nToSupportedLocales);
}

// css:
Expand Down Expand Up @@ -525,6 +555,64 @@ async function createManifest(libraryResource, libBundle, descriptorVersion, _in
return sapUI5;
}

/**
* Creates an i18n section:
* - either using bundleUrl and supportedLocales
* - or the i18n String
*
* @param {string} i18n bundle url, e.g. "messagebundle.properties"
* @param {Map<string, Set<string>>} i18nToSupportedLocales cache to determine the supportedLocales only once
* @returns {{bundleUrl: string, supportedLocales: string[]}|null|string} json structure with bundleUrl and
* supportedLocales or the i18n String if not a ".properties" file.
* <code>null</code> if given i18n String is <code>null</code>
*/
function createI18nSection(i18n, i18nToSupportedLocales) {
if (i18n === undefined) {
return undefined;
}
if (!i18n.endsWith(".properties")) {
return i18n;
}

// if the supported locales information should not be included use i18n text
if (!includeSupportedLocalesInformation) {
return i18n;
}

let supportedLocales = i18nToSupportedLocales.get(i18n);

if (!supportedLocales) {
supportedLocales = new Set();

if (libBundle.findResource(i18n) != null) {
supportedLocales.add("");
}
const i18nPathPrefix = i18n.substring(0, i18n.length - ".properties".length) + "_";
// e.g. i18n/i18n_

libBundle.getResources().forEach((resource) => {
const resPath = resource.getPath();
// e.g. sap/ui/mine/i18n/i18n_en.properties
const indexOfI18nPathPrefix = resPath.lastIndexOf(i18nPathPrefix);
if (resPath.endsWith(".properties") && indexOfI18nPathPrefix >= 0) {
const i18nPath = resPath.substring(indexOfI18nPathPrefix + i18nPathPrefix.length,
resPath.length - ".properties".length);
if (!i18nPath.includes(".")) {
supportedLocales.add(i18nPath.replace(/_/g, "-"));
}
}
});
i18nToSupportedLocales.set(i18n, supportedLocales);
}

const supportedLocalesArray = Array.from(supportedLocales);
supportedLocalesArray.sort();
return {
bundleUrl: i18n,
supportedLocales: supportedLocalesArray
};
}

function createSapFiori() {
// collect registrationIds if present
function registrationIds() {
Expand Down Expand Up @@ -613,7 +701,7 @@ async function createManifest(libraryResource, libBundle, descriptorVersion, _in
module.exports = function({libraryResource, resources, options}) {
// merge options with defaults
options = Object.assign({
descriptorVersion: APP_DESCRIPTOR_V10,
descriptorVersion: APP_DESCRIPTOR_V22,
include3rdParty: true,
prettyPrint: true
}, options);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_version": "1.9.0",
"_version": "1.21.0",
"sap.app": {
"id": "library.d",
"type": "library",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_version": "1.9.0",
"_version": "1.21.0",
"sap.app": {
"id": "library.h",
"type": "library",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
{
"name": "manifest.json",
"module": "library/h/manifest.json",
"size": 613
"size": 614
},
{
"name": "not.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_version": "1.9.0",
"_version": "1.21.0",
"sap.app": {
"id": "library.h",
"type": "library",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_version": "1.9.0",
"_version": "1.21.0",
"sap.app": {
"id": "library.i",
"type": "library",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_version": "1.9.0",
"_version": "1.21.0",
"sap.app": {
"id": "library.k",
"type": "library",
Expand All @@ -22,7 +22,14 @@
"libs": {}
},
"library": {
"i18n": "messagebundle.properties",
"i18n": {
"bundleUrl": "messagebundle.properties",
"supportedLocales": [
"",
"de",
"en"
]
},
"content": {
"controls": [
"library.k.AnyControl"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_version": "1.9.0",
"_version": "1.21.0",
"sap.app": {
"id": "library.k",
"type": "library",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ui5-bundle library/ø/library-preload.js
sap.ui.require.preload({
"library/ø/manifest.json":'{"_version":"1.9.0","sap.app":{"id":"library.ø","type":"library","embeds":[],"applicationVersion":{"version":"1.0.0"},"title":"Library Ø","description":"Library Ø","resources":"resources.json","offline":true},"sap.ui":{"technology":"UI5","supportedThemes":["цветя"]},"sap.ui5":{"dependencies":{"minUI5Version":"1.0","libs":{}},"library":{"i18n":false}}}',
"library/ø/manifest.json":'{"_version":"1.21.0","sap.app":{"id":"library.ø","type":"library","embeds":[],"applicationVersion":{"version":"1.0.0"},"title":"Library Ø","description":"Library Ø","resources":"resources.json","offline":true},"sap.ui":{"technology":"UI5","supportedThemes":["цветя"]},"sap.ui5":{"dependencies":{"minUI5Version":"1.0","libs":{}},"library":{"i18n":false}}}',
"library/ø/some.js":function(){/*!
* Some fancy copyright
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_version": "1.9.0",
"_version": "1.21.0",
"sap.app": {
"id": "library.ø",
"type": "library",
Expand Down

0 comments on commit 8102034

Please sign in to comment.