func literalsHandler(w http.ResponseWriter, r *http.Request) { uri := r.FormValue("uri") q, _ := qBank.Prepare("literals", struct{ URI string }{uri}) resp, err := repo.Query(conf.QuadStore.Endpoint, q, "json") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } res, err := sparql.ParseJSON(resp) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer resp.Close() if len(res.Results.Bindings) == 0 { w.Write([]byte("No literals on resource")) return } var b bytes.Buffer b.WriteString("<table class='preview'>") for _, s := range res.Solutions() { b.WriteString("<tr><td>" + prefixify(&conf.Vocab.Dict, s["p"].Serialize(rdf.Turtle)) + "</td><td>") b.WriteString(s["o"].Serialize(rdf.Turtle) + "</td></tr>") } b.WriteString("</table>") w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Write(b.Bytes()) }
// mainHandler serves the resource HTML presentation, or dispatches to the // rdfHandler or jsonHandler func (m mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { // redirect from root to info page http.Redirect(w, r, conf.UI.RootRedirectTo, http.StatusFound) return } var uri string resolved := false suffix := suffixRg.FindString(r.URL.Path) switch suffix { case "": break case ".html": uri = conf.BaseURI + strings.TrimSuffix(r.URL.Path, ".html") resolved = true case ".json": jsonHandler(w, r) return case ".rdf": rdfHandler(w, r) return default: errorHandler(w, r, fmt.Sprintf("Unsupported output format: %s.\n\n"+ "Valid formats are: html, json, rdf", suffix[1:]), http.StatusBadRequest) return } // The URI should be an exclusive identifier of the resource; so we redirect // to URI+.html if !resolved { http.Redirect(w, r, r.URL.Path+".html", http.StatusFound) return } q, _ := qBank.Prepare("select", struct { URI string Limit int }{uri, conf.QuadStore.ResultsLimit}) resp, err := repo.Query(conf.QuadStore.Endpoint, q, "json") if err != nil { //println(err.Error()) errorHandler(w, r, err.Error()+". Refresh to try again.\n\nYou can increase the timeout"+ " values in Fensters configuration file.", http.StatusInternalServerError) return } defer resp.Close() res, err := sparql.ParseJSON(resp) if err != nil { errorHandler(w, r, "Failed to parse JSON response from remote SPARQL endpoint.", http.StatusInternalServerError) return } if len(res.Results.Bindings) == 0 { errorHandler(w, r, "This URI has no information", http.StatusNotFound) return } var maxS, maxO int if len(res.Results.Bindings) >= conf.QuadStore.ResultsLimit { // Fetch solution counts, if we hit the results limit q, _ := qBank.Prepare("count", struct{ URI string }{uri}) resp, err := repo.Query(conf.QuadStore.Endpoint, q, "json") if err == nil { res, err := sparql.ParseJSON(resp) if err == nil { b := res.Bindings() v, _ := b["maxS"][0].(rdf.Literal).Typed() maxS = v.(int) v, _ = b["maxO"][0].(rdf.Literal).Typed() maxO = v.(int) } resp.Close() } } solutions := res.Solutions() subj := rejectWhereEmpty("o", solutions) obj := rejectWhereEmpty("s", solutions) data := struct { Title string License, LicenseURL string Endpoint string Name, Version, URI string AsSubject []map[string]interface{} AsObject []map[string]interface{} AsSubjectSize int AsObjectSize int MaxSubject int MaxObject int Images []string }{ findTitle(conf.UI.TitlePredicates, solutions), conf.License, conf.LicenseURL, conf.QuadStore.Endpoint, "Fenster", string(version), uri, subj, obj, len(subj) - 1, len(obj) - 1, maxS, maxO, findImages(conf.UI.ImagePredicates, solutions), } buf := bufpool.Get() defer bufpool.Put(buf) err = templates.ExecuteTemplate(buf, "index.html", data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(http.StatusOK) buf.WriteTo(w) }