From b6d30091c49f5562cf31e99c6d0bbeaa51693144 Mon Sep 17 00:00:00 2001 From: Shawn Hurley Date: Tue, 12 Sep 2023 15:33:10 -0400 Subject: [PATCH] Adding ability to snip files and make all konveyor-jdt into file URI's --- provider/internal/java/dependency.go | 1 + provider/internal/java/filter.go | 114 +++++++++++++++++++++------ provider/internal/java/snipper.go | 65 ++------------- 3 files changed, 99 insertions(+), 81 deletions(-) diff --git a/provider/internal/java/dependency.go b/provider/internal/java/dependency.go index 40563a3c..76f66df5 100644 --- a/provider/internal/java/dependency.go +++ b/provider/internal/java/dependency.go @@ -373,6 +373,7 @@ func (p *javaServiceClient) initOpenSourceDepLabels() error { if err != nil { return err } + defer file.Close() return loadDepLabelItems(file, p.depToLabels, labels.AsString(provider.DepSourceLabel, javaDepSourceOpenSource)) } diff --git a/provider/internal/java/filter.go b/provider/internal/java/filter.go index 76dc135f..b6371ca6 100644 --- a/provider/internal/java/filter.go +++ b/provider/internal/java/filter.go @@ -1,6 +1,12 @@ package java import ( + "fmt" + "net/url" + "os" + "os/exec" + "path/filepath" + "strconv" "strings" "github.com/konveyor/analyzer-lsp/lsp/protocol" @@ -117,18 +123,11 @@ func (p *javaServiceClient) filterConstructorSymbols(symbols []protocol.Workspac } func (p *javaServiceClient) convertToIncidentContext(symbol protocol.WorkspaceSymbol) (provider.IncidentContext, error) { - var u uri.URI - var err error - - // TODO: Can remove when the LSP starts giving files to decompiled binaries - if strings.HasPrefix(symbol.Location.URI, FILE_URI_PREFIX) { - u = uri.URI(symbol.Location.URI) - } else { - u, err = uri.Parse(symbol.Location.URI) - if err != nil { - return provider.IncidentContext{}, err - } + u, err := p.getURI(symbol.Location.URI) + if err != nil { + return provider.IncidentContext{}, err } + lineNumber := int(symbol.Location.Range.Start.Line) incident := provider.IncidentContext{ FileURI: u, @@ -157,18 +156,11 @@ func (p *javaServiceClient) convertToIncidentContext(symbol protocol.WorkspaceSy } func (p *javaServiceClient) convertSymbolRefToIncidentContext(symbol protocol.WorkspaceSymbol, ref protocol.Location) (provider.IncidentContext, error) { - var u uri.URI - var err error - - // TODO: Can remove when the LSP starts giving files to decompiled binaries - if strings.HasPrefix(symbol.Location.URI, FILE_URI_PREFIX) { - u = uri.URI(symbol.Location.URI) - } else { - u, err = uri.Parse(ref.URI) - if err != nil { - return provider.IncidentContext{}, err - } + u, err := p.getURI(ref.URI) + if err != nil { + return provider.IncidentContext{}, err } + incident := provider.IncidentContext{ FileURI: u, Variables: map[string]interface{}{ @@ -198,3 +190,81 @@ func (p *javaServiceClient) convertSymbolRefToIncidentContext(symbol protocol.Wo return incident, nil } + +func (p *javaServiceClient) getURI(refURI string) (uri.URI, error) { + if !strings.HasPrefix(refURI, FILE_URI_PREFIX) { + return uri.Parse(refURI) + } + + u, err := url.Parse(refURI) + if err != nil { + return uri.URI(""), err + } + + fmt.Printf("\nurl parse result: %#v\n", u) + + //konveyor-jdt:/contents/root/.m2/repository/org/springframework/spring-tx/5.3.7/spring-tx-5.3.7.jar?packageName=org.springframework.jca.cci.connection.CciLocalTransactionManager.class&source-range=true + + // Decompile the jar + sourceRange, err := strconv.ParseBool(u.Query().Get("source-range")) + if err != nil { + // then we got some response that does not make sense or should not be valid + return uri.URI(""), fmt.Errorf("unable to get konveyor-jdt source range query parameter") + } + packageName := u.Query().Get("packageName") + + if sourceRange { + // If there is a source range, we know we know there is a sources jar + jarName := filepath.Base(u.Path) + s := strings.TrimSuffix(jarName, ".jar") + s = fmt.Sprintf("%v-sources.jar", s) + jarPath := filepath.Join(filepath.Dir(u.Path), s) + + path := filepath.Join(strings.Split(strings.TrimSuffix(packageName, ".class"), ".")...) + + javaFileName := fmt.Sprintf("%s.java", filepath.Base(path)) + if i := strings.Index(javaFileName, "$"); i > 0 { + javaFileName = fmt.Sprintf("%v.java", javaFileName[0:i]) + } + + javaFileAbsolutePath := filepath.Join(filepath.Dir(jarPath), filepath.Dir(path), javaFileName) + + if _, err := os.Stat(javaFileAbsolutePath); err != nil { + cmd := exec.Command("jar", "xf", filepath.Base(jarPath)) + cmd.Dir = filepath.Dir(jarPath) + err := cmd.Run() + if err != nil { + fmt.Printf("\n java error%v", err) + return "", err + } + } + + fmt.Printf("\npath: %v\n absPath: %v", u.Path, javaFileAbsolutePath) + return uri.File(javaFileAbsolutePath), nil + } else { + jarName := filepath.Base(u.Path) + jarPath := filepath.Join(filepath.Dir(u.Path), jarName) + + path := filepath.Join(strings.Split(strings.TrimSuffix(packageName, ".class"), ".")...) + + javaFileName := fmt.Sprintf("%s.java", filepath.Base(path)) + if i := strings.Index(javaFileName, "$"); i > 0 { + javaFileName = fmt.Sprintf("%v.java", javaFileName[0:i]) + } + + javaFileAbsolutePath := filepath.Join(filepath.Dir(jarPath), filepath.Dir(path), javaFileName) + + if _, err := os.Stat(javaFileAbsolutePath); err != nil { + cmd := exec.Command("jar", "xf", filepath.Base(jarPath)) + cmd.Dir = filepath.Dir(jarPath) + err := cmd.Run() + if err != nil { + fmt.Printf("\n java error%v", err) + return "", err + } + } + } + + return uri.New(refURI), nil + +} diff --git a/provider/internal/java/snipper.go b/provider/internal/java/snipper.go index 79c09c51..2ffeb7f5 100644 --- a/provider/internal/java/snipper.go +++ b/provider/internal/java/snipper.go @@ -4,8 +4,6 @@ import ( "bufio" "fmt" "os" - "os/exec" - "path/filepath" "strconv" "strings" @@ -20,66 +18,15 @@ const ( var _ engine.CodeSnip = &javaProvider{} func (p *javaProvider) GetCodeSnip(u uri.URI, loc engine.Location) (string, error) { - ur := string(u) - if !strings.Contains(ur, FILE_URI_PREFIX) { - return "", fmt.Errorf("invalid uri, must be for %s", FILE_URI_PREFIX) + if !strings.Contains(string(u), uri.FileScheme) { + return "", fmt.Errorf("invalid file uri, must be for %s", FILE_URI_PREFIX) } - ur = strings.TrimPrefix(ur, fmt.Sprintf("%s://contents", FILE_URI_PREFIX)) - - parts := strings.Split(ur, "?") - if len(parts) != 2 { - return "", fmt.Errorf("invalid uri, can not find correct query string") - } - path := parts[0] - queryString := parts[1] - - queryStringParts := strings.Split(queryString, "&") - if len(queryStringParts) != 2 { - return "", fmt.Errorf("invalid uri, can not find correct parts for query string") - } - - packageName := strings.Split(queryStringParts[0], "=")[1] - sourceRange := strings.Split(queryStringParts[1], "=")[1] - isSourceRange, err := strconv.ParseBool(sourceRange) + snip, err := p.scanFile(u.Filename(), loc) if err != nil { - return "", fmt.Errorf("invalid boolean set for source range") - } - - if isSourceRange { - // If there is a source range, we know we know there is a sources jar - jarName := filepath.Base(path) - s := strings.TrimSuffix(jarName, ".jar") - s = fmt.Sprintf("%v-sources.jar", s) - jarPath := filepath.Join(filepath.Dir(path), s) - - path := filepath.Join(strings.Split(strings.TrimSuffix(packageName, ".class"), ".")...) - - javaFileName := fmt.Sprintf("%s.java", filepath.Base(path)) - if i := strings.Index(javaFileName, "$"); i > 0 { - javaFileName = fmt.Sprintf("%v.java", javaFileName[0:i]) - } - - javaFileAbsolutePath := filepath.Join(filepath.Dir(jarPath), filepath.Dir(path), javaFileName) - - if _, err := os.Stat(javaFileAbsolutePath); err != nil { - cmd := exec.Command("jar", "xf", filepath.Base(jarPath)) - cmd.Dir = filepath.Dir(jarPath) - err := cmd.Run() - if err != nil { - fmt.Printf("\n java%v", err) - return "", err - } - } - - snip, err := p.scanFile(javaFileAbsolutePath, loc) - if err != nil { - fmt.Printf("\n%v", err) - return "", err - } - return snip, nil + fmt.Printf("\n%v", err) + return "", err } - - return "", nil + return snip, nil } func (p *javaProvider) scanFile(path string, loc engine.Location) (string, error) {