| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- // package use_link -- связь между объектами
- package use_link
- import (
- "fmt"
- "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
- "gitp78su.ipnodns.ru/svi/goarch/lev0/cons"
- "gitp78su.ipnodns.ru/svi/goarch/lev0/types"
- "gitp78su.ipnodns.ru/svi/goarch/pkg/elems/coord"
- "gitp78su.ipnodns.ru/svi/goarch/pkg/elems/elem_base"
- )
- // UseLink -- связь между объектами
- type UseLink struct {
- *elem_base.ElemBase
- CoordEnd_ *coord.Coord `json:"coord1"` // Координаты второй точки
- Src_ alias.Id `json:"src"` // Источник координат
- Dst_ alias.Id `json:"dst"` // Получатель координат
- TypeLink_ string `json:"typeLink"` // Тип связи
- }
- // NewUseLink -- возвращает новую связь
- func NewUseLink(elem map[string]interface{}) (*UseLink, error) {
- elemBase, err := elem_base.NewElemBase(elem)
- if err != nil {
- return nil, fmt.Errorf("NewUseLink(): in create BaseSvg, err=\n\t%w", err)
- }
- id := elemBase.Id_
- _src := elemBase.Elem_["src"]
- src0, isOk := _src.(string)
- if !isOk {
- return nil, fmt.Errorf("NewUseLink(): id=%q, field `src` not string, type=%T, value=%v", id, _src, elemBase.StrElem_)
- }
- src := alias.Id(src0)
- if src == "" {
- return nil, fmt.Errorf("NewUseLink(): id=%q, `src` is empty", id)
- }
- _dst := elemBase.Elem_["dst"]
- dst0, isOk := _dst.(string)
- if !isOk {
- return nil, fmt.Errorf("NewUseLink(): id=%q, field `dst` not string, type=%T, value=%+v<br>%+v", id, _dst, _dst, elemBase.StrElem_)
- }
- dst := alias.Id(dst0)
- _typeLink, isOk := elemBase.Elem_["type_link"]
- if !isOk {
- return nil, fmt.Errorf("NewUseLink(): name=%q, field `type_link` not found<br>%+v", id, elemBase.StrElem_)
- }
- typeLink, isOk := _typeLink.(string)
- if !isOk {
- return nil, fmt.Errorf("NewUseLink(): name=%q, `type_link`(%+v) not string", id, _typeLink)
- }
- if typeLink == "" {
- return nil, fmt.Errorf("NewUseLink(): name=%q, type_link=%q is empty", id, typeLink)
- }
- sf := &UseLink{
- ElemBase: elemBase,
- CoordEnd_: coord.NewCoord("coord1", elem),
- Src_: src,
- Dst_: dst,
- TypeLink_: typeLink,
- }
- return sf, nil
- }
- // Links -- ссылки актора
- func (sf *UseLink) Links() []alias.Id {
- return []alias.Id{sf.Src_, sf.Dst_}
- }
- // Check -- проверяет связи между объектами
- func (sf *UseLink) Check(mapDrawer map[alias.Id]types.IElemDrawer) string {
- if sf.Dst_ == sf.Src_ {
- return fmt.Sprintf("ВНИМАНИЕ! Источник и получатель совпадают\nsrc=%v, dst=%v\n", sf.Src_, sf.Dst_)
- }
- if msgErr := sf.checkSrc(mapDrawer); msgErr != "" {
- return "ОШИБКА при проверке связи источника\n" + msgErr
- }
- if msgErr := sf.checkDst(mapDrawer); msgErr != "" {
- return "ОШИБКА при проверке связи получателя\n" + msgErr
- }
- if sf.TypeLink_ == "" { // Проверка на правильность типа связи
- return "Пустой собственный тип связи\n"
- }
- return ""
- }
- // проверить связь получателя
- func (sf *UseLink) checkDst(mapDrawer map[alias.Id]types.IElemDrawer) string {
- if sf.Dst_ == "" {
- return "ОШИБКА получатель `dst` не задан"
- }
- dst, isOk := mapDrawer[sf.Dst_] // Вычислить, если такой получатель
- if !isOk {
- return "Отсутствует собственный получатель(dst)\n"
- }
- // Вычислить на допустимые типы для получателя
- switch dst.Type() {
- case cons.TypeUseActor:
- actor, isOk := dst.(types.IActor)
- if !isOk {
- return fmt.Sprintf("Недопустимый тип получателя(%q)\nтип=%q\n", dst.Id(), dst.Type())
- }
- isOk = false
- for _, id := range actor.Links() {
- if id == sf.Id_ {
- isOk = true
- break
- }
- }
- if !isOk {
- return fmt.Sprintf("Невзаимная ссылка\nid=%q,dst=(%q)", sf.Id_, actor.Id())
- }
- case cons.TypeUseLink:
- link, isOk := dst.(types.ILinker)
- if !isOk {
- return fmt.Sprintf("Недопустимый тип получателя(%q)\nтип=%q\n", dst.Id(), dst.Type())
- }
- isOk = sf.Id_ == link.DstId() || sf.Id_ == link.SrcId()
- if !isOk {
- return fmt.Sprintf("id=%q, Невзаимная ссылка(%q)\n", sf.Id_, link.Id())
- }
- case cons.TypeUseCase:
- useCase, isOk := dst.(types.IUseCase)
- if !isOk {
- return fmt.Sprintf("id=%q, Недопустимый тип получателя(%q)\nтип=%q\n", sf.Id_, dst.Id(), dst.Type())
- }
- isOk = false
- for _, id := range useCase.Links() {
- if id == sf.Id_ {
- isOk = true
- break
- }
- }
- if !isOk {
- return fmt.Sprintf("id=%q, Невзаимная ссылка(%q)\n", sf.Id_, useCase.Id())
- }
- default: // Недопустимый источник
- return fmt.Sprintf("id=%q, Недопустимый тип получателя(%q)\nid=%q\n", sf.Id_, dst.Type(), dst.Id())
- }
- return ""
- }
- // Проверяет связь источника
- func (sf *UseLink) checkSrc(mapDrawer map[alias.Id]types.IElemDrawer) string {
- if sf.Src_ == "" {
- return "ВНИМАНИЕ! Источник связи не задан(src)\n"
- }
- src, isOk := mapDrawer[sf.Src_]
- if !isOk {
- return "Отсутствует источник(src)\n"
- }
- switch src.Type() {
- case cons.TypeUseActor:
- isOk = false
- actor := types.IActor(src)
- for _, id := range actor.Links() { // Проверка на взаимность
- if id == sf.Id_ {
- isOk = true
- break
- }
- }
- if !isOk {
- return fmt.Sprintf("Невзаимная ссылка с актором %q\n", actor.Id())
- }
- case cons.TypeUseLink:
- link, isOk := src.(types.ILinker)
- if !isOk {
- return fmt.Sprintf("Несоответствие типа источника(%q)\nтип='useLink'\n", src.Id())
- }
- isOk = sf.Id_ == link.DstId() || sf.Id_ == link.SrcId()
- if !isOk {
- return fmt.Sprintf("id=%q, Невзаимная ссылка(%q)\n", sf.Id_, link.Id())
- }
- case cons.TypeUseCase:
- useCase, isOk := src.(types.IUseCase)
- if !isOk {
- return fmt.Sprintf("id=%q, Тип источника(%q) не совпадает с фактическим\nтип='useCase'\n", sf.Id_, src.Id())
- }
- isOk = false
- for _, id := range useCase.Links() { // Проверка на взаимность
- if id == sf.Id_ {
- isOk = true
- break
- }
- }
- if !isOk {
- return fmt.Sprintf("id=%q, Невзаимная ссылка(%q)\n", sf.Id_, useCase.Id())
- }
- default: // Неизвестный источник
- return fmt.Sprintf("id=%q, неизвестный тип источника(%q)<br>id=%q\n", sf.Id_, src.Type(), src.Id())
- }
- return ""
- }
- // SrcId -- возвращает источник связи
- func (sf *UseLink) SrcId() alias.Id {
- return sf.Src_
- }
- // DstId -- возвращает получателя связи
- func (sf *UseLink) DstId() alias.Id {
- return sf.Dst_
- }
|