github.com/amp-space/amp-sdk-go@v0.7.6/amp/registry.go (about)

     1  package amp
     2  
     3  import (
     4  	"strings"
     5  	"sync"
     6  )
     7  
     8  func newRegistry() Registry {
     9  	return &registry{
    10  		appsByUID:    make(map[UID]*App),
    11  		appsByInvoke: make(map[string]*App),
    12  	}
    13  }
    14  
    15  // Implements amp.Registry
    16  type registry struct {
    17  	mu           sync.RWMutex
    18  	appsByUID    map[UID]*App
    19  	appsByInvoke map[string]*App
    20  	elemTypes    []ElemVal
    21  }
    22  
    23  func (reg *registry) RegisterElemType(prototype ElemVal) {
    24  	reg.mu.Lock()
    25  	defer reg.mu.Unlock()
    26  	reg.elemTypes = append(reg.elemTypes, prototype)
    27  }
    28  
    29  func (reg *registry) ExportTo(dst SessionRegistry) error {
    30  	reg.mu.Lock()
    31  	defer reg.mu.Unlock()
    32  	for _, elemType := range reg.elemTypes {
    33  		if err := dst.RegisterElemType(elemType); err != nil {
    34  			return err
    35  		}
    36  	}
    37  	return nil
    38  }
    39  
    40  // Implements amp.Registry
    41  func (reg *registry) RegisterApp(app *App) error {
    42  	reg.mu.Lock()
    43  	defer reg.mu.Unlock()
    44  
    45  	if strings.ContainsRune(app.AppID, '/') ||
    46  		strings.ContainsRune(app.AppID, ' ') ||
    47  		strings.Count(app.AppID, ".") < 2 {
    48  
    49  		// Reject if URI does not conform to standards for App.AppURI
    50  		return ErrCode_BadSchema.Errorf("illegal app ID: %q", app.AppID)
    51  	}
    52  
    53  	reg.appsByUID[app.UID] = app
    54  
    55  	for _, invok := range app.Invocations {
    56  		if invok != "" {
    57  			reg.appsByInvoke[invok] = app
    58  		}
    59  	}
    60  
    61  	// invoke by full app ID
    62  	reg.appsByInvoke[app.AppID] = app
    63  
    64  	// invoke by first component of app ID
    65  	appPos := strings.Index(app.AppID, ".")
    66  	appName := app.AppID[0:appPos]
    67  	reg.appsByInvoke[appName] = app
    68  
    69  	return nil
    70  }
    71  
    72  // Implements amp.Registry
    73  func (reg *registry) GetAppByUID(appUID UID) (*App, error) {
    74  	reg.mu.RLock()
    75  	defer reg.mu.RUnlock()
    76  
    77  	app := reg.appsByUID[appUID]
    78  	if app == nil {
    79  		return nil, ErrCode_AppNotFound.Errorf("app not found: %s", appUID)
    80  	} else {
    81  		return app, nil
    82  	}
    83  }
    84  
    85  // Implements amp.Registry
    86  func (reg *registry) GetAppForInvocation(invocation string) (*App, error) {
    87  	if invocation == "" {
    88  		return nil, ErrCode_AppNotFound.Errorf("missing app invocation")
    89  	}
    90  
    91  	reg.mu.RLock()
    92  	defer reg.mu.RUnlock()
    93  
    94  	app := reg.appsByInvoke[invocation]
    95  	if app == nil {
    96  		return nil, ErrCode_AppNotFound.Errorf("app not found for invocation %q", invocation)
    97  	}
    98  	return app, nil
    99  }