blob: 0de142ad637c4755e2b58efb6cad7d9ef5bfe99c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component, ComponentHeader, ComponentProperty, SupportedComponent } from '../model/ComponentModels';
import { CamelElement } from '../model/IntegrationDefinition';
const Components: Component[] = [];
const SupportedComponents: SupportedComponent[] = [];
let SupportedOnly: boolean = false;
export class ComponentApi {
private constructor() {}
static setSupportedOnly = (supportedOnly: boolean): void => {
SupportedOnly = supportedOnly;
};
static saveSupportedComponents = (jsons: string): void => {
SupportedComponents.length = 0;
const sc: SupportedComponent[] = (JSON.parse(jsons) as []).map(json => new SupportedComponent(json));
SupportedComponents.push(...sc);
};
static getSupportedComponents = (): SupportedComponent[] => {
return SupportedComponents;
};
static jsonToComponent = (json: string): Component => {
const fromJson: Component = JSON.parse(json) as Component;
const k: Component = new Component(fromJson);
return k;
};
static saveComponents = (jsons: string[], clean: boolean = false): void => {
if (clean) Components.length = 0;
const components: Component[] = jsons.map(json => ComponentApi.jsonToComponent(json));
Components.push(...components);
};
static saveComponent = (json: string): void => {
const component: Component = ComponentApi.jsonToComponent(json);
if (Components.findIndex((c: Component) => c.component.name === component.component.name) === -1) {
Components.push(component);
}
};
static getComponents = (): Component[] => {
const comps: Component[] = [];
if (SupportedOnly) {
comps.push(
...Components.filter(
comp => SupportedComponents.findIndex(sc => sc.name === comp.component.name) !== -1,
),
);
} else {
comps.push(...Components);
}
return comps
.map(comp => {
const sc = SupportedComponents.find(sc => sc.name === comp.component.name);
if (sc !== undefined) {
comp.component.supportLevel = sc.level;
comp.component.supportType = 'Supported';
return comp;
} else {
comp.component.supportType = 'Community';
return comp;
}
})
.sort((a, b) => a.component.name.localeCompare(b.component.name, undefined, { sensitivity: 'base' }));
};
static findByName = (name: string): Component | undefined => {
return ComponentApi.getComponents().find((c: Component) => c.component.name === name);
};
static getComponentNameFromUri = (uri: string): string | undefined => {
return uri !== undefined ? uri.split(':')[0] : undefined;
};
static getComponentTitleFromUri = (uri: string): string | undefined => {
if (uri !== undefined) {
const componentName = uri.split(':')[0];
const title = ComponentApi.findByName(componentName)?.component.title;
return title ? title : componentName;
} else {
return undefined;
}
};
static getComponentDescriptionFromUri = (uri: string): string | undefined => {
if (uri !== undefined) {
const componentName = uri.split(':')[0];
const description = ComponentApi.findByName(componentName)?.component.description;
return description ? description : componentName;
} else {
return undefined;
}
};
static parseElementUri(def: any): any {
if (def.dslName === 'ToDynamicDefinition') {
return def;
}
const uriParts = ComponentApi.parseUri(def.uri);
if (uriParts.length > 1 && !def.uri.startsWith('kamelet:')) {
const uriValues = ComponentApi.getUriParts(def.uri);
uriValues.forEach((value, key) => {
def.parameters[key] = value;
});
def.uri = uriParts[0];
}
return def;
}
static getUriParts = (uri: string): Map<string, string> => {
const result: Map<string, string> = new Map<string, string>();
const name = ComponentApi.getComponentNameFromUri(uri);
if (name) {
const component = ComponentApi.findByName(name);
const syntax = component?.component.syntax;
const syntaxParts = ComponentApi.parseSyntax(syntax + '');
const syntaxSeparators = ComponentApi.getSyntaxSeparators(syntax + '');
let newUri = uri === name ? name + syntaxSeparators.join('') : uri;
if (name === 'salesforce') {
// workaround for salesforce component
const parts = newUri.split(':');
if (parts.length === 2) result.set('operationName', parts.at(1) || '').set('topicName', '');
else if (parts.length === 3)
result.set('operationName', parts.at(1) || '').set('topicName', parts.at(2) || '');
} else if (name === 'cxf') {
// workaround for CXF component
const cxfParts = newUri.split(':');
const firstPart = cxfParts.at(1);
const secondPart = cxfParts.at(2);
if (cxfParts.length === 3 && firstPart === 'bean' && secondPart)
result.set('beanId', firstPart + ':' + secondPart);
if (cxfParts.length === 2 && firstPart?.startsWith('//')) result.set('address', firstPart);
} else if (name === 'jt400') {
// workaround for JT400 component
const jt400Parts = newUri.split('.').join(':').split('/').join(':').split('@').join(':').split(':');
const userID = jt400Parts.at(1) || '';
const password = jt400Parts.at(2) || '';
const systemName = jt400Parts.at(3) || '';
const objectPath = jt400Parts.at(4) || '';
const type = jt400Parts.at(5) || '';
result.set('userID', userID);
result.set('password', password);
result.set('systemName', systemName);
result.set('objectPath', objectPath);
result.set('type', type);
} else {
// workarounds end
syntaxParts
.filter((_, i) => i > 0)
.forEach((part, index) => {
if (index < syntaxParts.length - 1) {
const startSeparator = syntaxSeparators[index];
const endSeparator = syntaxSeparators[index + 1];
const start = newUri.indexOf(startSeparator) + startSeparator.length;
const end = endSeparator ? newUri.indexOf(endSeparator, start) : newUri.length;
const val = newUri.substring(start, end);
result.set(part, val);
newUri = newUri.substring(end);
}
});
}
}
return result;
};
static parseSyntax = (syntax: string): string[] => {
const separators: string[] = ['://', '//', ':', '/', '#'];
let simplifiedSyntax = '' + syntax;
separators.forEach(s => {
simplifiedSyntax = simplifiedSyntax?.replaceAll(s, ':');
});
return simplifiedSyntax.split(':');
};
static getSyntaxSeparators = (syntax: string): string[] => {
const result: string[] = [];
const parts: string[] = ComponentApi.parseSyntax(syntax);
let str = '';
parts.forEach((part, index) => {
if (index < parts.length - 1) {
const start = syntax.indexOf(part, str.length) + part.length;
const end = syntax.indexOf(parts[index + 1], start);
const separator = syntax.substring(start, end);
result.push(separator);
str = str + part + separator;
}
});
return result;
};
static parseUri = (uri?: string): string[] => {
const separators: string[] = ['://', '//', ':', '/', '#'];
let simplifiedUri = '' + uri;
separators.forEach(s => {
simplifiedUri = simplifiedUri.replaceAll(s, ':');
});
return simplifiedUri.split(':');
};
static getUriSeparators = (uri: string): string[] => {
const result: string[] = [];
const name = ComponentApi.getComponentNameFromUri(uri);
if (name) {
const component = ComponentApi.findByName(name);
const syntax = '' + component?.component.syntax;
const parts: string[] = Array.from(ComponentApi.getUriParts(uri).keys());
let str = '';
parts.forEach((part, index) => {
if (index < parts.length - 1) {
const start = syntax.indexOf(part, str.length) + part.length;
const end = syntax.indexOf(parts[index + 1], start);
const separator = syntax.substring(start, end);
result.push(separator);
str = str + part + separator;
}
});
}
return result;
};
static getPathParameterValue = (uri: string, pathParameter: string): string | undefined => {
return ComponentApi.getUriParts(uri).get(pathParameter);
};
static getComponentProperties = (componentName: string, type: 'consumer' | 'producer'): ComponentProperty[] => {
const invertedType = type === 'consumer' ? 'producer' : 'consumer';
const component: Component | undefined = ComponentApi.findByName(componentName);
const properties: ComponentProperty[] = [];
if (component !== undefined && component.properties) {
for (const [key, value] of Object.entries(component.properties) as [string, any][]) {
const prop = new ComponentProperty();
prop.name = key;
prop.label = value.label;
prop.description = value.description;
prop.type = value.type;
prop.displayName = value.displayName;
prop.group = value.group;
prop.type = value.type;
prop.deprecated = value.deprecated;
prop.secret = value.secret;
prop.enum = value.enum;
prop.kind = value.kind;
prop.required = value.required;
if (value.defaultValue) {
prop.defaultValue = value.defaultValue;
}
if (!value.deprecated) {
properties.push(prop);
}
}
}
const result: ComponentProperty[] = [];
result.push(...properties.filter(p => p.kind === 'path'));
result.push(...properties.filter(p => p.kind !== 'path' && p.required));
result.push(...properties.filter(p => p.label.length === 0 && p.kind !== 'path' && !p.required));
result.push(
...properties.filter(p => !p.label.includes(invertedType) && !p.label.includes('advanced') && !p.required),
);
result.push(...properties.filter(p => p.label === 'formatting' && !p.required));
result.push(
...properties.filter(
p =>
!p.label.includes(invertedType) &&
(p.label.includes('scheduler') || p.label.includes('security') || p.label.includes('advanced')),
),
);
result.push(
...properties.filter(
p =>
!p.label.includes(invertedType) &&
(p.label.includes('scheduler') || p.label.includes('security') || p.label.includes('advanced')),
),
);
return Array.from(new Map(result.map(item => [item.name, item])).values());
};
static getComponentHeaders = (componentName: string, type: 'consumer' | 'producer'): ComponentHeader[] => {
const invertedType = type === 'consumer' ? 'producer' : 'consumer';
const component: Component | undefined = ComponentApi.findByName(componentName);
const properties: ComponentHeader[] = [];
if (component !== undefined && component.headers) {
for (const [key, value] of Object.entries(component.headers) as [string, any][]) {
const prop = new ComponentHeader();
prop.name = key;
prop.label = value.label;
prop.description = value.description;
prop.index = value.index;
prop.displayName = value.displayName;
prop.group = value.group;
prop.deprecated = value.deprecated;
prop.secret = value.secret;
prop.kind = value.kind;
prop.constantName = value.constantName;
prop.defaultValue = value.defaultValue;
prop.javaType = value.javaType;
prop.autowired = value.autowired;
if (!value.deprecated) {
properties.push(prop);
}
}
}
return Array.from(new Map(properties.map(item => [item.name, item])).values());
};
}