# ContentService usage

**URL:** <https://community.developer.atlassian.com/t/contentservice-usage/7220>\
**Category:** Bitbucket Server\
**Tags:** contentservice, bitbucket-server, java\
**Created:** [August 9, 2017, 5:27pm UTC](https://community.developer.atlassian.com/t/contentservice-usage/7220 "2017-08-09T17:27:58Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![srand](https://avatars.discourse-cdn.com/v4/letter/s/ee7513/32.png) [@srand](https://community.developer.atlassian.com/u/srand)\
**Post date:** [August 9, 2017, 5:27pm UTC](https://community.developer.atlassian.com/t/contentservice-usage/7220/1 "2017-08-09T17:27:58Z")

</div>

Hey all,

I am working on a script that will utilize the ContentService class. In particular, the streamDirectory() method.

My usage is as follows:

```auto
def repo = repositoryService.getById(1930)
def callback = new AbstractContentTreeCallback()
contentService.streamDirectory(repo,"patch","files",false,callback,pageReq)

```

Syntax wise, this is correct. However I do not understand how to actually see the data that is returned. The API states that streamDirectory() calls methods for the AbstractContentTreeCallback object I pass in. The streamDirectory() method itself does not return anything.

I think I am not understanding the “callback” terminology in a Java sense. I’ve seen callbacks in javascript but not in Java.

Has anyone been successful with this class before?

---

<div class="post-metadata">

**Author:** ![bplump](https://sea1.discourse-cdn.com/atlassiandeveloper/user_avatar/community.developer.atlassian.com/bplump/32/41448_2.png) [@bplump](https://community.developer.atlassian.com/u/bplump)\
**Post date:** [August 9, 2017, 10:48pm UTC](https://community.developer.atlassian.com/t/contentservice-usage/7220/2 "2017-08-09T22:48:54Z")

</div>

`AbstractContentTreeCallback` doesn’t actually do anything, you need to extend it. You might want to start by writing a subclass that calls `System.out.println` for each method, so you can understand when the methods will be called and what data they get passed.

---

<div class="post-metadata">

**Author:** ![srand](https://avatars.discourse-cdn.com/v4/letter/s/ee7513/32.png) [@srand](https://community.developer.atlassian.com/u/srand)\
**Post date:** [August 10, 2017, 11:44am UTC](https://community.developer.atlassian.com/t/contentservice-usage/7220/3 "2017-08-10T11:44:30Z")

</div>

Ahhhhh that makes sense. Thanks Brent.

I will go ahead and try that out and report back.

---

<div class="post-metadata">

**Author:** ![srand](https://avatars.discourse-cdn.com/v4/letter/s/ee7513/32.png) [@srand](https://community.developer.atlassian.com/u/srand)\
**Post date:** [August 10, 2017, 1:24pm UTC](https://community.developer.atlassian.com/t/contentservice-usage/7220/4 "2017-08-10T13:24:57Z")

</div>

EDIT: I got it. Added a few methods in my extended class to store data that was returned.

So, here is my updated code:

```auto
public class MyContentTreeCallback extends AbstractContentTreeCallback {
    
    ArrayList<String> files = new ArrayList<String>()
    Logger log;
    ContentTreeSummary fileSummary;
    public MyContentTreeCallback() {
        log = Logger.getLogger("com.onresolve.jira.groovy")
    log.setLevel(Level.DEBUG)
    }
    
    @Override
    public void onEnd(@Nonnull ContentTreeSummary summary) {
        log.debug(summary)
        fileSummary = summary
        log.debug("hello world")
    }
    
  @Override
    public void onStart(@Nonnull ContentTreeContext context) {
       log.debug(context)
       log.debug("hello world")
       
    }
    
  @Override
    public boolean onTreeNode(@Nonnull ContentTreeNode node) {
       
       String filePath = ""
       if(node.getPath().getComponents().size()>1){
            for(int i=0;i<node.getPath().getComponents().size();i++){
              filePath+=node.getPath().getComponents()[i]+"/"
                //filePath=filePath.substring(0,filePath.length() - 1)
          }
       } else {
           filePath+=node.getPath().getName()
       }
       
       String lastChar = filePath.charAt(filePath.length() - 1)
       if(lastChar.equals("/")){
           filePath=filePath.substring(0,filePath.length() - 1)
       }
       files.add(filePath)
       return true;
      
    }

    public ArrayList<String> getFiles(){
        return files
    }
    
}
//further down the file......
def repo = repositoryService.getById(1930)
MyContentTreeCallback callback = new MyContentTreeCallback()
contentService.streamDirectory(repo,"release/production","",true,callback,pageReq);

ArrayList<String> repoFiles = callback.getFiles()

```

Thanks @bplump
