All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reprezen.genflow.openapi.diagram.assets.script.diagram-specifics.js Maven / Gradle / Ivy

The newest version!
var DiagramSpecifics = {

        // Vertical gap between horizontal parts of URISegment links used to separate them from each other.
        // This goes (for every bound URISegment) into the vertical space
        // between resource label and the top of its contents
        URI_LINK_VGAP: 5,

        // Horizontal gap between vertical parts of URISegment used to separate them from each other.
        // This goes (for every bound URISegment) into the left-side padding of the resource
        URI_LINK_HGAP: 5,

        // FIXME: this is used to locate response ports which should be placed
        // FIXME: at the middle of the repsonse's part of the method
        // FIXME: Actually this code is called from many places, which is bad
        // FIXME: Instead: introduce implicit child ResponsePort
        // FIXME: compute its positions (using this metho inlined) once and then reuse the value
        collectChildrenVerticalMinMax: function (parent, childFilter) {
            var result = {
                "minTop": Number.POSITIVE_INFINITY,
                "maxBottom": Number.NEGATIVE_INFINITY,
                getMiddle: function () {
                    return (this.minTop + this.maxBottom) / 2;
                }
            };
            (parent.children || []).forEach(function (item, i, arr) {
                if (childFilter(item) && item.y && item.height) {
                    result.minTop = Math.min(result.minTop, item.y);
                    result.maxBottom = Math.max(result.maxBottom, item.y + item.height);
                }
            });
            return (result.minTop < result.maxBottom) ? result : null;
        },

        getURISegmentBindings: function (node) {
            function getFeaturesToBind(resource) {
                var result = [];
                if (resource.children) {
                    resource.children.forEach(function (child) {
                        if (child.objecttype == "DataType" || child.objecttype == "BaseType") {
                            if (child.children) {
                                child.children.forEach(function (deep) {
                                    if (deep.objecttype == "PrimitiveProperty") {
                                        result.push(deep);
                                    }
                                });
                            }
                        }
                    });
                }
                return result;
            }

            var bindings = [];
            var segments = (node.children || []).filter(function (d) {
                return d.objecttype == "URISegment";
            });
            if (segments.length > 0 && node.URI && node.URI.parameters && node.URI.parameters.length > 0) {
                /*const*/var featuresToMatch = getFeaturesToBind(node);
                node.URI.parameters.forEach(function (param) {
                    var matchedFeature = CoreUtils.findFirst(featuresToMatch, function (f) {
                        return f.id == param.propertyId;
                    });
                    var matchedSegment = CoreUtils.findFirst(segments, function (seg) {
                        return seg.id == param.uriFragment;
                    });
                    if (matchedFeature && matchedSegment) {
                        var nextBinding = {};
                        nextBinding.matchedFeature = matchedFeature;
                        nextBinding.matchedSegment = matchedSegment;
                        nextBinding.matchingParameter = param;
                        bindings.push(nextBinding);
                    }
                });
            }
            return bindings;
        },

        /**
         * get which string going to be shown on container
         * */
        getVisibleNodeString: function (node) {
            switch (node.objecttype) {
                case "URISegment":
                    return node.label || "";

                case "Response":
                    //Responses themselves are empty now, status & resource type labels are ad hoc children
                    return "";

                case "Request":
                    return node.name || node.resource_type || "";

                case "ResourceType":
                    return node.resource_type || "(empty response)";

                case "StatusCode":
                    //FIXME: check swagger default responses and responses without status code in general
                    return node.statusCode || "Status";

                case "Method":
                    return node.name + " (" + node.type + ")";

                case "ObjectResource":
                case "CollectionResource":
                case "DataType":
                case "ReferenceLink":
                case "HeaderParameter":
                case "QueryParameter":
                // break through, next 3 are separated as they are questionable, see below
                case "TemplateParameter":
                case "MatrixParameter":
                case "CollectionParameter":
                    //FIXME: last 3 parameters are questionable: I don't think that they can be shown at any diagram
                    //FIXME: leaving here just in case
                    return node.name || "";

                case "ReferenceEmbed":
                    // note: for ReferenceEmbed the name itself contains ':'
                    return node.name || "";

                case "PrimitiveProperty":
                case "ReferenceProperty":
                    return node.name + ":" + node.type;

                default:
                    if (!node.name) {
                        return "Empty";
                    }
                    return node.name + (node.type ? " (" + node.type + ") " : "");
            }
        },

        computeChildren: function (data, depth) {
            function cloneData(any) {
                var result = JSON.parse(JSON.stringify(any));
                return result;
            }

            function isArray(any) {
                return Object.prototype.toString.call(any) == '[object Array]';
            }

            var children;
            if (data.children) {
                return data.children;
            } else {
                if (!data._children) {
                    if (data.objecttype == "Response") {
                        //FIXME: revisit known false/true checks here and below, simplify structure
                        if (!children) {
                            children = [];
                        }

                        // This label is shown when resourceType or *neither type nor status*,
                        // in the latter case, show '(empty request)'
                        // FIXME: actually '(empty request)' is passed as data.name,
                        // FIXME: would be better to solve this at the data generator level
                        if (data.resource_type || !data.statusCode) {
                            //NOTE: data.resource_type may be null here
                            var implicitResourceType = {
                                "objecttype": "ResourceType",
                                "resource_type": data.resource_type
                            };
                            children.push(implicitResourceType);
                        }

                        if (data.statusCode) {
                            var implicitStatusCode = {
                                "objecttype": "StatusCode",
                                "statusCode": data.statusCode,
                                "statusCodeGroup": data.statusCodeGroup
                            };
                            children.push(implicitStatusCode);
                        }
                    }

                    if (data.baseType) {
                        if (!children) {
                            children = [];
                        }
                        children.push(data.baseType);
                    }

                    if (data.objecttype == "Method") {
                        if (!children) {
                            children = [];
                        }
                        if (data.request) {
                            children.push(cloneData(data.request));
                        }
                        if (data.responses) {
                            if (isArray(data.responses)) {
                                for (_responseIndex in data.responses) {
                                    children.push(cloneData(data.responses[_responseIndex]));
                                }
                            }
                        }
                    } else {
                        for (_dataIndex in data) {
                            if (isArray(data[_dataIndex])) {
                                if (children) {
                                    Array.prototype.push.apply(children, cloneData(data[_dataIndex]));
                                } else {
                                    children = cloneData(data[_dataIndex]);
                                }
                                break;
                            }
                        }
                    }

                    if (data.objecttype == "ObjectResource" || data.objecttype == "CollectionResource") {

                        if (data.dataType) {
                            var _dataTypeObject = cloneData(data.dataType);
                            if (children) {
                                var _dataType = children.filter(function (d) {
                                    return d.objecttype == "DataType";
                                });
                                if (_dataType.length == 0) {
                                    children.splice(0, 0, _dataTypeObject);
                                }
                            }
                        }

                        if (data.URI && data.URI.name) {
                            if (!children) {
                                children = [];
                            }
                            if (isArray(data.URI.name)) {
                                Array.prototype.push.apply(children, cloneData(data.URI.name));
                            }
                        }
                    }

//                            if(data.objecttype == "DataType"){
                    if (data.referenceTreatments) {
                        var _referenceLinks = cloneData(data.referenceTreatments).reverse();
                        if (children) {
                            var _referenceLinkList = children.filter(function (d) {
                                return d.objecttype == "ReferenceLink";
                            });
                            if (_referenceLinkList.length == 0) {
                                for (_referenceIndex in _referenceLinks) {
                                    children.splice(0, 0, _referenceLinks[_referenceIndex]);
                                }
                            }
                        }
                    }
//                            }
                }
            }

            if (children) {
                children.forEach(DiagramSpecifics.setupViewmap);
            }
            return children;
        },

        setupViewmap: function (datum) {
            /*const*/var imageHrefFun = DiagramSpecifics.getImageHrefFun(url_prefix);
            /*const*/var toStringFun = DiagramSpecifics.getVisibleNodeString;
            /*const*/var EXPANDER_GROUP_CLASS = "expander-group";

            //FIXME: move to _Conditions?
            function isPrimitiveOrReferenceProperty(d) {
                return d.objecttype == "PrimitiveProperty" || d.objecttype == "ReferenceProperty";
            }

            function isNotProperty(d) {
                return !isPrimitiveOrReferenceProperty(d);
            }

            function isURISegment(d) {
                return d.objecttype == "URISegment";
            }

            function isNotURISegment(d) {
                return !isURISegment(d);
            }

            switch (datum.objecttype) {
                case "QueryParameter":
                case "HeaderParameter":
                case "RequestParameter":
                case "ResourceType":
                case "StatusCode":
                    Viewmaps.newLabeledRowViewMap(datum)
                        .withIcon(12, 12, imageHrefFun)
                        .withText(toStringFun)
                        .asSemanticRoot();
                    break;

                case "Request":
                    // requests without parameters show the name,
                    // requests with parameters only show parameters
                    if (datum.parameters == null || datum.parameters.length == 0) {
                        Viewmaps.newLabeledRowViewMap(datum)
                            .withInsets(0, 0, 0, 0)
                            .withIcon(12, 12, imageHrefFun)
                            .withText(toStringFun)
                            .asSemanticRoot();
                    } else {
                        Viewmaps.newVBoxViewMap(datum)
                            .withInsets(5, 5, 5, 5)
                            .asSemanticRoot();
                    }
                    break;

                case "Response":
                    Viewmaps.newVBoxViewMap(datum)
                        .withInsets(5, 5, 5, 5)
                        .asSemanticRoot();
                    break;

                case "Method":
                    Viewmaps.newVBoxViewMap(datum)
                        .withInsets(0, 0, 5, 0)
                        .withChild(Viewmaps.newLabeledRowViewMap(datum)
                            .withEmptyBox(12, 16, EXPANDER_GROUP_CLASS)
                            .withIcon(12, 12, imageHrefFun)
                            .withText(toStringFun))
                        .withChildAsSharedContentPane(
                            Viewmaps.newVBoxViewMap(datum)
                                .withSpacing(10)
                                .withInsets(5, 10, 5, 10)
                        )
                        .asSemanticRoot();
                    break;

                case "PrimitiveProperty":
                case "ReferenceProperty":
                    Viewmaps.newLabeledRowViewMap(datum)
                        .withText(toStringFun)
                        .asSemanticRoot();
                    break;

                case "DataType":
                case "ReferenceEmbed":
                    //FIXME: old code did NOT had expanders for empty containers
                    Viewmaps.newVBoxViewMap(datum)
                        .withSpacing(5)
                        .withInsets(0, 0, 5, 5)
                        .withChild(Viewmaps.newLabeledRowViewMap(datum)
                            .withEmptyBox(12, 16, EXPANDER_GROUP_CLASS)
                            .withIcon(12, 12, imageHrefFun)
                            .withText(toStringFun))
                        .withChildAsContentPaneFor(isNotProperty,
                            Viewmaps.newVBoxViewMap(datum)
                                .withSpacing(10)
                                .withInsets(0, 10, 0, 5)
                        )
                        .withChildAsContentPaneFor(isPrimitiveOrReferenceProperty,
                            Viewmaps.newVBoxViewMap(datum)
                                .withInsets(0, 10, 0, 5)
                        )
                        .asSemanticRoot();
                    break;

                case "ReferenceLink":
                    //ReferenceLink's are like DadaType's but also may have LinkRelation label
                    //FIXME: old code did NOT had expanders for empty containers
                    Viewmaps.newVBoxViewMap(datum)
                        .withSpacing(5)
                        .withInsets(0, 0, 5, 5)
                        .withChild(Viewmaps.newHBoxViewMap(datum)
                            .withMinorAlignment(Draw2D.Alignment.TOP_LEFT)
                            .withChild(Viewmaps.newLabeledRowViewMap(datum)
                                .withEmptyBox(12, 16, EXPANDER_GROUP_CLASS)
                                .withIcon(12, 12, imageHrefFun)
                            )
                            .withChild(Viewmaps.newVBoxViewMap(datum)
                                .withChild(Viewmaps.newLabeledRowViewMap(datum)
                                    .withText(toStringFun)
                                )
                                .withChild(Viewmaps.newLabeledRowViewMap(datum)
                                    .withText(function (d) {
                                        var result = d.linkRelation;
                                        return result && result.length > 0 ? result : ""
                                    })
                                )
                            )
                        )
                        .withChildAsContentPaneFor(isNotProperty,
                            Viewmaps.newVBoxViewMap(datum)
                                .withSpacing(10)
                                .withInsets(0, 10, 0, 5)
                        )
                        .withChildAsContentPaneFor(isPrimitiveOrReferenceProperty,
                            Viewmaps.newVBoxViewMap(datum)
                                .withInsets(0, 10, 0, 5)
                        )
                        .asSemanticRoot();
                    break;

                case "ObjectResource":
                case "CollectionResource":
                    var segmentsContentPane;
                    var restContentPane;
                    var rightColumn = Viewmaps.newVBoxViewMap(datum)
                        .withInsets(0, 0, 10, 0)
                        .withChild(// top row: expander + icon + vertical place for name and composite uri label
                            Viewmaps.newHBoxViewMap(datum)
                                .withMinorAlignment(Draw2D.Alignment.TOP_LEFT)
                                .withSpacing(5)
                                .withChild(
                                    Viewmaps.newLabeledRowViewMap(datum)
                                        .withEmptyBox(12, 16, EXPANDER_GROUP_CLASS)
                                        .withIcon(12, 12, imageHrefFun)
                                )
                                .withChild( // vertical place for name and composite uri label
                                    Viewmaps.newVBoxViewMap(datum)
                                        .withText(toStringFun)
                                        .withChild(
                                            segmentsContentPane = Viewmaps.newHBoxViewMap(datum)
                                                //FIXME: the measuring code for some reason always add this margin
                                                //FIXME: so we are adjusting to this to have URI segments without gaps
                                                //FIXME: this should be removed in the measuring
                                                .withSpacing(-ViewmapUtils.ALL_LABELS_RIGHT_MARGIN)
                                        )
                                )
                        )
                        .withEmptyBox(0, function (datum) {
                            var urlLinks = DiagramSpecifics.getURISegmentBindings(datum);
                            return 5 + DiagramSpecifics.URI_LINK_HGAP * urlLinks.length;
                        })
                        .withChild(
                            restContentPane = Viewmaps.newVBoxViewMap(datum)
                                .withSpacing(10)
                                .withInsets(0, 10, 0, 10)
                        );

                    // first dynamic empty box to form a padding for vertical part of the URL links
                    // then the real content as a right column
                    Viewmaps.newHBoxViewMap(datum)
                        .withSpacing(0)
                        .withEmptyBox(
                            function (d) {
                                var urlLinks = DiagramSpecifics.getURISegmentBindings(datum);
                                return Math.max(0, DiagramSpecifics.URI_LINK_HGAP * (urlLinks.length - 1));
                            }, 0)
                        .withChild(rightColumn)
                        .withDeepContentPaneFor(isURISegment, segmentsContentPane)
                        .withDeepContentPaneFor(isNotURISegment, restContentPane)
                        .asSemanticRoot();
                    break;

                case "URISegment":
                    Viewmaps.newLabeledRowViewMap(datum)
                        .withText(toStringFun)
                        .asSemanticRoot();
                    break;

                default:
                    throw 'Unknown child found: ' + datum.objecttype;
            }
        },

        getImageHrefFun: function (url_prefix) {
            return function (datum) {
                return DiagramSpecifics._getImageHref(datum, url_prefix);
            };
        },

        _getImageHref: function (datum, url_prefix) {
            //FIXME: url_prefix looks innatural here, should be constructor parameter to some module
            //FIXME: partially addressed using getImageHrefFun
            var path = "images/default.png";
            switch (datum.objecttype) {
                case "ObjectResource":
                    path = "images/objectResource.png";
                    break;
                case "CollectionResource":
                    path = "images/collectionResource.png";
                    break;
                case "DataType":
                    path = "images/dataType.png";
                    break;
                case "ReferenceLink":
                    path = "images/referenceLink.png";
                    break;
                case "ReferenceEmbed":
                    path = "images/referenceEmbed.png";
                    break;
                case "Method":
                    path = "images/method.png";
                    break;
                case "Request":
                    path = "images/request.png";
                    break;
                case "QueryParameter":
                    path = "images/queryParameter.png";
                    break;
                case "HeaderParameter":
                    path = "images/headerParameter.png";
                    break;
                case "RequestParameter":
                    path = "images/requestParameter.png";
                    break;
                case "ResourceType":
                    path = "images/response.png";
                    break;
                case "StatusCode":
                    switch (datum.statusCodeGroup) {
                        case "Server Error":
                            path = "images/response_serverError.png";
                            break;
                        case "Client Error":
                            path = "images/response_clientError.png";
                            break;
                        case "Redirection" :
                            path = "images/response_redirection.png";
                            break;
                        case "Success":
                            path = "images/response_success.png";
                            break;
                        case "Informational" :
                            path = "images/response_informational.png";
                            break;
                        case "Default" :
                            path = "images/response_default.png";
                            break;
                        default:
                            path = "images/response.png";
                    }
                    break;
                default :
                    path = "images/default.png";
            }
            return url_prefix + path;
        },

        getContainerBackgroundClass: function (datum) {
            var classes = ["background"];
            switch (datum.objecttype) {
                case "ObjectResource":
                case "CollectionResource":
                    classes.push("resource");
                    break;
                case "DataType":
                    classes.push("dataType");
                    break;
                case "Method":
                    classes.push("method");
                    break;
                case "ReferenceLink":
                    classes.push("referenceLink");
                    break;
                case "Request":
                    classes.push("request");
                    break;
                case "Response":
                    classes.push("response");
                    break;
                case "ReferenceEmbed":
                    classes.push("referenceEmbed");
                    break;
                case "ResourceAPI":
                    //NO-OP
                    break;
                default:
                    classes.push("otherChild");
            }
            return classes.join(' ');
        }
};




© 2015 - 2025 Weber Informatics LLC | Privacy Policy