| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package util |
| |
| import ( |
| "golang.org/x/net/context" |
| "net/http" |
| "time" |
| ) |
| |
| type StringContext struct { |
| parentCtx context.Context |
| kv *ConcurrentMap |
| } |
| |
| func (c *StringContext) Deadline() (deadline time.Time, ok bool) { |
| return c.parentCtx.Deadline() |
| } |
| |
| func (c *StringContext) Done() <-chan struct{} { |
| return c.parentCtx.Done() |
| } |
| |
| func (c *StringContext) Err() error { |
| return c.parentCtx.Err() |
| } |
| |
| func (c *StringContext) Value(key interface{}) interface{} { |
| k, ok := key.(string) |
| if !ok { |
| return c.parentCtx.Value(key) |
| } |
| v, _ := c.kv.Get(k) |
| return v |
| } |
| |
| func (c *StringContext) SetKV(key string, val interface{}) { |
| c.kv.Put(key, val) |
| } |
| |
| func NewStringContext(ctx context.Context) *StringContext { |
| strCtx, ok := ctx.(*StringContext) |
| if !ok { |
| strCtx = &StringContext{ |
| parentCtx: ctx, |
| kv: NewConcurrentMap(10), |
| } |
| } |
| return strCtx |
| } |
| |
| func SetContext(ctx context.Context, key string, val interface{}) context.Context { |
| strCtx := NewStringContext(ctx) |
| strCtx.SetKV(key, val) |
| return strCtx |
| } |
| |
| func CloneContext(ctx context.Context) context.Context { |
| old, ok := ctx.(*StringContext) |
| if !ok { |
| return &StringContext{ |
| parentCtx: ctx, |
| kv: NewConcurrentMap(10), |
| } |
| } |
| |
| strCtx := &StringContext{ |
| parentCtx: ctx, |
| kv: NewConcurrentMap(old.kv.Size()), |
| } |
| |
| old.kv.ForEach(func(item MapItem) bool { |
| strCtx.kv.Put(item.Key, item.Value) |
| return true |
| }) |
| return strCtx |
| } |
| |
| func FromContext(ctx context.Context, key string) interface{} { |
| return ctx.Value(key) |
| } |
| |
| func SetRequestContext(r *http.Request, key string, val interface{}) *http.Request { |
| ctx := r.Context() |
| ctx = SetContext(ctx, key, val) |
| if ctx != r.Context() { |
| nr := r.WithContext(ctx) |
| *r = *nr |
| } |
| return r |
| } |
| |
| func ParseDomainProject(ctx context.Context) string { |
| return ParseDomain(ctx) + "/" + ParseProject(ctx) |
| } |
| |
| func ParseTargetDomainProject(ctx context.Context) string { |
| return ParseTargetDomain(ctx) + "/" + ParseTargetProject(ctx) |
| } |
| |
| func ParseDomain(ctx context.Context) string { |
| v, ok := FromContext(ctx, "domain").(string) |
| if !ok { |
| return "" |
| } |
| return v |
| } |
| |
| func ParseTargetDomain(ctx context.Context) string { |
| v, _ := FromContext(ctx, "target-domain").(string) |
| if len(v) == 0 { |
| return ParseDomain(ctx) |
| } |
| return v |
| } |
| |
| func ParseProject(ctx context.Context) string { |
| v, ok := FromContext(ctx, "project").(string) |
| if !ok { |
| return "" |
| } |
| return v |
| } |
| |
| func ParseTargetProject(ctx context.Context) string { |
| v, _ := FromContext(ctx, "target-project").(string) |
| if len(v) == 0 { |
| return ParseProject(ctx) |
| } |
| return v |
| } |
| |
| func SetDomain(ctx context.Context, domain string) context.Context { |
| return SetContext(ctx, "domain", domain) |
| } |
| |
| func SetProject(ctx context.Context, project string) context.Context { |
| return SetContext(ctx, "project", project) |
| } |
| |
| func SetTargetDomain(ctx context.Context, domain string) context.Context { |
| return SetContext(ctx, "target-domain", domain) |
| } |
| |
| func SetTargetProject(ctx context.Context, project string) context.Context { |
| return SetContext(ctx, "target-project", project) |
| } |
| |
| func SetDomainProject(ctx context.Context, domain string, project string) context.Context { |
| return SetProject(SetDomain(ctx, domain), project) |
| } |
| |
| func SetTargetDomainProject(ctx context.Context, domain string, project string) context.Context { |
| return SetTargetProject(SetTargetDomain(ctx, domain), project) |
| } |