github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgView/kmgViewResource/Generated.go (about)

     1  package kmgViewResource
     2  
     3  import (
     4  	"github.com/bronze1man/kmg/encoding/kmgJson"
     5  	"github.com/bronze1man/kmg/kmgCache"
     6  	"github.com/bronze1man/kmg/kmgConfig"
     7  	"github.com/bronze1man/kmg/kmgFile"
     8  	"github.com/bronze1man/kmg/kmgNet/kmgHttp"
     9  	"github.com/bronze1man/kmg/kmgXss"
    10  	"reflect"
    11  	"strings"
    12  	"sync"
    13  )
    14  
    15  type Generated struct {
    16  	Name                 string //拿去做缓存控制的.
    17  	GeneratedJsFileUrl   string
    18  	GeneratedCssFileUrl  string
    19  	GeneratedJsFileName  string
    20  	GeneratedCssFileName string
    21  	GeneratedUrlPrefix   string // 末尾不包含 /
    22  	RequestImportList    []string
    23  
    24  	locker     sync.Mutex
    25  	cachedInfo resourceBuildToDirResponse
    26  	initOnce   sync.Once
    27  }
    28  
    29  type htmlTplData struct {
    30  	urlPrefix  string
    31  	jsFileUrl  string
    32  	cssFileUrl string
    33  }
    34  
    35  func (g *Generated) HtmlRender() string {
    36  	data := g.GetHtmlTplData()
    37  	return `<script>
    38  		function getResourceUrlPrefix(){
    39  			return ` + kmgXss.Jsonv(data.urlPrefix) + `
    40  		}
    41  	</script>
    42  	<link rel="stylesheet" href="` + kmgXss.H(data.cssFileUrl) + `">
    43  	<script src="` + kmgXss.H(data.jsFileUrl) + `"></script>`
    44  }
    45  
    46  func (g *Generated) HeaderHtml() string {
    47  	data := g.GetHtmlTplData()
    48  	return `<script>
    49  		function getResourceUrlPrefix(){
    50  			return ` + kmgXss.Jsonv(data.urlPrefix) + `
    51  		}
    52  	</script>
    53  	<link rel="stylesheet" href="` + kmgXss.H(data.cssFileUrl) + `">`
    54  }
    55  
    56  func (g *Generated) FooterHtml() string {
    57  	data := g.GetHtmlTplData()
    58  	return `<script src="` + kmgXss.H(data.jsFileUrl) + `"></script>`
    59  }
    60  
    61  func (g *Generated) GetHtmlTplData() htmlTplData {
    62  	if kmgConfig.HasDefaultEnv() {
    63  		g.recheckAndReloadCache()
    64  		g.locker.Lock()
    65  		cachedInfo := g.cachedInfo
    66  		g.locker.Unlock()
    67  		urlPrefix := "/kmgViewResource." + g.Name
    68  		return htmlTplData{
    69  			urlPrefix:  urlPrefix,
    70  			jsFileUrl:  urlPrefix + "/" + cachedInfo.JsFileName,
    71  			cssFileUrl: urlPrefix + "/" + cachedInfo.CssFileName,
    72  		}
    73  	} else {
    74  		urlPrefix := "/kmgViewResource." + g.Name
    75  		return htmlTplData{
    76  			urlPrefix:  urlPrefix,
    77  			jsFileUrl:  urlPrefix + "/" + g.GeneratedJsFileName,
    78  			cssFileUrl: urlPrefix + "/" + g.GeneratedCssFileName,
    79  		}
    80  	}
    81  }
    82  
    83  // 返回url前缀,末尾不包含 '/'
    84  func (g *Generated) GetUrlPrefix() string {
    85  	if kmgConfig.HasDefaultEnv() {
    86  		g.recheckAndReloadCache()
    87  		return "/kmgViewResource." + g.Name
    88  	} else {
    89  		return "/kmgViewResource." + g.Name
    90  	}
    91  }
    92  
    93  func (g *Generated) GetJsUrl() string {
    94  	if kmgConfig.HasDefaultEnv() {
    95  		g.recheckAndReloadCache()
    96  		g.locker.Lock()
    97  		cachedInfo := g.cachedInfo
    98  		g.locker.Unlock()
    99  		return "/kmgViewResource." + g.Name + "/" + cachedInfo.JsFileName
   100  	} else {
   101  		return "/kmgViewResource." + g.Name + "/" + g.GeneratedJsFileName
   102  	}
   103  }
   104  func (g *Generated) GetCssUrl() string {
   105  	if kmgConfig.HasDefaultEnv() {
   106  		g.recheckAndReloadCache()
   107  		g.locker.Lock()
   108  		cachedInfo := g.cachedInfo
   109  		g.locker.Unlock()
   110  		return "/kmgViewResource." + g.Name + "/" + cachedInfo.CssFileName
   111  	} else {
   112  		return "/kmgViewResource." + g.Name + "/" + g.GeneratedCssFileName
   113  	}
   114  }
   115  
   116  // 这个初始化会在第一次使用的时候,自动进行,如果嫌自动初始化太慢,可以手动初始化.
   117  func (g *Generated) Init() {
   118  	g.initOnce.Do(func() {
   119  		if kmgConfig.HasDefaultEnv() {
   120  			g.recheckAndReloadCache()
   121  			kmgHttp.MustAddFileToHttpPathToDefaultServer("/kmgViewResource."+g.Name+"/",
   122  				kmgConfig.DefaultEnv().PathInProject("tmp/kmgViewResource_debug/"+g.Name))
   123  		} else {
   124  			// 默认使用反向代理方式提供数据.
   125  			kmgHttp.MustAddUriProxyRefToUriToDefaultServer("/kmgViewResource."+g.Name+"/", g.GeneratedUrlPrefix)
   126  		}
   127  	})
   128  }
   129  
   130  // 获取某个资源文件的内容
   131  func (g *Generated) GetContentByName(name string) (b []byte, err error) {
   132  	name = strings.TrimPrefix(name, "/")
   133  	if kmgConfig.HasDefaultEnv() {
   134  		g.recheckAndReloadCache()
   135  		path := kmgConfig.DefaultEnv().PathInProject("tmp/kmgViewResource_debug/" + g.Name + "/" + name)
   136  		return kmgFile.ReadFile(path)
   137  	} else {
   138  		// 默认使用反向代理方式提供数据.
   139  		return kmgHttp.UrlGetContent(g.GeneratedUrlPrefix + "/" + name)
   140  	}
   141  
   142  }
   143  
   144  func (g *Generated) recheckAndReloadCache() {
   145  	// 加载缓存文件,确定有哪些文件需要检查.
   146  	cachedInfo := &resourceBuildToDirResponse{}
   147  	err := kmgJson.ReadFile(kmgConfig.DefaultEnv().PathInProject("tmp/kmgViewResource_meta/"+g.Name), &cachedInfo)
   148  	if err != nil || cachedInfo.JsFileName == "" {
   149  		g.reloadCache()
   150  		return
   151  	}
   152  	// 第一次内存,没有数据时,需要从硬盘读入数据.
   153  	g.locker.Lock()
   154  	g.cachedInfo = *cachedInfo
   155  	g.locker.Unlock()
   156  	if !reflect.DeepEqual(cachedInfo.ImportPackageList, g.RequestImportList) {
   157  		g.reloadCache()
   158  		return
   159  	}
   160  	kmgCache.MustMd5FileChangeCache("kmgViewResource_"+g.Name, cachedInfo.NeedCachePathList, func() {
   161  		g.reloadCache()
   162  	})
   163  }
   164  
   165  func (g *Generated) reloadCache() {
   166  	debugBuildPath := kmgConfig.DefaultEnv().PathInProject("tmp/kmgViewResource_debug/" + g.Name)
   167  	kmgFile.MustDelete(debugBuildPath)
   168  	response := resourceBuildToDir(g.RequestImportList, debugBuildPath)
   169  	response.NeedCachePathList = append(response.NeedCachePathList, debugBuildPath)
   170  	kmgJson.MustWriteFileIndent(kmgConfig.DefaultEnv().PathInProject("tmp/kmgViewResource_meta/"+g.Name), response)
   171  	g.locker.Lock()
   172  	g.cachedInfo = response
   173  	g.locker.Unlock()
   174  	// 重新加载 NeedCachePathList 缓存.避免同一次变化多次更新缓存. TODO data race?
   175  	kmgCache.MustMd5FileChangeCache("kmgViewResource_"+g.Name, response.NeedCachePathList, func() {})
   176  
   177  }
   178  
   179  /*
   180  TODO 修复缓存无效原因1:
   181  	* 用户修改了资源文件的配置,现在资源文件需要访问的package和上一次缓存时需要访问的package不一致.
   182  */