552401 - Model mapping in atfxadapter with ExtSystem
added etities related to ExtSystem
Signed-off-by: Juergen Kleck <j.kleck@peak-solution.de>
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.css b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.css
new file mode 100644
index 0000000..ea615fe
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.css
@@ -0,0 +1,20 @@
+@charset "ISO-8859-1";
+
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+.navbar-vertical {}
+.navbar-vertical .navbar-nav {}
+.navbar-vertical .navbar-nav .navbar-brand {display:block;}
+.navbar-vertical .navbar-nav .nav-item {display:block;}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.html b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.html
index 8fbbf81..b240a99 100644
--- a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.html
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.html
@@ -12,19 +12,29 @@
*
********************************************************************************-->
-<nav class="navbar navbar-default navbar-expand bg-light">
- <div class="container-fluid">
- <div class="collapse navbar-collapse" id="bs-admin-navbar">
- <a class="navbar-brand" style="font-weight: 500;">{{'administration.admin-modules.scope' | translate }}</a>
- <ul class="nav navbar-nav mdm-link-list">
- <li *ngFor="let m of links" [routerLinkActive]="['active']" class="nav-item">
- <a routerLink="{{m.path}}" class="nav-link" style="cursor:pointer;">
- {{m.name | translate}}
- </a>
- </li>
- </ul>
- </div>
-
+<vertical-split-pane primary-component-minsize="{{minWidthLeft()}}" secondary-component-minsize="{{minWidthRight()}}" primary-component-initialratio="{{initRatio()}}">
+ <div class="split-pane-content-primary">
+ <nav class="navbar navbar-default navbar-vertical bg-light">
+ <div class="container-fluid">
+ <div class="" id="bs-admin-navbar">
+ <a class="navbar-brand" style="font-weight: 500;">{{'administration.admin-modules.modules' | translate }}</a>
+ <ul class="nav navbar-nav mdm-link-list">
+ <li *ngFor="let m of links" [routerLinkActive]="['active']" class="nav-item">
+ <a routerLink="{{m.path}}" class="nav-link" style="cursor:pointer;">
+ {{m.name | translate}}
+ </a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </nav>
</div>
-</nav>
-<router-outlet></router-outlet>
+ <div class="split-pane-content-secondary">
+ <div class="navigator-content" (scroll)=onScroll($event)>
+ <router-outlet></router-outlet>
+ <div *ngIf="scrollBtnVisible" style="position: fixed; bottom: 30px; right: 35px;">
+ <button class="btn btn-default" (click)="onScrollTop()" style="z-index: 10000;"><span class="fa fa-arrow-up" style="z-index: 10000;" title="{{ 'navigator-view.mdm-navigator-view.tooltip-scroll-up' | translate }}"></span></button>
+ </div>
+ </div>
+ </div>
+</vertical-split-pane>
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.ts
index 1727754..f784dfe 100644
--- a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.ts
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-modules.component.ts
@@ -17,18 +17,48 @@
import {Router} from '@angular/router';
import { TRANSLATE } from '../core/mdm-core.module';
+import { SplitPaneModule } from 'ng2-split-pane/lib/ng2-split-pane';
@Component({
selector: 'admin-modules',
templateUrl: 'admin-modules.component.html',
+ styleUrls: ['./admin-modules.component.css'],
providers: []
})
export class AdminModulesComponent {
+ div: any;
+ scrollBtnVisible = false;
+
links = [
- { name: TRANSLATE('administration.admin-modules.system'), path: 'system'},
- { name: TRANSLATE('administration.admin-modules.source'), path: 'source'},
- { name: TRANSLATE('administration.admin-modules.user'), path: 'user'}
+ { name: TRANSLATE('administration.admin-modules.preferences'), path: 'preferences'},
+ { name: TRANSLATE('administration.admin-modules.extsystems'), path: 'extsystems'}
];
- constructor(private router: Router) {}
+ constructor(private router: Router) { }
+
+
+ minWidthLeft() {
+ return 180;
+ }
+
+ minWidthRight() {
+ return 0.20 * window.innerWidth;
+ }
+
+ initRatio() {
+ return Math.max(200 / window.innerWidth, 0.20);
+ }
+
+ onScrollTop() {
+ this.div.scrollTop = 0;
+ }
+
+ onScroll(event: any) {
+ if (event.target.scrollTop > 0) {
+ this.scrollBtnVisible = true;
+ } else {
+ this.scrollBtnVisible = false;
+ }
+ this.div = event.target;
+ }
}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-routing.module.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-routing.module.ts
index 719b94c..dd2921b 100644
--- a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-routing.module.ts
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin-routing.module.ts
@@ -16,15 +16,17 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
-import { PreferenceComponent } from './preference.component';
import { AdminModulesComponent } from './admin-modules.component';
+import { ExtSystemComponent } from './extsystem.component';
+import { PreferenceRoutingModule } from './preference-routing.module';
const moduleRoutes: Routes = [
{
path: '', component: AdminModulesComponent,
children: [
- { path: ':scope', component: PreferenceComponent },
- { path: '', redirectTo: 'system', pathMatch: 'full' }
+ { path: 'preferences', loadChildren: './preference.module#PreferenceModule' },
+ { path: 'extsystems', component: ExtSystemComponent },
+ { path: '', redirectTo: 'preferences', pathMatch: 'full' }
]
}
];
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin.module.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin.module.ts
index 0e3839a..68eaff0 100644
--- a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin.module.ts
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/admin.module.ts
@@ -17,32 +17,48 @@
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
-import { PreferenceService } from '../core/preference.service';
import { MDMCoreModule } from '../core/mdm-core.module';
+import { ExtSystemComponent } from './extsystem.component';
+import { ExtSystemViewerComponent } from './extsystem-viewer.component';
+import { ExtSystemEditorComponent } from './extsystem-editor.component';
import { AdminModulesComponent } from './admin-modules.component';
import { AdminRoutingModule } from './admin-routing.module';
-import { PreferenceComponent } from './preference.component';
-import { EditPreferenceComponent } from './edit-preference.component';
+import { ExtSystemService } from './extsystem.service';
+import { SplitPaneModule } from 'ng2-split-pane/lib/ng2-split-pane';
+import { PreferenceModule } from './preference.module';
+import { TableModule } from 'primeng/table';
+import { ContextMenuModule } from 'primeng/contextmenu';
+import { DialogModule } from 'primeng/dialog';
+import { CatalogService } from './catalog.service';
+import { AutoCompleteModule } from 'primeng/autocomplete';
@NgModule( {
imports: [
AdminRoutingModule,
MDMCoreModule,
FormsModule,
- ReactiveFormsModule
+ ReactiveFormsModule,
+ SplitPaneModule,
+ PreferenceModule,
+ TableModule,
+ ContextMenuModule,
+ DialogModule,
+ AutoCompleteModule
],
declarations: [
- PreferenceComponent,
- EditPreferenceComponent,
AdminModulesComponent,
+ ExtSystemComponent,
+ ExtSystemViewerComponent,
+ ExtSystemEditorComponent
],
exports: [
AdminModulesComponent,
],
providers: [
ComponentLoaderFactory,
- PreferenceService
+ ExtSystemService,
+ CatalogService
],
})
export class AdminModule { }
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/catalog.service.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/catalog.service.ts
new file mode 100644
index 0000000..6f3991e
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/catalog.service.ts
@@ -0,0 +1,78 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+import { Injectable } from '@angular/core';
+import { Http, Response, Headers, RequestOptions } from '@angular/http';
+
+import { PropertyService } from '../core/property.service';
+
+import { plainToClass } from 'class-transformer';
+import { HttpErrorHandler } from '../core/http-error-handler';
+import { throwError as observableThrowError, Observable } from 'rxjs';
+import { map, catchError } from 'rxjs/operators';
+import { Node } from '../navigator/node';
+
+@Injectable()
+export class CatalogService {
+
+ private prefEndpoint: string;
+
+ constructor(private http: Http,
+ private httpErrorHandler: HttpErrorHandler,
+ private _prop: PropertyService) {
+ this.prefEndpoint = _prop.getUrl('mdm/environments/');
+ }
+
+ getTplRootsForType(scope: string, type: string): Observable<Node[]> {
+ return this.http.get(this.prefEndpoint + scope + '/tplroots/' + type).pipe(
+ map(response => plainToClass(Node, response.json().data)),
+ catchError(this.handleError));
+ }
+
+ getTplCompForRoot(scope: string, type: string, rootId: string): Observable<Node[]> {
+ return this.http.get(this.prefEndpoint + scope + '/tplroots/' + type + '/' + rootId + '/tplcomps/rootList').pipe(
+ map(response => plainToClass(Node, response.json().data)),
+ catchError(this.handleError));
+ }
+
+ getTplAttrsForComp(scope: string, type: string, rootId: string, tplCompId: string): Observable<Node[]> {
+ return this.http.get(this.prefEndpoint + scope + '/tplroots/' + type + '/' + rootId + '/tplcomps/' + tplCompId + '/tplattrs').pipe(
+ map(response => plainToClass(Node, response.json().data)),
+ catchError(this.handleError));
+ }
+
+ getCatCompsForType(scope: string, type: string): Observable<Node[]> {
+ return this.http.get(this.prefEndpoint + scope + '/catcomps/' + type).pipe(
+ map(response => plainToClass(Node, response.json().data)),
+ catchError(this.handleError));
+ }
+
+ getCatAttrsForComp(scope: string, type: string, catCompId: string): Observable<Node[]> {
+ return this.http.get(this.prefEndpoint + scope + '/catcomps/' + type + '/' + catCompId + '/catattrs').pipe(
+ map(response => plainToClass(Node, response.json().data)),
+ catchError(this.handleError));
+ }
+
+ private handleError(e: Error | any) {
+ if (e instanceof Response) {
+ let response = <Response> e;
+ if (response.status !== 200) {
+ return observableThrowError('Could not request catalog element! '
+ + 'Please check if application server is running and database is configured correctly.');
+ }
+ }
+ return this.httpErrorHandler.handleError(e);
+ }
+}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-editor.component.html b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-editor.component.html
new file mode 100644
index 0000000..a82d955
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-editor.component.html
@@ -0,0 +1,162 @@
+<!-- ********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ******************************************************************************** -->
+
+ <div class="mdm-extsystem-editor-container">
+
+ <p-table class="ext-system-table" [value]="tableExtSystems" *ngIf="selectedEnvironment && extSystems" styleClass="table-hover">
+ <ng-template pTemplate="header">
+ <tr>
+ <th>{{ 'administration.extsystem.name' | translate }}</th>
+ <th>{{ 'administration.extsystem.description' | translate }}</th>
+ </tr>
+ </ng-template>
+ <ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
+ <tr>
+ <td>
+ <input required type="text" [(ngModel)]="rowData.name" />
+ </td>
+ <td>
+ <input type="text" *ngIf="getAttributeFromNode(rowData,'Description')" [(ngModel)]="getAttributeFromNode(rowData,'Description').value" />
+ </td>
+ </tr>
+ </ng-template>
+ </p-table>
+ <div class="commands">
+ <button type="button" class="btn btn-default pull-right" (click)="saveExtSystem()">
+ <span class="fa fa-plus"></span> {{'administration.extsystem.btn-save' | translate }}
+ </button>
+ </div>
+
+ <div *ngIf="selectedExtSystem">
+ <div class="custom-split-pane">
+ <div class="custom-split-pane-content custom-split-pane-left">
+ <div>{{ 'administration.extsystem.ext-system-attributes' | translate }}</div>
+ <p-table [value]="getExternalSystemAttributes()" selectionMode="single" [(selection)]="selectedExtSystemAttr"
+ [(contextMenuSelection)]="selectedExtSystemAttr" [contextMenu]="cmExtSystemAttr">
+ <ng-template pTemplate="header">
+ <tr>
+ <th>{{ 'administration.extsystem.name' | translate }}</th>
+ <th>{{ 'administration.extsystem.description' | translate }}</th>
+ </tr>
+ </ng-template>
+ <ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
+ <tr [pSelectableRow]="rowData" [pSelectableRowIndex]="rowIndex" [pContextMenuRow]="rowData">
+ <td>{{rowData.name}}</td>
+ <td>{{getAttributeValueFromNode(rowData,'Description')}}</td>
+ </tr>
+ </ng-template>
+ </p-table>
+ <div *ngIf="loadingExtSystemAttr">{{ 'administration.extsystem.loading-attributes' | translate }}</div>
+
+ <div class="commands">
+ <button type="button" class="btn btn-default pull-right" (click)="addExtSystemAttr()">
+ <span class="fa fa-plus"></span> {{'administration.extsystem.btn-add' | translate }}
+ </button>
+ </div>
+
+ </div>
+ <div class="custom-split-pane-content custom-split-pane-right">
+ <div>{{ 'administration.extsystem.mdm-attributes' | translate }}</div>
+ <p-table *ngIf="selectedExtSystemAttr" [value]="getMDMAttributes()" selectionMode="single" [(selection)]="selectedExtSystemMDMAttr"
+ [(contextMenuSelection)]="selectedExtSystemMDMAttr" [contextMenu]="cmExtSystemMDMAttr">
+ <ng-template pTemplate="header">
+ <tr>
+ <th>{{ 'administration.extsystem.component-type' | translate }}</th>
+ <th>{{ 'administration.extsystem.component-name' | translate }}</th>
+ <th>{{ 'administration.extsystem.attribute-name' | translate }}</th>
+ </tr>
+ </ng-template>
+ <ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
+ <tr [pSelectableRow]="rowData" [pSelectableRowIndex]="rowIndex" [pContextMenuRow]="rowData">
+ <td>{{getAttributeValueFromNode(rowData,'CompType')}}</td>
+ <td>{{getAttributeValueFromNode(rowData,'CompName')}}</td>
+ <td>{{getAttributeValueFromNode(rowData,'AttrName')}}</td>
+ </tr>
+ </ng-template>
+ </p-table>
+
+ <div class="commands">
+ <button *ngIf="selectedExtSystemAttr" type="button" class="btn btn-default pull-right" (click)="addExtSystemMDMAttr()">
+ <span class="fa fa-plus"></span> {{'administration.extsystem.btn-add' | translate }}
+ </button>
+ </div>
+
+ </div>
+ </div>
+
+ <div class="float-elements">
+ <p-contextMenu #cmExtSystemAttr [model]="menuItemsExtSystemAttr"></p-contextMenu>
+
+ <p-dialog header="{{ 'administration.extsystem.dialog-ext-system-attr-title' | translate}}" [(visible)]="dialogExtSystemAttr">
+ <table *ngIf="tmpExtSystemAttr">
+ <tr>
+ <td>{{ 'administration.extsystem.name' | translate}}</td>
+ <td><input required type="text" [(ngModel)]="tmpExtSystemAttr.name" /></td>
+ </tr>
+ <tr *ngIf="tmpExtSystemAttr.id">
+ <td>{{ 'administration.extsystem.description' | translate}}</td>
+ <td><input type="text" *ngIf="getAttributeFromNode(tmpExtSystemAttr,'Description')" [(ngModel)]="getAttributeFromNode(tmpExtSystemAttr,'Description').value" /></td>
+ </tr>
+ </table>
+ <div class="dialogcommands">
+ <button type="button" class="btn btn-default pull-right" (click)="saveDialogExtSystemAttr()">
+ <span class="fa fa-plus"></span> {{'administration.extsystem.btn-save' | translate }}
+ </button>
+ <button type="button" class="btn btn-default pull-right" (click)="cancelDialogExtSystemAttr()">
+ <span class="fa fa-times"></span> {{'administration.extsystem.btn-cancel' | translate }}
+ </button>
+ </div>
+ </p-dialog>
+
+
+ <p-contextMenu #cmExtSystemMDMAttr [model]="menuItemsExtSystemMDMAttr"></p-contextMenu>
+
+ <p-dialog header="{{ 'administration.extsystem.dialog-ext-system-mdm-attr-title' | translate}}" [(visible)]="dialogExtSystemMDMAttr"
+ [contentStyle]="{'overflow':'visible'}" class="dialog-extsystem-mdmattr">
+ <table *ngIf="tmpExtSystemMDMAttr">
+ <tr>
+ <td>{{ 'administration.extsystem.component-type' | translate}}</td>
+ <td>
+ <p-dropdown *ngIf="getAttributeFromNode(tmpExtSystemMDMAttr,'CompType')" [options]="mdmCompTypes" [(ngModel)]="getAttributeFromNode(tmpExtSystemMDMAttr,'CompType').value" (onChange)="handleCompTypeSelect($event)" required="true"></p-dropdown>
+ </td>
+ </tr>
+ <tr>
+ <td>{{ 'administration.extsystem.component-name' | translate}}</td>
+ <td>
+ <div *ngIf="dialogLoadingExtSystemComps" class="floattext"><div class="text">{{ 'administration.extsystem.loading-short' | translate }}</div></div>
+ <p-autoComplete *ngIf="getAttributeFromNode(tmpExtSystemMDMAttr,'CompName')" [(ngModel)]="getAttributeFromNode(tmpExtSystemMDMAttr,'CompName').value" [suggestions]="tmpCatalogComps" (completeMethod)="searchCatalogComps($event)" (onSelect)="handleCompSelect($event)" [dropdown]="true"></p-autoComplete>
+ </td>
+ </tr>
+ <tr>
+ <td>{{ 'administration.extsystem.attribute-name' | translate}}</td>
+ <td>
+ <div *ngIf="dialogLoadingExtSystemAttrs" class="floattext"><div class="text">{{ 'administration.extsystem.loading-short' | translate }}</div></div>
+ <p-autoComplete *ngIf="getAttributeFromNode(tmpExtSystemMDMAttr,'AttrName')" [(ngModel)]="getAttributeFromNode(tmpExtSystemMDMAttr,'AttrName').value" [suggestions]="tmpAttributeComps" (completeMethod)="searchAttributeComps($event)" [dropdown]="true"></p-autoComplete>
+ </td>
+ </tr>
+ </table>
+ <div class="dialogcommands">
+ <button type="button" class="btn btn-default pull-right" (click)="saveDialogExtSystemMDMAttr()">
+ <span class="fa fa-plus"></span> {{'administration.extsystem.btn-save' | translate }}
+ </button>
+ <button type="button" class="btn btn-default pull-right" (click)="cancelDialogExtSystemMDMAttr()">
+ <span class="fa fa-times"></span> {{'administration.extsystem.btn-cancel' | translate }}
+ </button>
+ </div>
+ </p-dialog>
+ </div>
+
+ </div>
+
+ </div>
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-editor.component.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-editor.component.ts
new file mode 100644
index 0000000..02e0ab8
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-editor.component.ts
@@ -0,0 +1,612 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+import { Component, OnInit, ViewChild, Input, OnDestroy, Output, EventEmitter } from '@angular/core';
+import { FormGroup, FormControl, FormBuilder, FormArray, Validators } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+import { TranslateService } from '@ngx-translate/core';
+import { DropdownModule } from 'primeng/dropdown';
+import { TreeTableModule } from 'primeng/treetable';
+import { TreeNode, MenuItem, SelectItem } from 'primeng/api';
+import { ContextMenuModule } from 'primeng/contextmenu';
+import { TreeTable, TreeTableToggler, DataTable } from 'primeng/primeng';
+import { DialogModule } from 'primeng/dialog';
+import { Observable, BehaviorSubject } from 'rxjs';
+import 'rxjs/add/operator/toPromise';
+
+import { MDMNotificationService } from '../core/mdm-notification.service';
+import { ExtSystemService } from './extsystem.service';
+import { Node, Attribute, Relation } from '../navigator/node';
+import { plainToClass } from 'class-transformer';
+import { CatalogService } from './catalog.service';
+
+@Component( {
+ selector: 'mdm-extsystem-editor',
+ templateUrl: './extsystem-editor.component.html',
+ styleUrls: ['./extsystem.component.css']
+})
+export class ExtSystemEditorComponent implements OnInit, OnDestroy {
+
+ // passed down from parent
+ @Input() extSystems: Node[];
+ @Input() selectedEnvironment: Node;
+ @Input() selectedES: string;
+
+ @Output() editMode = new EventEmitter<boolean>();
+
+ // table selection
+ selectedExtSystem: Node;
+ selectedExtSystemAttr: Node;
+ selectedExtSystemMDMAttr: Node;
+ tableExtSystems: Node[] = new Array();
+
+ // dropdown for edit dialog
+ mdmCompTypes: SelectItem[];
+ mdmCompNames: Node[];
+ mdmAttrNames: Node[];
+
+ // external system attributes
+ extSystemAttrs: Node[];
+ bsExtSystemAttrs: BehaviorSubject<Node[]> = new BehaviorSubject<Node[]>(undefined);
+
+ // contextmenu mappings
+ menuItemsExtSystemAttr: MenuItem[];
+ menuItemsExtSystemMDMAttr: MenuItem[];
+
+ // dialog and loading states
+ dialogExtSystemAttr: boolean = false;
+ dialogExtSystemMDMAttr: boolean = false;
+ loadingExtSystemAttr: boolean = false;
+
+ dialogLoadingExtSystemComps: boolean = false;
+ dialogLoadingExtSystemAttrs: boolean = false;
+
+ // for edit dialogs
+ tmpExtSystemAttr: Node;
+ tmpExtSystemMDMAttr: Node;
+ tmpNode: Node;
+ tmpCatalogComps: string[];
+ tmpAttributeComps: string[];
+
+ loadedTemplateRoots: any[][] = [];
+ loadedCatalogComps: any[][] = [];
+ loadedAttributeComps: Node[] = new Array();
+
+ constructor(private extSystemService: ExtSystemService,
+ private notificationService: MDMNotificationService,
+ private translateService: TranslateService,
+ private catalogService: CatalogService) {
+
+ this.bsExtSystemAttrs.subscribe(value => {
+ this.extSystemAttrs = value;
+ });
+
+ this.mdmCompTypes = [
+ { label: this.translateService.instant('administration.extsystem.dropdown-please-select'), value: '' },
+ { label: this.translateService.instant('administration.extsystem.unit-under-test'), value: 'UnitUnderTest' },
+ { label: this.translateService.instant('administration.extsystem.test-equipment'), value: 'TestEquipment' },
+ { label: this.translateService.instant('administration.extsystem.test-sequence'), value: 'TestSequence' },
+ { label: this.translateService.instant('administration.extsystem.sensor'), value: 'Sensor' }
+ ];
+ }
+
+ ngOnInit() {
+ for (let i in this.extSystems) {
+ if (this.extSystems[i].type === 'ExtSystem' && this.extSystems[i].id === this.selectedES) {
+ this.selectedExtSystem = this.extSystems[i];
+ this.tableExtSystems.push(this.selectedExtSystem);
+ break;
+ }
+ }
+
+ this.loadingExtSystemAttr = true;
+ this.extSystemService.getExtSystemAttributesForScope(this.selectedEnvironment.sourceName, this.selectedExtSystem.id).subscribe(attrs => {
+ this.bsExtSystemAttrs.next(attrs);
+ this.loadingExtSystemAttr = false;
+ });
+
+ this.menuItemsExtSystemAttr = [
+ {
+ label: this.translateService.instant('administration.extsystem.btn-edit'), icon: 'fa fa-pencil-square-o', command: (event) => this.editExtSystemAttr(this.selectedExtSystemAttr)
+ },
+ { label: this.translateService.instant('administration.extsystem.btn-del'), icon: 'fa fa-times', command: (event) => this.removeExtSystemAttr(this.selectedExtSystemAttr) }
+ ];
+
+ this.menuItemsExtSystemMDMAttr = [
+ {
+ label: this.translateService.instant('administration.extsystem.btn-edit'), icon: 'fa fa-pencil-square-o', command: (event) => this.editExtSystemMDMAttr(this.selectedExtSystemMDMAttr)
+ },
+ { label: this.translateService.instant('administration.extsystem.btn-del'), icon: 'fa fa-times', command: (event) => this.removeExtSystemMDMAttr(this.selectedExtSystemMDMAttr) }
+ ];
+ }
+
+ ngOnDestroy() {
+ }
+
+ getExternalSystemAttributes() {
+ let data = new Array();
+ for (let i in this.extSystemAttrs) {
+ if (this.extSystemAttrs[i].type === 'ExtSystemAttribute') {
+ data.push(this.extSystemAttrs[i]);
+ }
+ }
+ return data;
+ }
+ getMDMAttributes() {
+ let ids = new Array();
+ for (let i in this.selectedExtSystemAttr.relations) {
+ if (this.selectedExtSystemAttr.relations[i].entityType === 'MDMAttribute') {
+ for (let j in this.selectedExtSystemAttr.relations[i].ids) {
+ ids.push(this.selectedExtSystemAttr.relations[i].ids[j]);
+ }
+ }
+ }
+ let data = new Array();
+ for (let i in this.extSystemAttrs) {
+ if (this.extSystemAttrs[i].type === 'MDMAttribute' && ids.find(el => el === this.extSystemAttrs[i].id)) {
+ data.push(this.extSystemAttrs[i]);
+ }
+ }
+ return data;
+ }
+
+ getAttributeValueFromNode(node: Node, attribute: string) {
+ if (node.attributes !== undefined) {
+ for (let i in node.attributes) {
+ if (node.attributes[i].name === attribute) {
+ return node.attributes[i].value;
+ }
+ }
+ }
+ return '';
+ }
+
+ getAttributeFromNode(node: Node, attribute: string) {
+ if (node.attributes !== undefined) {
+ for (let i in node.attributes) {
+ if (node.attributes[i].name === attribute) {
+ return node.attributes[i];
+ }
+ }
+ }
+ return undefined;
+ }
+
+ getNextTemporaryId() {
+ let id: number = -1;
+ for (let i in this.extSystems) {
+ if (parseInt(this.extSystems[i].id) < id) {
+ id = parseInt(this.extSystems[i].id);
+ }
+ }
+ return --id;
+ }
+
+ createAttribute(name: string, value?: string) {
+ let attr = new Attribute();
+ attr.dataType = 'STRING';
+ attr.unit = '';
+ attr.value = value !== undefined ? value : '';
+ attr.name = name;
+ return attr;
+ }
+
+ getIndicesForIds(ids: string[]) {
+ let indices = new Array();
+ for (let id in ids) {
+ for (let i in this.extSystems) {
+ if (this.extSystems[i].id === ids[id]) {
+ indices.push(this.extSystems.indexOf(this.extSystems[i]));
+ }
+ }
+ }
+ return indices;
+ }
+
+ addExtSystemAttr() {
+ this.tmpExtSystemAttr = new Node();
+ this.tmpExtSystemAttr.type = 'ExtSystemAttribute';
+ this.tmpExtSystemAttr.sourceType = 'ExtSystemAttr';
+ this.tmpExtSystemAttr.sourceName = this.selectedEnvironment.sourceName;
+ this.tmpExtSystemAttr.attributes = new Array();
+ this.tmpExtSystemAttr.attributes.push(this.createAttribute('Description'));
+ this.tmpExtSystemAttr.attributes.push(this.createAttribute('Name'));
+ this.tmpExtSystemAttr.attributes.push(this.createAttribute('ConverterClassname'));
+ this.tmpExtSystemAttr.attributes.push(this.createAttribute('ConverterParameter'));
+ this.tmpExtSystemAttr.attributes.push(this.createAttribute('MimeType', 'application/x-asam.aoany.extsystemattr'));
+ this.dialogExtSystemAttr = true;
+ }
+
+ editExtSystemAttr(extSystemAttr?: Node) {
+ if (extSystemAttr != undefined) {
+ this.tmpNode = JSON.parse(JSON.stringify(extSystemAttr));
+ this.tmpExtSystemAttr = extSystemAttr;
+ this.dialogExtSystemAttr = true;
+ }
+ }
+
+ removeExtSystemAttr(extSystemAttr?: Node) {
+ if (extSystemAttr != undefined) {
+
+ if (extSystemAttr.id !== undefined && parseInt(extSystemAttr.id) > 0 && this.extSystemAttrs.indexOf(extSystemAttr) !== -1) {
+ this.extSystemService.deleteExtSystemAttr(this.selectedEnvironment.sourceName, extSystemAttr.id).subscribe();
+ let idxES: number = this.extSystemAttrs.indexOf(extSystemAttr);
+ if (idxES !== -1) {
+ this.extSystemAttrs.splice(idxES, 1);
+ if (extSystemAttr.relations !== undefined && extSystemAttr.relations.length > 0) {
+ // remove all children
+ let indices = new Array<number>();
+ for (let h in extSystemAttr.relations) {
+ // the mdm attributes
+ indices = indices.concat(this.getIndicesForIds(extSystemAttr.relations[h].ids));
+ }
+ indices.sort((a, b) => b - a);
+ for (let i in indices) {
+ this.extSystemAttrs.splice(indices[i], 1);
+ }
+ }
+ }
+ }
+ }
+ this.selectedExtSystemAttr = undefined;
+ }
+
+ saveExtSystem() {
+ this.getAttributeFromNode(this.selectedExtSystem, 'Name').value = this.selectedExtSystem.name;
+ this.extSystemService.saveExtSystem(this.selectedEnvironment.sourceName, this.selectedExtSystem)
+ .subscribe(
+ response => { /* discard */ },
+ error => this.notificationService.notifyError(
+ this.translateService.instant('administration.extsystem.err-cannot-update-ext-system'), error)
+ );
+ }
+
+ patchResponseAttr(nodes: Node[]) {
+ for (let i in nodes) {
+ if (nodes[i].name === this.tmpExtSystemAttr.name) {
+ if (this.tmpExtSystemAttr.id === undefined) {
+ this.extSystemAttrs.push(this.tmpExtSystemAttr);
+ }
+ this.tmpExtSystemAttr.id = nodes[i].id;
+ }
+ }
+ this.tmpExtSystemAttr = undefined;
+ this.tmpNode = undefined;
+ }
+
+ saveDialogExtSystemAttr() {
+ if (this.tmpExtSystemAttr.id === undefined) {
+ // add relation
+ if (this.selectedExtSystem.relations === undefined || this.selectedExtSystem.relations.length == 0) {
+ this.selectedExtSystem.relations = new Array();
+ let relation = new Relation();
+ relation.entityType = 'ExtSystemAttribute';
+ relation.type = 'CHILDREN';
+ relation.ids = new Array();
+ this.selectedExtSystem.relations.push(relation);
+ }
+ if (this.selectedExtSystem.relations[0].ids === undefined) {
+ this.selectedExtSystem.relations[0].ids = new Array();
+ }
+ this.tmpExtSystemAttr.id = undefined;
+ }
+ // update the name attribute
+ this.getAttributeFromNode(this.tmpExtSystemAttr, 'Name').value = this.tmpExtSystemAttr.name;
+ this.extSystemService.saveExtSystemAttr(this.selectedEnvironment.sourceName, this.tmpExtSystemAttr, this.selectedExtSystem)
+ .subscribe(
+ response => this.patchResponseAttr(plainToClass(Node, response.json().data)),
+ error => {
+ this.notificationService.notifyError(
+ this.translateService.instant('administration.extsystem.err-cannot-save-ext-system-attr'), error);
+ // restore values
+ this.getAttributeFromNode(this.tmpExtSystemAttr, 'Name').value = this.getAttributeValueFromNode(this.tmpNode, 'Name');
+ this.getAttributeFromNode(this.tmpExtSystemAttr, 'Description').value = this.getAttributeValueFromNode(this.tmpNode, 'Description');
+ this.tmpExtSystemAttr.name = this.getAttributeValueFromNode(this.tmpExtSystemAttr, 'Name');
+ this.tmpNode = undefined;
+ }
+ );
+
+ this.dialogExtSystemAttr = false;
+ }
+
+ cancelDialogExtSystemAttr() {
+ this.dialogExtSystemAttr = false;
+ this.getAttributeFromNode(this.tmpExtSystemAttr, 'Name').value = this.getAttributeValueFromNode(this.tmpNode, 'Name');
+ this.getAttributeFromNode(this.tmpExtSystemAttr, 'Description').value = this.getAttributeValueFromNode(this.tmpNode, 'Description');
+ this.tmpExtSystemAttr.name = this.getAttributeValueFromNode(this.tmpExtSystemAttr, 'Name');
+ this.tmpExtSystemAttr = undefined;
+ }
+
+ addExtSystemMDMAttr() {
+ this.tmpExtSystemMDMAttr = new Node();
+ this.tmpExtSystemMDMAttr.type = 'MDMAttribute';
+ this.tmpExtSystemMDMAttr.sourceType = 'MDMAttr';
+ this.tmpExtSystemMDMAttr.sourceName = this.selectedEnvironment.sourceName;
+ this.tmpExtSystemMDMAttr.attributes = new Array();
+ this.tmpExtSystemMDMAttr.attributes.push(this.createAttribute('AttrName'));
+ this.tmpExtSystemMDMAttr.attributes.push(this.createAttribute('CompName'));
+ this.tmpExtSystemMDMAttr.attributes.push(this.createAttribute('CompType'));
+ this.tmpExtSystemMDMAttr.attributes.push(this.createAttribute('MimeType', 'application/x-asam.aoany.mdmattr'));
+ // the name is the hierarchy from the parent elements appended with the name, set in save method
+ this.tmpExtSystemMDMAttr.attributes.push(this.createAttribute('Name'));
+ this.dialogExtSystemMDMAttr = true;
+ }
+
+ editExtSystemMDMAttr(extSystemMDMAttr?: Node) {
+ if (extSystemMDMAttr != undefined) {
+ this.tmpNode = JSON.parse(JSON.stringify(extSystemMDMAttr));
+ this.tmpExtSystemMDMAttr = extSystemMDMAttr;
+ // trigger data reload
+ this.tmpAttributeComps = [];
+ this.loadedAttributeComps = new Array();
+ this.dialogExtSystemMDMAttr = true;
+ this.getAttributeComponentStr();
+ }
+ }
+
+ removeExtSystemMDMAttr(extSystemMDMAttr?: Node) {
+ if (extSystemMDMAttr != undefined) {
+ if (this.extSystemAttrs.indexOf(extSystemMDMAttr) !== -1) {
+ if (extSystemMDMAttr.id !== undefined && parseInt(extSystemMDMAttr.id) > 0) {
+ this.extSystemService.deleteExtSystemMDMAttr(this.selectedEnvironment.sourceName, extSystemMDMAttr.id).subscribe();
+ this.extSystemAttrs.splice(this.extSystemAttrs.indexOf(extSystemMDMAttr), 1);
+ }
+ }
+ }
+ this.selectedExtSystemMDMAttr = undefined;
+ }
+
+ patchResponseMDMAttr(nodes: Node[]) {
+ for (let i in nodes) {
+ if (nodes[i].name === this.tmpExtSystemMDMAttr.name) {
+ if (this.tmpExtSystemMDMAttr.id === undefined) {
+ this.extSystemAttrs.push(this.tmpExtSystemMDMAttr);
+ }
+ this.tmpExtSystemMDMAttr.id = nodes[i].id;
+ for (let j in this.selectedExtSystemAttr.relations) {
+ if (this.selectedExtSystemAttr.relations[j].entityType === 'MDMAttribute') {
+ if (this.selectedExtSystemAttr.relations[j].ids === undefined) {
+ this.selectedExtSystemAttr.relations[j].ids = new Array();
+ };
+ this.selectedExtSystemAttr.relations[j].ids.push(nodes[i].id);
+ }
+ }
+ }
+ }
+ this.tmpExtSystemMDMAttr = undefined;
+ this.tmpNode = undefined;
+ }
+
+ saveDialogExtSystemMDMAttr() {
+ if (this.tmpExtSystemMDMAttr.id === undefined) {
+ // add relation
+ if (this.selectedExtSystemAttr.relations === undefined || this.selectedExtSystemAttr.relations.length == 0) {
+ this.selectedExtSystemAttr.relations = new Array();
+ let relation = new Relation();
+ relation.entityType = 'MDMAttribute';
+ relation.type = 'CHILDREN';
+ relation.ids = new Array();
+ this.selectedExtSystemAttr.relations.push(relation);
+ }
+ if (this.selectedExtSystemAttr.relations[0].ids === undefined) {
+ this.selectedExtSystemAttr.relations[0].ids = new Array();
+ }
+ this.tmpExtSystemMDMAttr.id = undefined;
+ }
+ // update the name attribute with the hierarchy
+ this.tmpExtSystemMDMAttr.name = this.getAttributeValueFromNode(this.tmpExtSystemMDMAttr, 'CompType') + '.' + this.getAttributeValueFromNode(this.tmpExtSystemMDMAttr, 'CompName') + '.' + this.getAttributeValueFromNode(this.tmpExtSystemMDMAttr, 'AttrName');
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'Name').value = this.tmpExtSystemMDMAttr.name;
+ this.extSystemService.saveExtSystemMDMAttr(this.selectedEnvironment.sourceName, this.tmpExtSystemMDMAttr, this.selectedExtSystemAttr)
+ .subscribe(
+ response => this.patchResponseMDMAttr(plainToClass(Node, response.json().data)),
+ error => {
+ this.notificationService.notifyError(
+ this.translateService.instant('administration.extsystem.err-cannot-save-ext-mdm-attr'), error);
+ // restore values
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'Name').value = this.getAttributeValueFromNode(this.tmpNode, 'Name');
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'CompType').value = this.getAttributeValueFromNode(this.tmpNode, 'CompType');
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'CompName').value = this.getAttributeValueFromNode(this.tmpNode, 'CompName');
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'AttrName').value = this.getAttributeValueFromNode(this.tmpNode, 'AttrName');
+ this.tmpExtSystemMDMAttr.name = this.getAttributeValueFromNode(this.tmpExtSystemMDMAttr, 'Name');
+ this.tmpNode = undefined;
+ }
+ );
+
+ this.dialogExtSystemMDMAttr = false;
+ }
+
+ cancelDialogExtSystemMDMAttr() {
+ this.dialogExtSystemMDMAttr = false;
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'Name').value = this.getAttributeValueFromNode(this.tmpNode, 'Name');
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'CompType').value = this.getAttributeValueFromNode(this.tmpNode, 'CompType');
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'CompName').value = this.getAttributeValueFromNode(this.tmpNode, 'CompName');
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'AttrName').value = this.getAttributeValueFromNode(this.tmpNode, 'AttrName');
+ this.tmpExtSystemMDMAttr = undefined;
+ }
+
+ async loadCatalogComps(type: string) {
+ if (type !== undefined && type != null && type.length > 0) {
+ this.tmpCatalogComps = [];
+ this.tmpAttributeComps = [];
+ this.loadedCatalogComps[type] = [];
+ this.loadedAttributeComps = new Array();
+
+ if (this.loadedTemplateRoots[type] === undefined) {
+ await this.catalogService.getTplRootsForType(this.selectedEnvironment.sourceName, type)
+ .subscribe(
+ response => this.loadedTemplateRoots[type] = response,
+ error => this.notificationService.notifyError(
+ this.translateService.instant('administration.extsystem.err-cannot-load-comp-types'), error)
+ );
+ }
+
+ if (this.loadedTemplateRoots[type] !== undefined) {
+ let tmpIds = '';
+ for (let i = 0; i < this.loadedTemplateRoots[type].length; i++) {
+ tmpIds = tmpIds + this.loadedTemplateRoots[type][i].id;
+ if (i + 1 < this.loadedTemplateRoots[type].length) tmpIds = tmpIds + ',';
+ }
+ this.dialogLoadingExtSystemComps = true;
+ await this.catalogService.getTplCompForRoot(this.selectedEnvironment.sourceName, type, tmpIds)
+ .subscribe(
+ response => {
+ for(let t in response) this.loadedCatalogComps[type].push(response[t])
+ this.dialogLoadingExtSystemComps = false;
+ },
+ error => {
+ this.notificationService.notifyError(
+ this.translateService.instant('administration.extsystem.err-cannot-load-comp-types'), error);
+ this.dialogLoadingExtSystemComps = false;
+ }
+ );
+ return true;
+ }
+ }
+ return false;
+ }
+
+ async loadAttributeComps(type: string, comp: string) {
+ if (type !== undefined && type != null && type.length > 0 && comp !== undefined && comp != null && comp.length > 0) {
+ this.loadedAttributeComps = new Array();
+ this.tmpAttributeComps = [];
+ let compId: string = '';
+ let rootId: string = '0';
+ for (let i in this.loadedCatalogComps[type]) {
+ if (this.loadedCatalogComps[type][i].name === comp) {
+ compId = this.loadedCatalogComps[type][i].id;
+ break;
+ }
+ }
+ for (let i in this.loadedTemplateRoots[type]) {
+ if (this.loadedTemplateRoots[type][i].relations !== undefined) {
+ for (let j in this.loadedTemplateRoots[type][i].relations) {
+ if (this.loadedTemplateRoots[type][i].relations[j].entityType === 'TemplateComponent' && this.loadedTemplateRoots[type][i].relations[j].ids !== undefined) {
+ for (let k in this.loadedTemplateRoots[type][i].relations[j].ids) {
+ if (this.loadedTemplateRoots[type][i].relations[j].ids[k] === compId) {
+ rootId = this.loadedTemplateRoots[type][i].id;
+ break;
+ }
+ }
+ if (rootId !== '0') break;
+ }
+ }
+ if (rootId !== '0') break;
+ }
+ }
+ this.dialogLoadingExtSystemAttrs = true;
+ if (rootId !== '0' && compId !== '') {
+ await this.catalogService.getTplAttrsForComp(this.selectedEnvironment.sourceName, type, rootId, compId)
+ .subscribe(
+ response => {
+ this.loadedAttributeComps = response;
+ this.dialogLoadingExtSystemAttrs = false;
+ },
+ error => {
+ this.notificationService.notifyError(
+ this.translateService.instant('administration.extsystem.err-cannot-load-comp-types'), error);
+ this.dialogLoadingExtSystemAttrs = false;
+ }
+ );
+ return true;
+ }
+ this.dialogLoadingExtSystemAttrs = false;
+ } else {
+ return false;
+ }
+ }
+
+ getCatalogComponentStr() {
+ let type: string = this.getAttributeValueFromNode(this.tmpExtSystemMDMAttr, 'CompType');
+ let data: string[] = new Array();
+ // sensor does not have catalog elements
+ if (type !== undefined && type !== 'Sensor') {
+ let tmp = this.getCatalogComponents(type);
+ for (let i in tmp) {
+ data.push(tmp[i].name);
+ }
+ }
+ return data;
+ }
+
+ getAttributeComponentStr() {
+ let type: string = this.getAttributeValueFromNode(this.tmpExtSystemMDMAttr, 'CompType');
+ let comp: string = this.getAttributeValueFromNode(this.tmpExtSystemMDMAttr, 'CompName');
+ let data: string[] = new Array();
+ if (type !== undefined && comp !== undefined) {
+ let tmp = this.getAttributeComponents(type, comp);
+ for (let i in tmp) {
+ data.push(tmp[i].name);
+ }
+ }
+ return data;
+ }
+
+ getCatalogComponents(type: string) {
+ let data: Node[] = this.loadedCatalogComps[type];
+ if (data === undefined || data == null || data.length == 0) {
+ if (this.loadCatalogComps(type)) {
+ data = this.loadedCatalogComps[type];
+ }
+ }
+ return data;
+ }
+
+ getAttributeComponents(type: string, comp: string) {
+ let data: Node[] = this.loadedAttributeComps;
+ if (data === undefined || data == null || data.length == 0) {
+ if (this.loadAttributeComps(type, comp)) {
+ data = this.loadedAttributeComps;
+ }
+ }
+ return data;
+ }
+
+ searchCatalogComps(event) {
+ this.tmpCatalogComps = [];
+ for (let i = 0; i < this.getCatalogComponentStr().length; i++) {
+ let item = this.getCatalogComponentStr()[i];
+ if (item !== undefined && item.toLowerCase().indexOf(event.query.toLowerCase()) == 0) {
+ this.tmpCatalogComps.push(item);
+ }
+ }
+ }
+
+ searchAttributeComps(event) {
+ this.tmpAttributeComps = [];
+ for (let i = 0; i < this.getAttributeComponentStr().length; i++) {
+ let item = this.getAttributeComponentStr()[i];
+ if (item !== undefined && item.toLowerCase().indexOf(event.query.toLowerCase()) == 0) {
+ this.tmpAttributeComps.push(item);
+ }
+ }
+ }
+
+ handleCompTypeSelect(event) {
+ this.tmpAttributeComps = [];
+ this.tmpCatalogComps = [];
+ this.loadedAttributeComps = new Array();
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'CompName').value = '';
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'AttrName').value = '';
+ this.getCatalogComponentStr();
+ }
+
+ handleCompSelect(event) {
+ this.tmpAttributeComps = [];
+ this.loadedAttributeComps = new Array();
+ this.getAttributeFromNode(this.tmpExtSystemMDMAttr, 'AttrName').value = '';
+ this.getAttributeComponentStr();
+ }
+
+}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-viewer.component.html b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-viewer.component.html
new file mode 100644
index 0000000..543a87e
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-viewer.component.html
@@ -0,0 +1,127 @@
+<!-- ********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ******************************************************************************** -->
+
+ <div class="mdm-extsystem-viewer-container">
+
+ <p-table class="ext-system-table" [value]="getExternalSystems()" *ngIf="selectedEnvironment && extSystems" styleClass="table-hover"
+ (onRowSelect)="onExtSystemRowSelect($event)" (onRowUnselect)="onExtSystemRowUnselect($event)"
+ selectionMode="single" [(selection)]="selectedExtSystem">
+ <ng-template pTemplate="header">
+ <tr>
+ <th>{{ 'administration.extsystem.name' | translate }}</th>
+ <th>{{ 'administration.extsystem.description' | translate }}</th>
+ <th class="button-col"></th>
+ <th class="button-col"></th>
+ </tr>
+ </ng-template>
+ <ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
+ <tr [pSelectableRow]="rowData" [pSelectableRowIndex]="rowIndex" [pContextMenuRow]="rowData">
+ <td>
+ <span>{{rowData.name}}</span>
+ </td>
+ <td>
+ <span>{{getAttributeValueFromNode(rowData,'Description')}}</span>
+ </td>
+ <td>
+ <button type="button" class="btn btn-default pull-right" (click)="editExtSystem(rowData)" title="{{'administration.extsystem.btn-edit' | translate }}">
+ <span class="fa fa-pencil-square-o"></span>
+ </button>
+ </td>
+ <td>
+ <button type="button" class="btn btn-default pull-right" (click)="removeExtSystem(rowData)" title="{{'administration.extsystem.btn-del' | translate }}">
+ <span class="fa fa-times"></span>
+ </button>
+ </td>
+ </tr>
+ </ng-template>
+ </p-table>
+
+ <p-dialog header="{{ 'administration.extsystem.dialog-ext-system-delete-title' | translate }}" [(visible)]="dialogExtSystemDelete">
+ <div class="text">
+ <span>{{ 'administration.extsystem.dialog-ext-system-delete-text' | translate }}</span>
+ </div>
+ <div class="dialogcommands">
+ <button type="button" class="btn btn-default pull-right" (click)="confirmRemoveExtSystem()">
+ <span class="fa fa-plus"></span> {{'administration.extsystem.btn-del' | translate }}
+ </button>
+ <button type="button" class="btn btn-default pull-right" (click)="cancelRemoveExtSystem()">
+ <span class="fa fa-times"></span> {{'administration.extsystem.btn-cancel' | translate }}
+ </button>
+ </div>
+ </p-dialog>
+
+ <p-dialog header="{{ 'administration.extsystem.dialog-ext-system-title' | translate}}" [(visible)]="dialogExtSystemCreate">
+ <table *ngIf="tmpExtSystemCreate">
+ <tr>
+ <td>{{ 'administration.extsystem.name' | translate}}</td>
+ <td><input required type="text" [(ngModel)]="tmpExtSystemCreate.name" /></td>
+ </tr>
+ </table>
+ <div class="dialogcommands">
+ <button type="button" class="btn btn-default pull-right" (click)="saveDialogExtSystem()">
+ <span class="fa fa-plus"></span> {{'administration.extsystem.btn-save' | translate }}
+ </button>
+ <button type="button" class="btn btn-default pull-right" (click)="cancelDialogExtSystem()">
+ <span class="fa fa-times"></span> {{'administration.extsystem.btn-cancel' | translate }}
+ </button>
+ </div>
+ </p-dialog>
+
+ <div *ngIf="selectedEnvironment" class="commands">
+ <button type="button" class="btn btn-default pull-right" (click)="addExtSystem()">
+ <span class="fa fa-plus"></span> {{'administration.extsystem.btn-add' | translate }}
+ </button>
+ </div>
+
+ <div class="custom-split-pane" *ngIf="selectedExtSystem">
+ <div class="custom-split-pane-content custom-split-pane-left">
+ <div>{{ 'administration.extsystem.ext-system-attributes' | translate }}</div>
+ <p-table [value]="getExternalSystemAttributes()" selectionMode="single" [(selection)]="selectedExtSystemAttr">
+ <ng-template pTemplate="header">
+ <tr>
+ <th>{{ 'administration.extsystem.name' | translate }}</th>
+ <th>{{ 'administration.extsystem.description' | translate }}</th>
+ </tr>
+ </ng-template>
+ <ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
+ <tr [pSelectableRow]="rowData" [pSelectableRowIndex]="rowIndex" [pContextMenuRow]="rowData">
+ <td>{{rowData.name}}</td>
+ <td>{{getAttributeValueFromNode(rowData,'Description')}}</td>
+ </tr>
+ </ng-template>
+ </p-table>
+ <div *ngIf="loadingExtSystemAttr">{{ 'administration.extsystem.loading-attributes' | translate }}</div>
+ </div>
+ <div class="custom-split-pane-content custom-split-pane-right">
+ <div>{{ 'administration.extsystem.mdm-attributes' | translate }}</div>
+ <p-table *ngIf="selectedExtSystemAttr" [value]="getMDMAttributes()">
+ <ng-template pTemplate="header">
+ <tr>
+ <th>{{ 'administration.extsystem.component-type' | translate }}</th>
+ <th>{{ 'administration.extsystem.component-name' | translate }}</th>
+ <th>{{ 'administration.extsystem.attribute-name' | translate }}</th>
+ </tr>
+ </ng-template>
+ <ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
+ <tr>
+ <td>{{getAttributeValueFromNode(rowData,'CompType')}}</td>
+ <td>{{getAttributeValueFromNode(rowData,'CompName')}}</td>
+ <td>{{getAttributeValueFromNode(rowData,'AttrName')}}</td>
+ </tr>
+ </ng-template>
+ </p-table>
+ </div>
+ </div>
+
+ </div>
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-viewer.component.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-viewer.component.ts
new file mode 100644
index 0000000..a8daaf8
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem-viewer.component.ts
@@ -0,0 +1,270 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+import { Component, OnInit, ViewChild, Input, OnDestroy, Output, EventEmitter } from '@angular/core';
+import { FormGroup, FormControl, FormBuilder, FormArray, Validators } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+import { TranslateService } from '@ngx-translate/core';
+import { DropdownModule } from 'primeng/dropdown';
+import { TreeTableModule } from 'primeng/treetable';
+import { TreeNode, MenuItem } from 'primeng/api';
+import { ContextMenuModule } from 'primeng/contextmenu';
+import { TreeTable, TreeTableToggler, DataTable } from 'primeng/primeng';
+import { DialogModule } from 'primeng/dialog';
+import { Observable, BehaviorSubject } from 'rxjs';
+
+import { MDMNotificationService } from '../core/mdm-notification.service';
+import { ExtSystemService } from './extsystem.service';
+import { Node, Attribute } from '../navigator/node';
+import { plainToClass } from 'class-transformer';
+
+@Component( {
+ selector: 'mdm-extsystem-viewer',
+ templateUrl: './extsystem-viewer.component.html',
+ styleUrls: ['./extsystem.component.css']
+})
+export class ExtSystemViewerComponent implements OnInit, OnDestroy {
+
+ // passed down from parent
+ @Input() extSystems: Node[];
+ @Input() selectedEnvironment: Node;
+
+ @Output() editMode = new EventEmitter<boolean>();
+ @Output() selectedES = new EventEmitter<string>();
+
+ // dialog and loading states
+ dialogExtSystemCreate: boolean = false;
+ dialogExtSystemDelete: boolean = false;
+ loadingExtSystemAttr: boolean = false;
+
+ // temporary data for dialogs
+ tmpExtSystemCreate: Node;
+ tmpExtSystemDelete: Node;
+
+ // external system attributes
+ extSystemAttrs: Node[];
+ bsExtSystemAttrs: BehaviorSubject<Node[]> = new BehaviorSubject<Node[]>(undefined);
+
+ // table selection
+ selectedExtSystem: Node;
+ selectedExtSystemAttr: Node;
+
+ constructor(private extSystemService: ExtSystemService,
+ private notificationService: MDMNotificationService,
+ private translateService: TranslateService) {
+
+ this.bsExtSystemAttrs.subscribe(value => {
+ this.extSystemAttrs = value;
+ });
+ }
+
+ ngOnInit() {
+ this.bsExtSystemAttrs.next(undefined);
+ }
+
+
+ ngOnDestroy() {
+ }
+
+ getExternalSystems() {
+ let data = new Array();
+ for (let i in this.extSystems) {
+ if (this.extSystems[i].type === 'ExtSystem') {
+ data.push(this.extSystems[i]);
+ }
+ }
+ return data;
+ }
+ getExternalSystemAttributes() {
+ let data = new Array();
+ for (let i in this.extSystemAttrs) {
+ if (this.extSystemAttrs[i].type === 'ExtSystemAttribute') {
+ data.push(this.extSystemAttrs[i]);
+ }
+ }
+ return data;
+ }
+ getMDMAttributes() {
+ let ids = new Array();
+ for (let i in this.selectedExtSystemAttr.relations) {
+ if (this.selectedExtSystemAttr.relations[i].entityType === 'MDMAttribute') {
+ for (let j in this.selectedExtSystemAttr.relations[i].ids) {
+ ids.push(this.selectedExtSystemAttr.relations[i].ids[j]);
+ }
+ }
+ }
+ let data = new Array();
+ for (let i in this.extSystemAttrs) {
+ if (this.extSystemAttrs[i].type === 'MDMAttribute' && ids.find(el => el === this.extSystemAttrs[i].id)) {
+ data.push(this.extSystemAttrs[i]);
+ }
+ }
+ return data;
+ }
+
+ getAttributeValueFromNode(node: Node, attribute: string) {
+ for (let i in node.attributes) {
+ if (node.attributes[i].name === attribute) {
+ return node.attributes[i].value;
+ }
+ }
+ return '';
+ }
+
+ getAttributeFromNode(node: Node, attribute: string) {
+ if (node.attributes !== undefined) {
+ for (let i in node.attributes) {
+ if (node.attributes[i].name === attribute) {
+ return node.attributes[i];
+ }
+ }
+ }
+ return undefined;
+ }
+
+ onExtSystemRowSelect(event: any) {
+ this.selectedExtSystemAttr = undefined;
+ this.bsExtSystemAttrs.next(undefined);
+ this.loadingExtSystemAttr = true;
+ this.selectedExtSystem = event.data;
+ this.extSystemService.getExtSystemAttributesForScope(this.selectedEnvironment.sourceName, this.selectedExtSystem.id).subscribe(attrs => {
+ this.bsExtSystemAttrs.next(attrs);
+ this.loadingExtSystemAttr = false;
+ });
+ }
+
+ onExtSystemRowUnselect(event: any) {
+ this.selectedExtSystem = undefined;
+ this.bsExtSystemAttrs.next(undefined);
+ }
+
+
+ createAttribute(name: string, value?: string) {
+ let attr = new Attribute();
+ attr.dataType = 'STRING';
+ attr.unit = '';
+ attr.value = value !== undefined ? value : '';
+ attr.name = name;
+ return attr;
+ }
+
+ getIndicesForIds(ids: string[]) {
+ let indices = new Array();
+ for (let id in ids) {
+ for (let i in this.extSystems) {
+ if (this.extSystems[i].id === ids[id]) {
+ indices.push(this.extSystems.indexOf(this.extSystems[i]));
+ }
+ }
+ }
+ return indices;
+ }
+
+ addExtSystem() {
+ this.tmpExtSystemCreate = new Node();
+ this.tmpExtSystemCreate.type = 'ExtSystem';
+ this.tmpExtSystemCreate.sourceType = 'ExtSystem';
+ this.tmpExtSystemCreate.sourceName = this.selectedEnvironment.sourceName;
+ this.tmpExtSystemCreate.attributes = new Array();
+ this.tmpExtSystemCreate.attributes.push(this.createAttribute('Description'));
+ this.tmpExtSystemCreate.attributes.push(this.createAttribute('Name'));
+ this.tmpExtSystemCreate.attributes.push(this.createAttribute('MimeType', 'application/x-asam.aoany.extsystem'));
+ this.dialogExtSystemCreate = true;
+ }
+
+ editExtSystem(extSystem?: Node) {
+ if (extSystem != undefined) {
+ this.tmpExtSystemCreate = extSystem;
+ //this.dialogExtSystem = true;
+ this.selectedES.next(extSystem.id);
+ this.editMode.next(true);
+ }
+ }
+
+ removeExtSystem(extSystem?: Node) {
+ this.tmpExtSystemDelete = extSystem;
+ this.dialogExtSystemDelete = true;
+ }
+
+ cancelRemoveExtSystem() {
+ this.tmpExtSystemDelete = undefined;
+ this.dialogExtSystemDelete = false;
+ }
+
+ confirmRemoveExtSystem() {
+ if (this.tmpExtSystemDelete != undefined) {
+ let idxES: number = this.extSystems.indexOf(this.tmpExtSystemDelete);
+ if (idxES !== -1) {
+ this.extSystems.splice(idxES, 1);
+ if (this.tmpExtSystemDelete.relations !== undefined && this.tmpExtSystemDelete.relations.length > 0) {
+ // remove all children
+ let indices = new Array<number>();
+ for (let h in this.tmpExtSystemDelete.relations) {
+ // the ext system attributes
+ let indicesESA = this.getIndicesForIds(this.tmpExtSystemDelete.relations[h].ids);
+ for (let i in indicesESA) {
+ for (let j in this.extSystems[indicesESA[i]].relations) {
+ // the mdm attributes
+ indices = indices.concat(this.getIndicesForIds(this.extSystems[indicesESA[i]].relations[j].ids));
+ }
+ }
+ indices = indices.concat(indicesESA);
+ }
+ indices.sort((a, b) => b - a);
+ for (let i in indices) {
+ this.extSystems.splice(indices[i], 1);
+ }
+ }
+ }
+ if (this.tmpExtSystemDelete.id !== undefined && parseInt(this.tmpExtSystemDelete.id) > 0) {
+ this.extSystemService.deleteExtSystem(this.selectedEnvironment.sourceName, this.tmpExtSystemDelete.id).subscribe();
+ }
+ }
+ this.selectedExtSystem = undefined;
+ this.tmpExtSystemDelete = undefined;
+ this.dialogExtSystemDelete = false;
+ }
+
+ // for new external systems only
+ saveDialogExtSystem() {
+ // update the name attribute
+ this.getAttributeFromNode(this.tmpExtSystemCreate, 'Name').value = this.tmpExtSystemCreate.name;
+ this.extSystemService.saveExtSystem(this.selectedEnvironment.sourceName, this.tmpExtSystemCreate)
+ .subscribe(
+ response => this.patchResponse(plainToClass(Node, response.json().data)),
+ error => this.notificationService.notifyError(
+ this.translateService.instant('administration.extsystem.err-cannot-save-ext-system'), error)
+ );
+ this.dialogExtSystemCreate = false;
+ }
+
+ cancelDialogExtSystem() {
+ this.dialogExtSystemCreate = false;
+ this.tmpExtSystemCreate = undefined;
+ }
+
+ patchResponse(nodes: Node[]) {
+ for (let i in nodes) {
+ if (nodes[i].name === this.tmpExtSystemCreate.name) {
+ if (this.tmpExtSystemCreate.id === undefined) {
+ this.extSystems.push(this.tmpExtSystemCreate);
+ }
+ this.tmpExtSystemCreate.id = nodes[i].id;
+ }
+ }
+ this.tmpExtSystemCreate = undefined;
+ }
+
+}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.css b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.css
new file mode 100644
index 0000000..7044280
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.css
@@ -0,0 +1,67 @@
+@charset "ISO-8859-1";
+
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+.mdm-extsystem-viewer-container,
+.mdm-extsystem-editor-container{display:block;}
+
+ .mdm-extsystem-editor-container .commands,
+ .mdm-extsystem-viewer-container .commands,
+ .extsystem-comp .commands,
+ .extsystem-comp .commands {
+ min-height: 30px;
+ display: block;
+ margin-bottom: 10px;
+ margin-top:6px;
+ width: 100%;
+ }
+ .mdm-extsystem-editor-container .commands button,
+ .mdm-extsystem-viewer-container .commands button,
+ .extsystem-comp .commands button,
+ .extsystem-comp .commands button {
+ margin-left: 10px;
+ }
+
+.ext-system-table {
+ margin-top: 10px;
+}
+ .ext-system-table .button-col{
+ width:60px;
+ }
+ .ext-system-table td input{width:100%;}
+
+ .custom-split-pane {
+ display: block;
+ margin-top: 20px;
+ }
+.custom-split-pane-content{display: inline-block;}
+.custom-split-pane-left{width:48%;vertical-align:top;}
+.custom-split-pane-right {
+ margin-left: 1%;
+ width: 48%;
+ vertical-align: top;
+}
+
+.dialogcommands {padding-top:10px;min-height:45px;}
+.dialogcommands button {margin-left:10px;}
+
+.dialog-extsystem-mdmattr{height:200px;}
+ .dialog-extsystem-mdmattr .floattext {
+ position: absolute;
+ right: 70px;
+ margin-top:7px;
+ z-index:1001;
+ }
+ .dialog-extsystem-mdmattr .floattext .text{font-size:9pt;}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.html b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.html
new file mode 100644
index 0000000..a03a9ba
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.html
@@ -0,0 +1,35 @@
+<!-- ********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ******************************************************************************** -->
+
+<div class="extsystem-comp">
+ <div *ngIf="!environments">{{ 'administration.extsystem.loading' | translate }}</div>
+
+ <div class="system-selector">
+ <div *ngIf="!selectedEnvironment" style="display:inline;">{{ 'administration.extsystem.select-system' | translate }}:</div>
+ <div *ngIf="selectedEnvironment" style="display:inline;">{{ 'administration.extsystem.selected-system' | translate }}:</div>
+ <p-dropdown [options]="environments" [(ngModel)]="selectedEnvironment" optionLabel="sourceName" (onChange)="onChangeExtSystem($event)" placeholder="{{ 'administration.extsystem.dropdown-please-select' | translate }}"></p-dropdown>
+ </div>
+
+ <div *ngIf="selectedEnvironment && extSystems">
+
+ <div class="commands">
+ <button *ngIf="editorMode" type="button" class="btn btn-default pull-right" (click)="onPageBack()">
+ <span class="fa fa-reply"></span> {{'administration.extsystem.btn-back' | translate }}
+ </button>
+ </div>
+
+ <mdm-extsystem-editor *ngIf="editorMode" [selectedEnvironment]="selectedEnvironment" [extSystems]="extSystems" (editMode)="onEditModeChange($event)" [selectedES]="selectedExtSystem"></mdm-extsystem-editor>
+ <mdm-extsystem-viewer *ngIf="!editorMode" [selectedEnvironment]="selectedEnvironment" [extSystems]="extSystems" (editMode)="onEditModeChange($event)" (selectedES)="onChangeSelectedExtSystem($event)"></mdm-extsystem-viewer>
+ </div>
+</div>
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.ts
new file mode 100644
index 0000000..e6e0757
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.component.ts
@@ -0,0 +1,103 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+import { Component, OnInit, ViewChild, Input, OnDestroy } from '@angular/core';
+import { FormGroup, FormControl, FormBuilder, FormArray, Validators } from '@angular/forms';
+import { TranslateService } from '@ngx-translate/core';
+import { DropdownModule } from 'primeng/dropdown';
+import { TreeTableModule } from 'primeng/treetable';
+import { TreeNode, MenuItem } from 'primeng/api';
+import { ContextMenuModule } from 'primeng/contextmenu';
+import { TreeTable, TreeTableToggler, DataTable } from 'primeng/primeng';
+import { DialogModule } from 'primeng/dialog';
+import { Observable, BehaviorSubject } from 'rxjs';
+
+import { MDMNotificationService } from '../core/mdm-notification.service';
+import { ExtSystemService } from './extsystem.service';
+import { Node } from '../navigator/node';
+import { NodeService } from '../navigator/node.service';
+
+@Component( {
+ selector: 'mdm-extsystem',
+ templateUrl: './extsystem.component.html',
+ styleUrls: ['./extsystem.component.css']
+})
+export class ExtSystemComponent implements OnInit, OnDestroy {
+
+ // available external systems
+ extSystems: Node[];
+ bsExtSystems: BehaviorSubject<Node[]> = new BehaviorSubject<Node[]>(undefined);
+ selectedEnvironment: Node;
+
+ editorMode: boolean = false;
+ selectedExtSystem: string = undefined;
+
+ // dropdown selection
+ environments: Node[];
+
+ // unknown -> remove
+ scope: string;
+
+ constructor(private extSystemService: ExtSystemService,
+ private notificationService: MDMNotificationService,
+ private translateService: TranslateService,
+ private nodeService: NodeService) {
+
+ this.bsExtSystems.subscribe(value => {
+ this.extSystems = value;
+ });
+ }
+
+ ngOnInit() {
+ this.nodeService.getRootNodes().subscribe(
+ envs => this.environments = envs,
+ error => this.translateService.instant('basket.mdm-basket.err-cannot-load-sources')
+ .subscribe(msg => this.notificationService.notifyError(msg, error)
+ ));
+
+ this.bsExtSystems.next(undefined);
+ }
+
+ ngOnDestroy() {
+ }
+
+ onEditModeChange(editMode: boolean) {
+ this.editorMode = editMode;
+ }
+
+ onChangeSelectedExtSystem(extSystem: string) {
+ this.selectedExtSystem = extSystem;
+ }
+
+ onChangeExtSystem(event: any) {
+ this.extSystems = undefined;
+ if (this.selectedEnvironment !== undefined)
+ this.scope = this.selectedEnvironment.sourceName;
+ this.extSystemService.getExtSystemForScope(this.scope)
+ .subscribe(es => {
+ this.bsExtSystems.next(es);
+ });
+ }
+
+
+ onPageSwitchToEdit() {
+ this.onEditModeChange(true);
+ }
+
+ onPageBack() {
+ this.onEditModeChange(false);
+ }
+
+}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.service.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.service.ts
new file mode 100644
index 0000000..0bd2ff4
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/extsystem.service.ts
@@ -0,0 +1,166 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+import { Injectable } from '@angular/core';
+import { Http, Response, Headers, RequestOptions } from '@angular/http';
+
+import { PropertyService } from '../core/property.service';
+
+import { plainToClass } from 'class-transformer';
+import { HttpErrorHandler } from '../core/http-error-handler';
+import { throwError as observableThrowError, Observable } from 'rxjs';
+import { map, catchError } from 'rxjs/operators';
+import { Node } from '../navigator/node';
+
+@Injectable()
+export class ExtSystemService {
+
+ private prefEndpoint: string;
+
+ constructor(private http: Http,
+ private httpErrorHandler: HttpErrorHandler,
+ private _prop: PropertyService) {
+ this.prefEndpoint = _prop.getUrl('mdm/administration/');
+ }
+
+ getExtSystemForScope(scope: string, key?: string): Observable<Node[]> {
+ if (key == null) {
+ key = '';
+ }
+
+ return this.http.get(this.prefEndpoint + scope + '/externalsystems').pipe(
+ map(response => plainToClass(Node, response.json().data)),
+ catchError(this.handleError));
+ }
+
+ getExtSystemAttributesForScope(scope: string, id: string, key?: string): Observable<Node[]> {
+ if (key == null) {
+ key = '';
+ }
+
+ return this.http.get(this.prefEndpoint + scope + '/externalsystems/attributes/' + id).pipe(
+ map(response => plainToClass(Node, response.json().data)),
+ catchError(this.handleError));
+ }
+
+ getExtSystem(key?: string) {
+ if (key == null) {
+ key = '';
+ }
+ return this.http.get(this.prefEndpoint + '?key=' + key).pipe(
+ map(response => plainToClass(Node, response.json().data)),
+ catchError(this.handleError));
+ }
+
+ getAttributeValueFromNode(node: Node, attribute: string) {
+ if (node.attributes !== undefined) {
+ for (let i in node.attributes) {
+ if (node.attributes[i].name === attribute) {
+ return node.attributes[i].value;
+ }
+ }
+ }
+ return '';
+ }
+
+ saveExtSystemAttr(scope: string, extSystemAttr: Node, extSystem: Node) {
+ let headers = new Headers({ 'Content-Type': 'application/json' });
+ let options = new RequestOptions({ headers: headers });
+
+ let structure = {};
+ structure['Name'] = extSystemAttr.name;
+
+ if (parseInt(extSystemAttr.id) > 0) {
+ structure['Description'] = this.getAttributeValueFromNode(extSystemAttr, 'Description');
+ // update
+ return this.http.put(this.prefEndpoint + scope + '/externalsystems/attribute/' + extSystemAttr.id, JSON.stringify(structure), options).pipe(
+ catchError(this.handleError));
+ } else {
+ structure['ExtSystemAttribute'] = extSystemAttr;
+ // only provide the ID as the backend will evaluate the whole json string
+ structure['ExtSystem'] = extSystem.id;
+ // create
+ return this.http.post(this.prefEndpoint + scope + '/externalsystems/attribute', JSON.stringify(structure), options).pipe(
+ catchError(this.handleError));
+ }
+ }
+
+ saveExtSystemMDMAttr(scope: string, extSystemMDMAttr: Node, extSystemAttr: Node) {
+ let headers = new Headers({ 'Content-Type': 'application/json' });
+ let options = new RequestOptions({ headers: headers });
+
+ let structure = {};
+ structure['Name'] = extSystemMDMAttr.name;
+
+ if (parseInt(extSystemMDMAttr.id) > 0) {
+ structure['CompType'] = this.getAttributeValueFromNode(extSystemMDMAttr, 'CompType');
+ structure['CompName'] = this.getAttributeValueFromNode(extSystemMDMAttr, 'CompName');
+ structure['AttrName'] = this.getAttributeValueFromNode(extSystemMDMAttr, 'AttrName');
+ // update
+ return this.http.put(this.prefEndpoint + scope + '/externalsystems/mdmattribute/' + extSystemMDMAttr.id, JSON.stringify(structure), options).pipe(
+ catchError(this.handleError));
+ } else {
+ structure['MDMAttribute'] = extSystemMDMAttr;
+ structure['ExtSystemAttribute'] = extSystemAttr.id;
+ // create
+ return this.http.post(this.prefEndpoint + scope + '/externalsystems/mdmattribute', JSON.stringify(structure), options).pipe(
+ catchError(this.handleError));
+ }
+ }
+
+ saveExtSystem(scope: string, extSystem: Node) {
+ let headers = new Headers({ 'Content-Type': 'application/json' });
+ let options = new RequestOptions({ headers: headers });
+
+ let structure = {};
+ structure['Name'] = extSystem.name;
+
+ if (parseInt(extSystem.id) > 0) {
+ // update
+ structure['Description'] = this.getAttributeValueFromNode(extSystem, 'Description');
+ return this.http.put(this.prefEndpoint + scope + '/externalsystems/' + extSystem.id, JSON.stringify(structure), options).pipe(
+ catchError(this.handleError));
+ } else {
+ structure['ExtSystem'] = extSystem;
+ // create
+ return this.http.post(this.prefEndpoint + scope + '/externalsystems', JSON.stringify(structure), options).pipe(
+ catchError(this.handleError));
+ }
+ }
+
+ deleteExtSystem(scope: string, id: string) {
+ return this.http.delete(this.prefEndpoint + scope + '/externalsystems/' + id).pipe(
+ catchError(this.handleError));
+ }
+ deleteExtSystemAttr(scope: string, id: string) {
+ return this.http.delete(this.prefEndpoint + scope + '/externalsystems/attribute/' + id).pipe(
+ catchError(this.handleError));
+ }
+ deleteExtSystemMDMAttr(scope: string, id: string) {
+ return this.http.delete(this.prefEndpoint + scope + '/externalsystems/mdmattribute/' + id).pipe(
+ catchError(this.handleError));
+ }
+
+ private handleError(e: Error | any) {
+ if (e instanceof Response) {
+ let response = <Response> e;
+ if (response.status !== 200) {
+ return observableThrowError('Could not request extSystems! '
+ + 'Please check if application server is running and extSystem database is configured correctly.');
+ }
+ }
+ return this.httpErrorHandler.handleError(e);
+ }
+}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-module.component.html b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-module.component.html
new file mode 100644
index 0000000..e818119
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-module.component.html
@@ -0,0 +1,30 @@
+<!--/********************************************************************************
+* Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+*
+* See the NOTICE file(s) distributed with this work for additional
+* information regarding copyright ownership.
+*
+* This program and the accompanying materials are made available under the
+* terms of the Eclipse Public License v. 2.0 which is available at
+* http://www.eclipse.org/legal/epl-2.0.
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+********************************************************************************/-->
+
+<nav class="navbar navbar-default navbar-expand bg-light">
+ <div class="container-fluid">
+ <div class="collapse navbar-collapse" id="bs-admin-navbar">
+ <a class="navbar-brand" style="font-weight: 500;">{{'administration.admin-modules.scope' | translate }}</a>
+ <ul class="nav navbar-nav mdm-link-list">
+ <li *ngFor="let m of links" [routerLinkActive]="['active']" class="nav-item">
+ <a (click)="onScopeChange(m.path)" routerLink="{{m.path}}" class="nav-link" style="cursor:pointer;">
+ {{m.name | translate}}
+ </a>
+ </li>
+ </ul>
+ </div>
+
+ </div>
+</nav>
+<mdm-preference [scope]="scope" [preferences]="preferences"></mdm-preference>
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-module.component.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-module.component.ts
new file mode 100644
index 0000000..ab14b0a
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-module.component.ts
@@ -0,0 +1,52 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+import {Component, OnInit} from '@angular/core';
+import {Router} from '@angular/router';
+
+import { TRANSLATE } from '../core/mdm-core.module';
+import { PreferenceService, Preference } from '../core/preference.service';
+
+@Component({
+ selector: 'preference-module',
+ templateUrl: 'preference-module.component.html',
+ providers: []
+})
+export class PreferenceModuleComponent implements OnInit {
+
+ preferences: Preference[];
+ scope: string;
+ sub: any;
+
+ links = [
+ { name: TRANSLATE('administration.admin-modules.system'), path: 'system'},
+ { name: TRANSLATE('administration.admin-modules.source'), path: 'source'},
+ { name: TRANSLATE('administration.admin-modules.user'), path: 'user'}
+ ];
+ constructor(private router: Router,
+ private preferenceService: PreferenceService) { }
+
+ ngOnInit() {
+ this.onScopeChange('system');
+ }
+
+ onScopeChange(path: string) {
+ this.scope = path.toUpperCase();
+ if (this.scope !== undefined) {
+ this.preferenceService.getPreferenceForScope(this.scope)
+ .subscribe(pref => this.preferences = pref);
+ }
+ }
+}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-routing.module.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-routing.module.ts
new file mode 100644
index 0000000..b36bfc4
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference-routing.module.ts
@@ -0,0 +1,41 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+
+import { PreferenceComponent } from './preference.component';
+import { PreferenceModuleComponent } from './preference-module.component';
+
+const moduleRoutes: Routes = [
+ {
+ path: '', component: PreferenceModuleComponent,
+ children: [
+ { path: ':scope', component: PreferenceComponent },
+ { path: '', redirectTo: 'system', pathMatch: 'full' }
+ ]
+ }
+];
+
+@NgModule({
+ imports: [
+ RouterModule.forChild(moduleRoutes)
+ ],
+ exports: [
+ RouterModule
+ ]
+})
+
+export class PreferenceRoutingModule { }
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference.component.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference.component.ts
index 72f49a6..45f466e 100644
--- a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference.component.ts
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference.component.ts
@@ -20,7 +20,7 @@
import { PreferenceService, Preference, Scope } from '../core/preference.service';
import { EditPreferenceComponent } from './edit-preference.component';
-import {MDMNotificationService} from '../core/mdm-notification.service';
+import { MDMNotificationService } from '../core/mdm-notification.service';
import { TranslateService } from '@ngx-translate/core';
@@ -32,7 +32,7 @@
export class PreferenceComponent implements OnInit, OnDestroy {
@Input() preferences: Preference[];
- scope: string;
+ @Input() scope: string;
subscription: any;
sub: any;
@@ -46,21 +46,10 @@
private translateService: TranslateService) { }
ngOnInit() {
- this.sub = this.route.params.subscribe(
- params => this.onScopeChange(params),
- error => this.notificationService.notifyError(
- this.translateService.instant('administration.edit-preference.err-cannot-load-scope'), error)
- );
+
}
ngOnDestroy() {
- this.sub.unsubscribe();
- }
-
- onScopeChange(params: any) {
- this.scope = params['scope'].toUpperCase();
- this.preferenceService.getPreferenceForScope(this.scope)
- .subscribe(pref => this.preferences = pref);
}
editPreference( preference?: Preference ) {
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference.module.ts b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference.module.ts
new file mode 100644
index 0000000..49becfa
--- /dev/null
+++ b/org.eclipse.mdm.application/src/main/webapp/src/app/administration/preference.module.ts
@@ -0,0 +1,45 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+import { NgModule } from '@angular/core';
+import { PreferenceRoutingModule } from './preference-routing.module';
+import { PreferenceModuleComponent } from './preference-module.component';
+import { PreferenceComponent } from './preference.component';
+import { EditPreferenceComponent } from './edit-preference.component';
+import { MDMCoreModule } from '../core/mdm-core.module';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { PreferenceService } from '../core/preference.service';
+import { ComponentLoaderFactory } from 'ngx-bootstrap';
+
+
+@NgModule({
+ imports: [
+ MDMCoreModule,
+ FormsModule,
+ ReactiveFormsModule,
+ PreferenceRoutingModule
+ ],
+ declarations: [
+ EditPreferenceComponent,
+ PreferenceModuleComponent,
+ PreferenceComponent
+ ],
+ exports: [
+ ],
+ providers: [
+ ComponentLoaderFactory,
+ PreferenceService
+ ],
+})
+export class PreferenceModule {}
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/assets/i18n/de.json b/org.eclipse.mdm.application/src/main/webapp/src/assets/i18n/de.json
index 334a0a6..ad15cbf 100644
--- a/org.eclipse.mdm.application/src/main/webapp/src/assets/i18n/de.json
+++ b/org.eclipse.mdm.application/src/main/webapp/src/assets/i18n/de.json
@@ -1,31 +1,69 @@
{
- "administration": {
- "admin-modules": {
- "scope": "Geltungsbereich",
- "source": "Quelle",
- "system": "System",
- "user": "Benutzer"
- },
- "edit-preference": {
- "btn-cancel": "Abbrechen",
- "btn-save": "Speichern",
- "err-cannot-load-data-source": "Datenquelle kann nicht geladen werden.",
- "err-cannot-load-scope": "Geltungsbereich kann nicht geladen werden.",
- "lbl-key": "Schlüssel",
- "lbl-scope": "Geltungsbereich",
- "lbl-source": "Quelle",
- "lbl-value": "Wert",
- "title-preferences-editor": "Einstellungseditor",
- "tooltip-close": "Schließen"
- },
- "preference": {
- "btn-add-preference": "Einstellung hinzufügen",
- "btn-tooltip-delete-preference": "Entfernen",
- "btn-tooltip-edit-preference": "Bearbeiten",
- "err-cannot-save-preference": "Einstellung kann nicht gespeichert werden.",
- "err-cannot-update-preference": "Einstellung kann nicht aktualisiert werden."
- }
- },
+ "administration": {
+ "admin-modules": {
+ "scope": "Geltungsbereich",
+ "modules": "Module",
+ "source": "Quelle",
+ "system": "System",
+ "user": "Benutzer",
+ "extsystems": "Externe Systeme",
+ "preferences": "Präferenzen"
+ },
+ "edit-preference": {
+ "btn-cancel": "Abbrechen",
+ "btn-save": "Speichern",
+ "err-cannot-load-data-source": "Datenquelle kann nicht geladen werden.",
+ "err-cannot-load-scope": "Geltungsbereich kann nicht geladen werden.",
+ "lbl-key": "Schlüssel",
+ "lbl-scope": "Geltungsbereich",
+ "lbl-source": "Quelle",
+ "lbl-value": "Wert",
+ "title-preferences-editor": "Einstellungseditor",
+ "tooltip-close": "Schließen"
+ },
+ "preference": {
+ "btn-add-preference": "Einstellung hinzufügen",
+ "btn-tooltip-delete-preference": "Entfernen",
+ "btn-tooltip-edit-preference": "Bearbeiten",
+ "err-cannot-save-preference": "Einstellung kann nicht gespeichert werden.",
+ "err-cannot-update-preference": "Einstellung kann nicht aktualisiert werden."
+ },
+ "extsystem": {
+ "loading": "Lade Daten...",
+ "loading-short": "Lade",
+ "dropdown-please-select": "Bitte auswählen",
+ "select-system": "Datenquelle auswählen",
+ "selected-system": "Gewählte Datenquelle",
+ "name": "Name",
+ "description": "Beschreibung",
+ "ext-system-attributes": "Externes System Attribute",
+ "mdm-attributes": "MDM Attribute",
+ "btn-add": "Neu hinzufügen",
+ "btn-edit": "Bearbeiten",
+ "btn-del": "Entfernen",
+ "btn-save": "Speichern",
+ "btn-cancel": "Abbrechen",
+ "btn-back": "Zurück",
+ "component-type": "Komponenten-Typ",
+ "component-name": "Komponenten-Name",
+ "attribute-name": "Attribut-Name",
+ "dialog-ext-system-title": "Externes System",
+ "dialog-ext-system-attr-title": "Externes System Attribute",
+ "dialog-ext-system-mdm-attr-title": "MDM Attribute",
+ "dialog-ext-system-delete-title": "Externes System löschen",
+ "dialog-ext-system-delete-text": "Bitte bestätigen Sie das Löschen des Externen Systems",
+ "err-cannot-update-ext-system": "Externes System kann nicht gespeichert werden",
+ "err-cannot-save-ext-system": "Externes System kann nicht aktualisiert werden",
+ "err-cannot-save-ext-system-attr": "Externes System Attribut kann nicht gespeichert werden",
+ "err-cannot-save-ext-mdm-attr": "MDM Attribut kann nicht gespeichert werden",
+ "err-cannot-load-comp-types": "Komponententypen konnten nicht geladen werden",
+ "loading-attributes": "Lade Attribute...",
+ "sensor": "Sensor",
+ "test-equipment": "Messgerät",
+ "test-sequence": "Testablauf",
+ "unit-under-test": "Prüfling"
+ }
+ },
"app": {
"about": "Über",
"language": "Sprache",
diff --git a/org.eclipse.mdm.application/src/main/webapp/src/assets/i18n/en.json b/org.eclipse.mdm.application/src/main/webapp/src/assets/i18n/en.json
index 17e2c32..ac998b3 100644
--- a/org.eclipse.mdm.application/src/main/webapp/src/assets/i18n/en.json
+++ b/org.eclipse.mdm.application/src/main/webapp/src/assets/i18n/en.json
@@ -1,11 +1,14 @@
{
"administration": {
- "admin-modules": {
- "scope": "Scope",
- "source": "Source",
- "system": "System",
- "user": "User"
- },
+ "admin-modules": {
+ "scope": "Scope",
+ "modules": "Module",
+ "source": "Source",
+ "system": "System",
+ "user": "User",
+ "extsystems": "External Systems",
+ "preferences": "Preferences"
+ },
"edit-preference": {
"btn-cancel": "Cancel",
"btn-save": "Save",
@@ -18,13 +21,48 @@
"title-preferences-editor": "Preferences Editor",
"tooltip-close": "Close"
},
- "preference": {
- "btn-add-preference": "Add preference",
- "btn-tooltip-delete-preference": "Delete",
- "btn-tooltip-edit-preference": "Edit",
- "err-cannot-save-preference": "Cannot save preference.",
- "err-cannot-update-preference": "Cannot update preference."
- }
+ "preference": {
+ "btn-add-preference": "Add preference",
+ "btn-tooltip-delete-preference": "Delete",
+ "btn-tooltip-edit-preference": "Edit",
+ "err-cannot-save-preference": "Cannot save preference.",
+ "err-cannot-update-preference": "Cannot update preference."
+ },
+ "extsystem": {
+ "loading": "Loading data...",
+ "loading-short": "Loading",
+ "dropdown-please-select": "Please select...",
+ "select-system": "Select environment",
+ "selected-system": "Selected environment",
+ "name": "Name",
+ "description": "Description",
+ "ext-system-attributes": "Ext. system attributes",
+ "mdm-attributes": "MDM attributes",
+ "btn-add": "Add new",
+ "btn-edit": "Edit",
+ "btn-del": "Remove",
+ "btn-save": "Save",
+ "btn-cancel": "Cancel",
+ "btn-back": "Back",
+ "component-type": "Component type",
+ "component-name": "Component name",
+ "attribute-name": "Attribute name",
+ "dialog-ext-system-title": "External system",
+ "dialog-ext-system-attr-title": "External system attribute",
+ "dialog-ext-system-mdm-attr-title": "MDM attribute",
+ "dialog-ext-system-delete-title": "External system deletion",
+ "dialog-ext-system-delete-text": "Please confirm the deletion of the external system",
+ "err-cannot-update-ext-system": "External system cannot be saved",
+ "err-cannot-save-ext-system": "External system cannot be refreshed",
+ "err-cannot-save-ext-system-attr": "External system attribute cannot be saved",
+ "err-cannot-save-ext-mdm-attr": "MDM attribute cannot be saved",
+ "err-cannot-load-comp-types": "Cannot load component types",
+ "loading-attributes": "Loading attributes...",
+ "sensor": "Sensor",
+ "test-equipment": "Test equipment",
+ "test-sequence": "Test sequence",
+ "unit-under-test": "Unit under test"
+ }
},
"app": {
"about": "About",
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ExtSystemResource.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ExtSystemResource.java
new file mode 100644
index 0000000..a06a7c4
--- /dev/null
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ExtSystemResource.java
@@ -0,0 +1,359 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.businessobjects.boundary;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.vavr.collection.List;
+import io.vavr.control.Try;
+import org.eclipse.mdm.api.base.model.*;
+import org.eclipse.mdm.api.dflt.model.ExtSystem;
+import org.eclipse.mdm.api.dflt.model.ExtSystemAttribute;
+import org.eclipse.mdm.api.dflt.model.MDMAttribute;
+import org.eclipse.mdm.api.dflt.model.ValueList;
+import org.eclipse.mdm.businessobjects.control.FileLinkActivity;
+import org.eclipse.mdm.businessobjects.entity.*;
+import org.eclipse.mdm.businessobjects.service.ContextService;
+import org.eclipse.mdm.businessobjects.service.EntityService;
+import org.eclipse.mdm.businessobjects.utils.RequestBody;
+import org.eclipse.mdm.businessobjects.utils.ServiceUtils;
+
+import javax.ejb.EJB;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import static org.eclipse.mdm.businessobjects.boundary.ResourceConstants.REQUESTPARAM_ID;
+import static org.eclipse.mdm.businessobjects.boundary.ResourceConstants.REQUESTPARAM_SOURCENAME;
+import static org.eclipse.mdm.businessobjects.service.EntityService.V;
+
+/**
+ * {@link MDMEntity} REST interface for external systems
+ *
+ * @author Juergen Kleck, Peak Solution GmbH
+ *
+ */
+@Tag(name = "ExtSystem")
+@Path("/administration/{" + REQUESTPARAM_SOURCENAME + "}/externalsystems")
+public class ExtSystemResource {
+
+ @EJB
+ private ExtSystemService extSystemService;
+
+ @EJB
+ private EntityService entityService;
+
+ @EJB
+ private ContextService contextService;
+
+ @EJB
+ private FileLinkActivity fileLinkActivity;
+
+
+ /**
+ * delegates the request to the {@link ExtSystemService}
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param filter filter string to filter the ExtSystem result
+ * @return the result of the delegated request as {@link Response}
+ */
+ @GET
+ @Operation(summary = "Find ExtSystems by filter", description = "Get list of ExtSystems", responses = {
+ @ApiResponse(description = "The ExtSystems", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Error") })
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getExtSystems(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName) {
+
+ return Try.of(() -> extSystemService.getExtSystems(sourceName)).map(List::ofAll).map(e -> ServiceUtils.buildEntityResponse(e, Status.OK, ExtSystem.class))
+ .recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
+ .getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * delegates the request to the {@link ExtSystemService}
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param filter filter string to filter the ExtSystem result
+ * @return the result of the delegated request as {@link Response}
+ */
+ @GET
+ @Operation(summary = "Find ExtSystems by filter", description = "Get list of ExtSystems", responses = {
+ @ApiResponse(description = "The ExtSystems", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Error") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/attributes/{" + REQUESTPARAM_ID + "}")
+ public Response getExtSystemAttributes(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @Parameter(description = "ID of the ExtSystem", required = true) @PathParam(REQUESTPARAM_ID) String id) {
+
+ java.util.List all = new java.util.ArrayList<>();
+ java.util.List extSystems = extSystemService.getExtSystemAttributes(sourceName, id);
+ // the ext. system attributes
+ all.addAll(extSystems);
+ // the mdm attributes
+ extSystems.stream().forEach(e -> all.addAll(((ExtSystemAttribute) e).getAttributes()));
+
+ return ServiceUtils.buildEntityResponse(List.ofAll(all), Status.OK, ExtSystemAttribute.class);
+ }
+
+ /**
+ * delegates the request to the {@link ExtSystemService}
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param id id of the {@link MDMEntity}
+ * @return the result of the delegated request as {@link Response}
+ */
+ @GET
+ @Operation(summary = "Find a ExtSystem by ID", description = "Returns ExtSystem based on ID", responses = {
+ @ApiResponse(description = "The Project", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/{" + REQUESTPARAM_ID + "}")
+ public Response findExtSystem(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @Parameter(description = "ID of the ExtSystem", required = true) @PathParam(REQUESTPARAM_ID) String id) {
+ return entityService.find(V(sourceName), ExtSystem.class, V(id))
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
+ .getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Returns the created {@link MDMEntity}.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param body The {@link MDMEntity} to create.
+ * @return the created {@link MDMEntity} as {@link Response}.
+ */
+ @POST
+ @Operation(summary = "Create a new ExtSystem", responses = {
+ @ApiResponse(description = "The created ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "500", description = "Error") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response createExtSystem(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName, String body) {
+
+ return entityService
+ .create(V(sourceName), ExtSystem.class,
+ entityService.extractRequestBody(body, sourceName, List.of(ExtSystem.class)))
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.CREATED))
+ .recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Returns the created {@link MDMEntity}.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param body The {@link MDMEntity} to create.
+ * @return the created {@link MDMEntity} as {@link Response}.
+ */
+ @POST
+ @Operation(summary = "Create a new ExtSystem", responses = {
+ @ApiResponse(description = "The created ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "500", description = "Error") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Path("/attribute")
+ public Response createExtSystemAttribute(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName, String body) {
+
+ return entityService
+ .create(V(sourceName), ExtSystemAttribute.class,
+ entityService.extractRequestBody(body, sourceName, List.of(ExtSystem.class, ExtSystemAttribute.class)))
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.CREATED))
+ .recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Returns the created {@link MDMEntity}.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param body The {@link MDMEntity} to create.
+ * @return the created {@link MDMEntity} as {@link Response}.
+ */
+ @POST
+ @Operation(summary = "Create a new ExtSystem", responses = {
+ @ApiResponse(description = "The created ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "500", description = "Error") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Path("/mdmattribute")
+ public Response createMDMAttribute(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName, String body) {
+
+ return entityService
+ .create(V(sourceName), MDMAttribute.class,
+ entityService.extractRequestBody(body, sourceName, List.of(ExtSystemAttribute.class, MDMAttribute.class)))
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.CREATED))
+ .recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Updates the {@link MDMEntity} with all parameters set in the given JSON
+ * body of the request.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param id the identifier of the {@link MDMEntity} to update.
+ * @param body the body of the request containing the attributes to update
+ * @return the updated {@link MDMEntity}
+ */
+ @PUT
+ @Operation(summary = "Update an existing ExtSystem", description = "Updates the ExtSystem with all parameters set in the body of the request.", responses = {
+ @ApiResponse(description = "The updated ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Path("/{" + REQUESTPARAM_ID + "}")
+ public Response updateExtSystem(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @Parameter(description = "ID of the ExtSystem", required = true) @PathParam(REQUESTPARAM_ID) String id,
+ String body) {
+ RequestBody requestBody = RequestBody.create(body);
+
+ return entityService
+ .update(V(sourceName), entityService.find(V(sourceName), ExtSystem.class, V(id)),
+ requestBody.getValueMapSupplier())
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
+ .getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Updates the {@link MDMEntity} with all parameters set in the given JSON
+ * body of the request.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param id the identifier of the {@link MDMEntity} to update.
+ * @param body the body of the request containing the attributes to update
+ * @return the updated {@link MDMEntity}
+ */
+ @PUT
+ @Operation(summary = "Update an existing ExtSystem", description = "Updates the ExtSystem with all parameters set in the body of the request.", responses = {
+ @ApiResponse(description = "The updated ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Path("/attribute/{" + REQUESTPARAM_ID + "}")
+ public Response updateExtSystemAttribute(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @Parameter(description = "ID of the ExtSystem", required = true) @PathParam(REQUESTPARAM_ID) String id,
+ String body) {
+ RequestBody requestBody = RequestBody.create(body);
+
+ return entityService
+ .update(V(sourceName), entityService.find(V(sourceName), ExtSystemAttribute.class, V(id)),
+ requestBody.getValueMapSupplier())
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
+ .getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Updates the {@link MDMEntity} with all parameters set in the given JSON
+ * body of the request.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param id the identifier of the {@link MDMEntity} to update.
+ * @param body the body of the request containing the attributes to update
+ * @return the updated {@link MDMEntity}
+ */
+ @PUT
+ @Operation(summary = "Update an existing ExtSystem", description = "Updates the ExtSystem with all parameters set in the body of the request.", responses = {
+ @ApiResponse(description = "The updated ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Path("/mdmattribute/{" + REQUESTPARAM_ID + "}")
+ public Response updateMDMAttribute(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @Parameter(description = "ID of the ExtSystem", required = true) @PathParam(REQUESTPARAM_ID) String id,
+ String body) {
+ RequestBody requestBody = RequestBody.create(body);
+
+ return entityService
+ .update(V(sourceName), entityService.find(V(sourceName), MDMAttribute.class, V(id)),
+ requestBody.getValueMapSupplier())
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
+ .getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Deletes and returns the deleted {@link MDMEntity}.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param id The identifier of the {@link MDMEntity} to delete.
+ * @return the deleted {@link ValueList }s as {@link Response}
+ */
+ @DELETE
+ @Operation(summary = "Delete an existing ExtSystem", responses = {
+ @ApiResponse(description = "The deleted ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/{" + REQUESTPARAM_ID + "}")
+ public Response deleteExtSystem(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @Parameter(description = "ID of the ExtSystem", required = true) @PathParam(REQUESTPARAM_ID) String id) {
+ return entityService.delete(V(sourceName), entityService.find(V(sourceName), ExtSystem.class, V(id)))
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
+ .getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Deletes and returns the deleted {@link MDMEntity}.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param id The identifier of the {@link MDMEntity} to delete.
+ * @return the deleted {@link ValueList }s as {@link Response}
+ */
+ @DELETE
+ @Operation(summary = "Delete an existing ExtSystem", responses = {
+ @ApiResponse(description = "The deleted ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/attribute/{" + REQUESTPARAM_ID + "}")
+ public Response deleteExtSystemAttribute(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @Parameter(description = "ID of the ExtSystem", required = true) @PathParam(REQUESTPARAM_ID) String id) {
+ return entityService.delete(V(sourceName), entityService.find(V(sourceName), ExtSystemAttribute.class, V(id)))
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
+ .getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
+ * Deletes and returns the deleted {@link MDMEntity}.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param id The identifier of the {@link MDMEntity} to delete.
+ * @return the deleted {@link ValueList }s as {@link Response}
+ */
+ @DELETE
+ @Operation(summary = "Delete an existing ExtSystem", responses = {
+ @ApiResponse(description = "The deleted ExtSystem", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+ @ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/mdmattribute/{" + REQUESTPARAM_ID + "}")
+ public Response deleteMDMAttribute(
+ @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @Parameter(description = "ID of the ExtSystem", required = true) @PathParam(REQUESTPARAM_ID) String id) {
+ return entityService.delete(V(sourceName), entityService.find(V(sourceName), MDMAttribute.class, V(id)))
+ .map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
+ .getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+}
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ExtSystemService.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ExtSystemService.java
new file mode 100644
index 0000000..df6c50d
--- /dev/null
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ExtSystemService.java
@@ -0,0 +1,105 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.businessobjects.boundary;
+
+import org.eclipse.mdm.api.base.model.*;
+import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.dflt.EntityManager;
+import org.eclipse.mdm.api.dflt.model.ExtSystem;
+import org.eclipse.mdm.api.dflt.model.ExtSystemAttribute;
+import org.eclipse.mdm.businessobjects.control.*;
+import org.eclipse.mdm.connector.boundary.ConnectorService;
+
+import javax.ejb.Stateless;
+import javax.inject.Inject;
+import java.util.*;
+
+/**
+ * ExtSystemService Bean implementation with available
+ * operations
+ *
+ * @author Juergen Kleck, Peak Solution GmbH
+ *
+ */
+@Stateless
+public class ExtSystemService {
+
+ @Inject
+ private ConnectorService connectorService;
+
+ /**
+ * returns the matching {@link ExtSystem}s using the given filter or all
+ * {@link ExtSystem}s if no filter is available
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @return the found {@link ExtSystem}s
+ */
+ public List<ExtSystem> getExtSystems(String sourceName) {
+ List<ExtSystem> list = new ArrayList<>();
+ try {
+ Optional<List<ExtSystem>> values = this.connectorService.getContextByName(sourceName).getEntityManager()
+ .map(em -> em.loadAll(ExtSystem.class));
+
+ if(values.isPresent()) {
+ list = values.get();
+ }
+ } catch (DataAccessException e) {
+ throw new MDMEntityAccessException(e.getMessage(), e);
+ }
+ return list;
+ }
+
+ /**
+ * returns a {@link ExtSystem} identified by the given id.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param extSystemId id of the {@link ExtSystem}
+ * @return the matching {@link ExtSystem}
+ */
+ public ExtSystem getExtSystem(String sourceName, String extSystemId) {
+ try {
+ EntityManager em = this.connectorService.getContextByName(sourceName).getEntityManager()
+ .orElseThrow(() -> new MDMEntityAccessException("Entity manager not present!"));
+ return em.load(ExtSystem.class, extSystemId);
+ } catch (DataAccessException e) {
+ throw new MDMEntityAccessException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * returns the matching {@link ExtSystemAttribute}s using the given filter or all
+ * {@link ExtSystemAttribute}s if no filter is available
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param id the id of the external system
+ * @return the found {@link ExtSystemAttribute}s
+ */
+ public List<ExtSystemAttribute> getExtSystemAttributes(String sourceName, String id) {
+ List<ExtSystemAttribute> list = new ArrayList<>();
+ try {
+
+ Optional<List<ExtSystemAttribute>> values = this.connectorService.getContextByName(sourceName).getEntityManager()
+ .map(em -> em.loadChildren(em.load(ExtSystem.class, id), ExtSystemAttribute.class));
+
+ if(values.isPresent()) {
+ list = values.get();
+ }
+ } catch (DataAccessException e) {
+ throw new MDMEntityAccessException(e.getMessage(), e);
+ }
+ return list;
+ }
+
+}
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/TemplateComponentResource.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/TemplateComponentResource.java
index 9265f83..e0b95e1 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/TemplateComponentResource.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/TemplateComponentResource.java
@@ -38,6 +38,7 @@
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import io.vavr.control.Try;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Environment;
import org.eclipse.mdm.api.dflt.model.CatalogComponent;
@@ -51,6 +52,8 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import io.vavr.collection.List;
+import java.util.Collections;
+
/**
* {@link TemplateComponent} resource handling REST requests
*
@@ -111,6 +114,45 @@
}
/**
+ * Returns the (filtered) {@link TemplateComponent}s.
+ *
+ * @param sourceName name of the source (MDM {@link Environment} name)
+ * @param contextType {@link ContextType} of the {@link TemplateComponent} to
+ * load
+ * @param filter filter string to filter the {@link TemplateComponent}
+ * result
+ * @return the (filtered) {@link TemplateComponent}s as {@link Response}
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/rootList")
+ public Response findAllForAllRoots(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
+ @PathParam(REQUESTPARAM_CONTEXTTYPE) String contextTypeParam, @PathParam(REQUESTPARAM_ID) String tplRootIds,
+ @QueryParam("filter") String filter) {
+ java.util.List<TemplateComponent> components = new java.util.ArrayList<>();
+
+ String[] rootIds = tplRootIds.split(",");
+ for(String rootId : rootIds) {
+ entityService
+ .find(V(sourceName), TemplateRoot.class, V(rootId),
+ ServiceUtils.getContextTypeSupplier(contextTypeParam))
+ .map(e -> {
+ for(int j=0; j<e.getTemplateComponents().size(); j++) {
+ final TemplateComponent cmp = e.getTemplateComponents().get(j);
+ if(components.stream().noneMatch(tmp -> tmp.getName().equals(cmp.getName()))) {
+ components.add(cmp);
+ }
+ }
+ return true;
+ });
+ }
+ Collections.sort(components, (TemplateComponent tc1, TemplateComponent tc2) -> tc1.getName().compareTo(tc2.getName()));
+
+ return Try.of(() -> components).map(List::ofAll).map(e -> ServiceUtils.buildEntityResponse(e, Status.OK))
+ .recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
+ }
+
+ /**
* Returns the created {@link TemplateComponentValue}.
*
* @param body The {@link TemplateComponent} to create.
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/entity/MDMEntity.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/entity/MDMEntity.java
index 84ec915..1aaf322 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/entity/MDMEntity.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/entity/MDMEntity.java
@@ -261,6 +261,8 @@
Core core = ServiceUtils.getCore(entity);
// get children hash (type is key)
return HashMap.ofAll(core.getChildrenStore().getCurrent())
+ // if we don't check the size we crash, some elements may not have a relation
+ .filter(entry -> entry._2.size() > 0)
// create child relations (the ContextType is assumed to be same as the parent's
// one
.map(entry -> new MDMRelation(null, MDMRelation.RelationType.CHILDREN, entry._1.getSimpleName(),
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/utils/ServiceUtils.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/utils/ServiceUtils.java
index 9cb9fc2..013ddbc 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/utils/ServiceUtils.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/utils/ServiceUtils.java
@@ -40,12 +40,7 @@
import org.eclipse.mdm.api.base.query.FilterItem;
import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.EntityManager;
-import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
-import org.eclipse.mdm.api.dflt.model.CatalogComponent;
-import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
-import org.eclipse.mdm.api.dflt.model.TemplateComponent;
-import org.eclipse.mdm.api.dflt.model.TemplateRoot;
-import org.eclipse.mdm.api.dflt.model.ValueList;
+import org.eclipse.mdm.api.dflt.model.*;
import org.eclipse.mdm.businessobjects.control.FilterParser;
import org.eclipse.mdm.businessobjects.entity.I18NResponse;
import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse;
@@ -346,4 +341,5 @@
return (Core) getMetod.invoke(e);
}).get();
}
+
}