support set body parameter by json 93/10493/1
authorLvbo163 <lv.bo163@zte.com.cn>
Wed, 6 Sep 2017 06:32:16 +0000 (14:32 +0800)
committerLvbo163 <lv.bo163@zte.com.cn>
Wed, 6 Sep 2017 06:32:16 +0000 (14:32 +0800)
Rest task's body parameter is definited by json object in swagger definition.

Issue-ID: SDC-67

Change-Id: Idb1d96cf9d1135afd7b285105abfdd9a2c50380c
Signed-off-by: Lvbo163 <lv.bo163@zte.com.cn>
12 files changed:
sdc-workflow-designer-ui/src/app/app.module.ts
sdc-workflow-designer-ui/src/app/components/editable-property/editable-property.component.html [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/components/editable-property/editable-property.component.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.css [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.html [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/components/property/rest-task/rest-task-parameters/rest-task-parameters.component.html
sdc-workflow-designer-ui/src/app/components/property/rest-task/rest-task-parameters/rest-task-parameters.component.ts
sdc-workflow-designer-ui/src/app/components/property/rest-task/rest-task.component.html
sdc-workflow-designer-ui/src/app/services/swagger-tree-converter.service.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/services/workflow-config.service.ts
sdc-workflow-designer-ui/src/app/shared/shared.module.ts

index f257719..32af5d0 100644 (file)
@@ -38,17 +38,22 @@ import { ModalModule } from "ngx-bootstrap/modal";
 import { WorkflowConfigService } from "./services/workflow-config.service";
 import { RestTaskComponent } from "./components/property/rest-task/rest-task.component";
 import { RestTaskParametersComponent } from "./components/property/rest-task/rest-task-parameters/rest-task-parameters.component";
+import { ParameterTreeComponent } from "./components/parameter-tree/parameter-tree.component";
+import { EditablePropertyComponent } from "./components/editable-property/editable-property.component";
+import { SwaggerTreeConverterService } from "./services/swagger-tree-converter.service";
 
 @NgModule({
     declarations: [
         AppComponent,
         CanvasComponent,
+        EditablePropertyComponent,
         MenuComponent,
         MicroserviceComponent,
         MicroserviceDetailComponent,
         MicroserviceListComponent,
         NodeComponent,
         ParameterComponent,
+        ParameterTreeComponent,
         PropertiesComponent,
         RestTaskComponent,
         RestTaskParametersComponent,
@@ -68,6 +73,7 @@ import { RestTaskParametersComponent } from "./components/property/rest-task/res
         DataAccessService,
         HttpService,
         JsPlumbService,
+        SwaggerTreeConverterService,
         WorkflowConfigService,
         WorkflowService
     ],
diff --git a/sdc-workflow-designer-ui/src/app/components/editable-property/editable-property.component.html b/sdc-workflow-designer-ui/src/app/components/editable-property/editable-property.component.html
new file mode 100644 (file)
index 0000000..080a435
--- /dev/null
@@ -0,0 +1,25 @@
+<!--
+/**
+ * Copyright (c) 2017 ZTE Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ *     ZTE - initial API and implementation and/or initial documentation
+ */
+ -->
+<span *ngIf="!isEditing()">
+    <span (dblclick)="startEdit()">{{parameter.value}}</span>
+    <i class="fa fa-edit" (click)="startEdit()"></i>
+</span>
+<span class="row" *ngIf="isEditing()">
+    <span class="col-sm-10">
+        <b4t-parameter [param]="parameter" [showLabel]="showLabel" [valueSource]= "valueSource"></b4t-parameter>
+    </span>
+    <span class="col-sm-2">
+        <i class="fa fa-check" (click)="completeEdit()"></i>
+    </span>
+</span>
diff --git a/sdc-workflow-designer-ui/src/app/components/editable-property/editable-property.component.ts b/sdc-workflow-designer-ui/src/app/components/editable-property/editable-property.component.ts
new file mode 100644 (file)
index 0000000..577a8f1
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2017 ZTE Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ *     ZTE - initial API and implementation and/or initial documentation
+ */
+
+import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
+
+import { ValueSource } from '../../model/value-source.enum';
+import { ValueType } from '../../model/value-type.enum';
+import { Parameter} from '../../model/workflow/parameter';
+
+/**
+ * property component presents information of a workflow node.
+ * the presented information can be edit in this component.
+ * it may load information dynamically. the content may be different for different node type.
+ */
+@Component({
+    selector: 'b4t-editable-property',
+    templateUrl: 'editable-property.component.html',
+})
+export class EditablePropertyComponent {
+    @Input() public parameter: Parameter;
+    @Input() public showLabel: boolean;
+    @Input() public valueSource: ValueSource[];
+    @Output() public parameterChange = new EventEmitter<Parameter>();
+
+    private editing = false;
+
+    public isEditing(): boolean {
+        return this.editing;
+    }
+
+    public startEdit() {
+        this.editing = true;
+    }
+
+    public completeEdit() {
+        this.editing = false;
+        this.parameterChange.emit(this.parameter);
+    }
+}
diff --git a/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.css b/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.css
new file mode 100644 (file)
index 0000000..cda8b0c
--- /dev/null
@@ -0,0 +1,14 @@
+/**\r
+ * Copyright (c) 2017 ZTE Corporation.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * and the Apache License 2.0 which both accompany this distribution,\r
+ * and are available at http://www.eclipse.org/legal/epl-v10.html\r
+ * and http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Contributors:\r
+ *     ZTE - initial API and implementation and/or initial documentation\r
+ */\r
+.ui-treenode-label {\r
+    width: calc(100% - 32px) !important;\r
+}\r
diff --git a/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.html b/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.html
new file mode 100644 (file)
index 0000000..e97968d
--- /dev/null
@@ -0,0 +1,54 @@
+
+<!--
+/**
+ * Copyright (c) 2017 ZTE Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ *     ZTE - initial API and implementation and/or initial documentation
+ */
+ -->
+<p-tree *ngIf="parameters.length > 0" [value]="parameters">
+    <ng-template let-node  pTemplate="default">
+        <b4t-parameter [param]="node.parameter" [canEditName]="node.keyEditable" [valueSource]= "valueSource"
+            (paramChange)="paramChange($event, node)"></b4t-parameter>
+    </ng-template>
+
+    <ng-template let-node  pTemplate="array">
+        <span *ngIf="!node.keyEditable">[Array]({{node.children.length}}) {{node.label}}:</span>
+        <span *ngIf="node.keyEditable">[Array]({{node.children.length}})
+            <b4t-editable-property [parameter]="getKeyParameter(node)"  [showLabel]="false"
+                (parameterChange)="keyParameterChange(node, $event)"></b4t-editable-property>
+        </span>
+        <i class="fa fa-plus-square-o" (click)="addChildNode4ObjectArray(node)"></i>
+    </ng-template>
+    <ng-template let-node pTemplate="object">
+        <span *ngIf="!node.keyEditable">[Object] {{node.label}}:</span>
+        <span *ngIf="node.keyEditable">[Object]
+            <b4t-editable-property [parameter]="getKeyParameter(node)"  [showLabel]="false"
+                (parameterChange)="keyParameterChange(node, $event)"></b4t-editable-property>:
+        </span>
+
+        <span *ngIf="canEditValue(node)" class="dynamic-object-value">
+            <textarea [ngModel]="getObjectValue(node)" (ngModelChange)="updateObjectValue(node, $event)"></textarea>
+        </span>
+
+        <i *ngIf="canDelete(node)" class="fa fa-minus-square-o" (click)="deleteTreeNode(node)"></i>
+        <i *ngIf="canAdd(node)" class="fa fa-plus-square-o" (click)="addChildNode4DynamicObject(node)"></i>
+    </ng-template>
+
+    <ng-template let-node pTemplate="map">
+        <span *ngIf="!node.keyEditable">[Map] {{node.label}}:</span>
+        <span *ngIf="node.keyEditable">[Map]
+            <b4t-editable-property [parameter]="getKeyParameter(node)" [showLabel]="false"
+                (parameterChange)="keyParameterChange(node, $event)"></b4t-editable-property>:
+        </span>
+
+        <i *ngIf="canDelete(node)" class="fa fa-minus-square-o" (click)="deleteTreeNode(node)"></i>
+        <i *ngIf="canAdd(node)" class="fa fa-plus-square-o" (click)="addChildNode4DynamicObject(node)"></i>
+    </ng-template>
+</p-tree>
diff --git a/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.ts b/sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.ts
new file mode 100644 (file)
index 0000000..f5f098b
--- /dev/null
@@ -0,0 +1,230 @@
+/**
+ * Copyright (c) 2017 ZTE Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ *     ZTE - initial API and implementation and/or initial documentation
+ */
+
+import { Component, Input, OnChanges, Output, SimpleChange, SimpleChanges, ViewEncapsulation } from '@angular/core';
+import { TreeNode } from 'primeng/primeng';
+
+import { ValueSource } from '../../model/value-source.enum';
+import { ValueType } from '../../model/value-type.enum';
+import { Parameter } from '../../model/workflow/parameter';
+import { RestParameter } from '../../model/workflow/rest-parameter';
+import { RestTask } from '../../model/workflow/rest-task';
+import { SwaggerTreeConverterService } from '../../services/swagger-tree-converter.service';
+import { WorkflowUtil } from '../../util/workflow-util';
+
+/**
+ * parameter tree presents parameter of task node's input and output parameters.
+ */
+@Component({
+    selector: 'b4t-parameter-tree',
+    styleUrls: ['./parameter-tree.component.css'],
+    templateUrl: 'parameter-tree.component.html',
+    encapsulation: ViewEncapsulation.None
+})
+export class ParameterTreeComponent implements OnChanges {
+    @Input() public parameters: TreeNode[];
+    @Input() public task: RestTask;
+    @Input() public defaultValueSource: string;
+    @Input() public valueSource: ValueSource[];
+
+    constructor(private swaggerTreeConverterService: SwaggerTreeConverterService) { }
+
+    public ngOnChanges(changes: SimpleChanges) {
+        const changeParameters = changes["parameters"];
+        if (changeParameters && 0 < changeParameters.currentValue.length) {
+            this.formatParam(changeParameters.currentValue);
+        }
+    }
+
+    public getParam(node: any) {
+        if (undefined === node.parameter.name) {
+            node.parameter.name = node.label;
+            node.parameter.valueSource = this.defaultValueSource;
+        } else {
+            if (node.parent.parameter.value[node.label]) {
+                node.parameter.value = node.parent.parameter.value[node.label].value;
+                node.parameter.valueSource = node.parent.parameter.value[node.label].valueSource;
+            } else {
+                const tempParamValue: any = {};
+                tempParamValue.value = '';
+                tempParamValue.valueSource = this.defaultValueSource;
+                node.parent.parameter.value[node.label] = tempParamValue;
+                node.parameter.value = tempParamValue.value;
+                node.parameter.valueSource = tempParamValue.valueSource;
+            }
+        }
+        return node.parameter;
+    }
+
+    public paramChange(param: Parameter, node: any) {
+        if (node.label !== param.name) {
+            node.label = param.name;
+            this.propertyKeyChanged(node, param.value);
+        }
+        if (node.parent) {
+            if (node.parent.parameter.value[param.name]) {
+                node.parent.parameter.value[param.name].value = param.value;
+                node.parent.parameter.value[param.name].valueSource = param.valueSource;
+            } else {
+                node.parent.parameter.value[param.name] = {
+                    value: param.value,
+                    valueSource: param.valueSource
+                };
+            }
+        }
+    }
+
+    public getKeyParameter(node: any) {
+        return new Parameter('key', node.label, ValueSource[ValueSource.String], ValueType[ValueType.String]);
+    }
+
+    public keyParameterChange(node: any, parameter: Parameter) {
+        node.label = parameter.value;
+        this.propertyKeyChanged(node, parameter.value);
+    }
+
+    public getValueParameter(node: any, key: string) {
+        const nodeValue = node[key] ? node[key] : {
+            value: '',
+            valueSource: ValueSource[ValueSource.String],
+        };
+        node[key] = nodeValue;
+        return nodeValue;
+    }
+
+    public valueParameterChange(node: any, key: string, parameter: Parameter) {
+        node[key].value = parameter.value;
+        node[key].valueSource = parameter.valueSource;
+    }
+
+    public addChildNode4DynamicObject(node: any) {
+        const copyItem = WorkflowUtil.deepClone(node.parameter.additionalProperties);
+        const key = Object.keys(node.parameter.value).length;
+        const childrenNode = this.swaggerTreeConverterService
+            .schema2TreeNode(key, this.task.serviceName, this.task.serviceVersion, copyItem);
+
+        childrenNode.keyEditable = true;
+        node.parameter.value[key] = childrenNode.parameter.value;
+
+        node.children.push(childrenNode);
+    }
+
+    public propertyKeyChanged(node: any, newKey: string) {
+        const value = node.parent.parameter.value[node.label];
+        node.parent.parameter.value[newKey] = value;
+        delete node.parent.parameter.value[node.label];
+
+        node.label = newKey;
+    }
+
+    public addChildNode4ObjectArray(node: any) {
+        const copyItem = WorkflowUtil.deepClone(node.parameter.items);
+
+        const childrenNode = this.swaggerTreeConverterService
+            .schema2TreeNode(
+            node.children.length,
+            this.task.serviceName,
+            this.task.serviceVersion,
+            copyItem);
+
+        node.parameter.value.push(childrenNode.parameter.value);
+        node.children.push(childrenNode);
+        this.initParam(node);
+    }
+
+    public deleteTreeNode(node: any) {
+        // delete data
+        node.parent.parameter.value.splice(node.label, 1);
+        node.parent.children.splice(node.label, 1);
+
+        // update node index
+        node.parent.children.forEach((childNode, index) => childNode.label = index);
+    }
+
+    public canEditValue(node: any): boolean {
+        return node.children.length === 0;
+    }
+
+    public canDelete(node: any) {
+        const parent = node.parent;
+        if (parent &&
+            (this.isArrayObject(parent) || this.isDynamicObject(parent))) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public updateObjectValue(node: any, value: string) {
+        const newValueObj = JSON.parse(value);
+        for (const key in node.parameter.value) {
+            delete node.parameter.value[key];
+        }
+
+        for (const key in newValueObj) {
+            node.parameter.value[key] = newValueObj[key];
+        }
+    }
+
+    public getObjectValue(node) {
+        return JSON.stringify(node.parameter.value);
+    }
+
+    public canAdd(node: any) {
+        return this.isArrayObject(node) || this.isDynamicObject(node);
+    }
+
+    private formatParam(params: any[]): void {
+        console.log(params);
+        params.forEach(param => this.initParam(param));
+    }
+
+    private initParam(parameter: any, value?: any): void {
+        if (!parameter || 0 === parameter.length) {
+            return;
+        }
+        switch (parameter.type) {
+            case 'default':
+                parameter.parameter.name = parameter.label;
+                if (value && value[parameter.label]) {
+                    parameter.parameter.value = value[parameter.label].value;
+                    parameter.parameter.valueSource = value[parameter.label].valueSource;
+                } else {
+                    parameter.parameter.valueSource = this.defaultValueSource;
+                }
+                break;
+            case 'object':
+                for (let index = 0; index < parameter.children.length; index++) {
+                    let param = parameter.children[index];
+                    this.initParam(param, parameter.parameter.value);
+                }
+                break;
+            case 'array':
+                for (let index = 0; index < parameter.children.length; index++) {
+                    let param = parameter.children[index];
+                    this.initParam(param, parameter.parameter.value);
+                }
+                break;
+            default:
+                console.log('init a unsupport parameter, type is:' + parameter.type);
+                break;
+        }
+    }
+
+    private isArrayObject(node: any): boolean {
+        return node.type === 'array';
+    }
+
+    private isDynamicObject(node: any): boolean {
+        return node.type === 'map';
+    }
+}
index 4f98e68..53f02f1 100644 (file)
@@ -12,3 +12,7 @@
  *******************************************************************************/
 -->
 <b4t-parameter *ngFor="let param of requestParameters" [param]="param" [valueSource]= "inputSources"></b4t-parameter>
+
+<!-- body parameter -->
+<b4t-parameter-tree [task]="task" [parameters]="bodyParameter" [valueSource]="inputSources"
+    [defaultValueSource]="valueSource[valueSource.String]"></b4t-parameter-tree>
index f2d802c..a50cc1b 100644 (file)
@@ -18,6 +18,7 @@ import { RestTask } from '../../../../model/workflow/rest-task';
 import { BroadcastService } from '../../../../services/broadcast.service';
 import { RestParameter } from "../../../../model/workflow/rest-parameter";
 import { ValueSource } from "../../../../model/value-source.enum";
+import { SwaggerTreeConverterService } from "../../../../services/swagger-tree-converter.service";
 
 /**
  * property component presents information of a workflow node.
@@ -39,7 +40,7 @@ export class RestTaskParametersComponent implements OnInit {
 
     private index = 1;
 
-    constructor(private broadcastService: BroadcastService) {
+    constructor(private broadcastService: BroadcastService, private swaggerTreeConverterService: SwaggerTreeConverterService) {
     }
 
     public ngOnInit() {
@@ -55,8 +56,10 @@ export class RestTaskParametersComponent implements OnInit {
 
         this.task.parameters.forEach(param => {
             if (param.position === 'body') {
-                // TODO add body parameter handler
-                // this.bodyParameter.push(param);
+                const requestTreeNode = this.swaggerTreeConverterService
+                .schema2TreeNode('Request Param', this.task.serviceName, this.task.serviceVersion, param.schema);
+                param.value = param.schema.value;
+                this.bodyParameter.push(requestTreeNode);
             } else {
                 this.requestParameters.push(param);
             }
index a416944..af42884 100644 (file)
@@ -43,4 +43,6 @@
 </div>
 <hr>
 
-<b4t-rest-task-parameters [task]="node"></b4t-rest-task-parameters>
+<div class="ui-fluid">
+    <b4t-rest-task-parameters [task]="node"></b4t-rest-task-parameters>
+</div>
diff --git a/sdc-workflow-designer-ui/src/app/services/swagger-tree-converter.service.ts b/sdc-workflow-designer-ui/src/app/services/swagger-tree-converter.service.ts
new file mode 100644 (file)
index 0000000..a83ae2e
--- /dev/null
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2017 ZTE Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ *     ZTE - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+import { Injectable } from '@angular/core';
+import { TreeNode } from 'primeng/primeng';
+
+import { ValueSource } from '../model/value-source.enum';
+import { WorkflowUtil } from '../util/workflow-util';
+import { WorkflowConfigService } from "./workflow-config.service";
+
+@Injectable()
+export class SwaggerTreeConverterService {
+    private serviceName: string;
+    private serviceVersion: string;
+
+    constructor(private configService: WorkflowConfigService) {
+
+    }
+
+    public schema2TreeNode(key: string | number, serviceName: string, serviceVersion: string, schema: any): any {
+        this.serviceName = serviceName;
+        this.serviceVersion = serviceVersion;
+
+        if (schema.$ref) {
+            const treeNode = this.getTreeNodeBySwaggerDefinition(key, schema);
+            return treeNode;
+        } else {
+            this.setInitValue4Param(schema.value, schema);
+            return this.parameter2TreeNode(key, schema);
+        }
+    }
+
+    private getTreeNodeBySwaggerDefinition(key: string | number, schema: any): TreeNode {
+        const swagger = this.configService.getSwaggerInfo(this.serviceName, this.serviceVersion);
+        if(swagger === undefined) {
+            console.log(`swagger definition not exist, [${this.serviceName}].[${this.serviceVersion}]`);
+            return null;
+        }
+        const swaggerDefinition = this.configService.getDefinition(swagger, schema.$ref);
+
+        const definitionCopy = WorkflowUtil.deepClone(swaggerDefinition);
+
+        this.setInitValue4Param(schema.value, definitionCopy);
+        if (schema.value !== definitionCopy.value) {
+            schema.value = definitionCopy.value;
+        }
+
+        return this.schema2TreeNode(key, this.serviceName, this.serviceVersion, definitionCopy);
+    }
+
+    private setInitValue4Param(value: any | any[], param: any) {
+        param.value = value;
+        if (value == null) {
+            if (param.type === 'object') {
+                param.value = {};
+            } else if (param.type === 'array') {
+                param.value = [];
+            } else { // primary type
+                param.valueSource = ValueSource[ValueSource.String];
+            }
+        }
+    }
+
+    private parameter2TreeNode(name: string | number, paramDefinition: any): any {
+        const nodeType = this.getTreeNodeType(paramDefinition);
+
+        const node = {
+            label: name,
+            type: nodeType,
+            children: [],
+            parameter: paramDefinition,
+        };
+
+        if (paramDefinition.type === 'object') {
+            node.children = this.getPropertyFromObject(paramDefinition.value, paramDefinition);
+        } else if (paramDefinition.type === 'array') {
+            this.setChildrenForArray(node, paramDefinition);
+        }
+
+        return node;
+    }
+
+    private getTreeNodeType(param: any): string {
+        const type = param.type;
+        if (type === 'array') {
+            return 'array';
+        } else if (type === 'object') {
+            if (param.additionalProperties) {
+                return 'map';
+            } else {
+                return 'object';
+            }
+        } else {
+            return 'default';
+        }
+    }
+
+    private setChildrenForArray(node: any, param: any) {
+        param.value.forEach((itemValue, index) => {
+            const itemCopy = WorkflowUtil.deepClone(param.items);
+            itemCopy.value = itemValue;
+            node.children.push(this.schema2TreeNode(index, this.serviceName, this.serviceVersion, itemCopy));
+        });
+    }
+
+    private getPropertyFromObject(objectValue: any, param: any): TreeNode[] {
+        if (param.properties) {
+            return this.getPropertyFromSimpleObject(objectValue, param.properties);
+        } else if (param.additionalProperties) {
+            return this.getPropertyFromMapOrDictionary(objectValue, param.additionalProperties);
+        } else {
+            return [];
+        }
+
+    }
+
+    private getPropertyFromSimpleObject(objectValue: any, properties: any): TreeNode[] {
+        const treeNodes: TreeNode[] = [];
+        for (const key in properties) {
+            const property = properties[key];
+            this.setInitValue4Param(objectValue[key], property);
+
+            if (property.value !== objectValue[key]) {
+                objectValue[key] = property.value;
+            }
+
+            treeNodes.push(this.schema2TreeNode(key, this.serviceName, this.serviceVersion, property));
+        }
+        return treeNodes;
+    }
+
+    private getPropertyFromMapOrDictionary(mapOrDictionary: any, additionalProperties: any): TreeNode[] {
+        const treeNodes: TreeNode[] = [];
+        for (const key in mapOrDictionary) {
+            const propertyCopy = WorkflowUtil.deepClone(additionalProperties);
+            propertyCopy.value = mapOrDictionary[key];
+
+            const treeNode = this.schema2TreeNode(key, this.serviceName, this.serviceVersion, propertyCopy);
+            treeNode.keyEditable = true;
+            treeNodes.push(treeNode);
+
+            if (mapOrDictionary[key] !== propertyCopy.value) {
+                mapOrDictionary[key] = propertyCopy.value;
+            }
+        }
+        return treeNodes;
+    }
+}
index 469fde9..38d9fb5 100644 (file)
@@ -15,7 +15,7 @@ import { WorkflowService } from "./workflow.service";
 import { Microservice } from "../model/workflow/microservice";\r
 import { Observable } from "rxjs/Rx";\r
 import { HttpService } from "../util/http.service";\r
-import { Swagger } from "../model/swagger";\r
+import { Swagger, SwaggerSchemaObject } from "../model/swagger";\r
 \r
 /**\r
  * WorkflowConfigService\r
@@ -46,4 +46,11 @@ export class WorkflowConfigService {
             return undefined;\r
         }\r
     }\r
+\r
+    public getDefinition(swagger: Swagger, position: string): SwaggerSchemaObject {\r
+        const definitionName = position.substring('#/definitions/'.length);\r
+\r
+        return swagger.definitions[definitionName];\r
+    }\r
+\r
 }\r
index 1591a13..faa4d7d 100644 (file)
@@ -13,7 +13,7 @@ import { CommonModule } from '@angular/common';
 import { NgModule } from '@angular/core';
 import { FormsModule } from '@angular/forms';
 import { HttpModule } from '@angular/http';
-import { RadioButtonModule } from 'primeng/primeng';
+import { RadioButtonModule, TreeModule } from 'primeng/primeng';
 import { RouterModule } from '@angular/router';
 
 const module = [
@@ -21,6 +21,7 @@ const module = [
     FormsModule,
     RadioButtonModule,
     RouterModule,
+    TreeModule,
 ];
 
 @NgModule({