ModeShape quickstart tutorial

In this second tutorial about Modeshape we will show how to perform some basic operations with a ModeShape JCR repository such as storing binary files (images) and retrieving them.

 Modeshape is a lightweight, fast, pluggable, open-source JCR repository that federates and unifies content from multiple systems, including files systems, databases, data grids, other repositories, etc.

Getting started!

In order to get started with ModeShape you are strongly encouraged to use Maven. In your pom.xml you have to specify at least the following elements:
1. At first add dependenciesManagement the Bill of Materials related to ModeShape so you don't have to specify the versions of any of the ModeShape dependencies:

<dependencyManagement>
  <dependencies>

    <dependency>
      <groupId>org.modeshape.bom</groupId>
      <artifactId>modeshape-bom-embedded</artifactId>
      <version>3.1.1.Final</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

2. The only mandatory module that you need to include is the primary JCR implementation required for the ModeShape engine
<dependency>
  ...
  <dependency>
    <groupId>org.modeshape</groupId>
    <artifactId>modeshape-jcr</artifactId>
  </dependency>
  ...
</dependencies>

3. Then, if you are using ModeShape's public API (instead of just the JCR API) you should also include this dependency:
<dependency>
  <groupId>org.modeshape</groupId>
  <artifactId>modeshape-jcr-api</artifactId>
</dependency>

4. Finally, you need to include JBoss' nexus repository in order to reach ModeShape API:
<repositories>
        <repository>
            <id>JBoss-Releases</id>
            <url>https://repository.jboss.org/nexus/content/repositories/releases/</url>
        </repository>
</repositories>

Creating your first ModeShape application
The first thing we will add, before digging into ModeShape API is creating a repository configuration. The configuration can be arranged either programmatically or using a file. If you are using a file you will need to use, (since ModeShape 3.0) the JSON format:
{
    "name" : "My Repository",
    "workspaces" : {
        "predefined" : ["otherWorkspace"],
        "default" : "default",
        "allowCreation" : true
    },
    "security" : {
        "anonymous" : {
            "roles" : ["readonly","readwrite","admin"],
            "useOnFailedLogin" : false
        }
    }
 }
 

The  above configuration contains just a definition of the default workspace and the security provider to be used in order to access the JCR repository. The anonymous provider is enabled by default and always is the last provider to be consulted. It authenticates all users with read and write permission by default, although the exact roles (either "read", "readwrite", or "admin") can be configured with the "roles" field;

A first taste of ModeShape

Our first example will illustrate how to store some nodes in the Repository, using a J2SE standalone application. Then we will associate some content with that node. Once stored, some meaningful information is extracted from the file

Step #1:  Create and start the ModeShape engine

ModeShapeEngine engine = new ModeShapeEngine();
engine.start();

Step #2: Load the configuration for a repository via the classloader, validate the configuration and deploy the repository
Repository repository = null;
String repositoryName = null;
try {
    URL url = ModeShapeExample.class.getClassLoader().getResource("my-repository-config.json");
    RepositoryConfiguration config = RepositoryConfiguration.read(url);

    // Verify the configuration for the repository ...
    Problems problems = config.validate();
    if (problems.hasErrors()) {
        System.err.println("Problems starting the engine.");
        System.err.println(problems);
        System.exit(-1);
    }

    // Deploy the repository ...
    repository = engine.deploy(config);
    repositoryName = config.getName();
} catch (Throwable e) {
    e.printStackTrace();
    System.exit(-1);
    return;
}

Step 3#: Obtain a JCR repository.

As you can see, obtaining a JCR Repository instance is a matter of simply asking the engine for it by the name defined in the configuration:

Session session = null;
JcrTools tools = new JcrTools();

repository = engine.getRepository(repositoryName);

Step 4#: Creates a Session using the login method.

The login() method allows the implementation to choose its own security context to create a session in the default workspace for the repository.


session = repository.login("default");

Step 5#: Store nodes into the Repository!


We will create a root node from the session and add nodes to it : the node type nt:folder is used to represent folder-type nodes, while the node nt:file is used to contain a represent a file name. Beneath the nt:file an nt:resource Node is added to host the Image binary file.

// Create the '/files' node that is an 'nt:folder' ...
Node root = session.getRootNode();

Node filesNode = root.addNode("files", "nt:folder");

InputStream stream =
    new BufferedInputStream(new FileInputStream("C:\\modeshape-basic-example\\src\\main\\resources\\modeshape_logo.jpg"));

// Create an 'nt:file' node at the supplied path ...
Node fileNode = filesNode.addNode("modeshape_logo.jpg","nt:file");


// Upload the file to that node ...
Node contentNode = fileNode.addNode("jcr:content", "nt:resource");
Binary binary = session.getValueFactory().createBinary(stream);
contentNode.setProperty("jcr:data", binary);

session.save();

Here's the tree view of your Repository so far:

/ jcr:primaryType=mode:root jcr:uuid=/
   jcr:system jcr:primaryType=mode:system
   . . . . . . . .
   files jcr:primaryType=nt:folder
     - jcr:created=2013-02-21T11:11:22.599+01:00
     - jcr:createdBy="<anonymous>"
     modeshape_logo.jpg jcr:primaryType=nt:file
       - jcr:created=2013-02-21T11:11:22.599+01:00
       - jcr:createdBy="<anonymous>"
       jcr:content jcr:primaryType=nt:resource
         - jcr:data=binary (3,20KB, SHA1=4ba33d3d58c62ae8bf8cbf5290745067cedd2a79)
         - jcr:lastModified=2013-02-21T11:11:22.599+01:00
         - jcr:lastModifiedBy="<anonymous>"  

 Step 6#: Retrieve nodes from the Repository!
Once saved the session, the auto-created properties will be added as well. Retrieving the nodes and the binary content is a piece of cake. All you need to do is referencing the node which has been stored in the "/files/modeshape_logo.jpg" path. Once that you have got the node, you will be also able to dig into the jcr:content sub-Node which contains the Binary data.

The Binary content is downloaded from the node using the getProperty method show shown. Finally, the InputStream is displayed in a JLabel on the screen!

Node doc = session.getNode("/files/modeshape_logo.jpg");
Node imageContent = doc.getNode("jcr:content");
Binary content = imageContent.getProperty("jcr:data").getBinary();
InputStream is = content.getStream();

 

Image image = ImageIO.read(is);

JFrame frame = new JFrame();
JLabel label = new JLabel(new ImageIcon(image));
frame.getContentPane().add(label, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);

tools.printSubgraph(root);

is.close();

A final notice: pay attention to the useful printSubgraph method, which is from the JcrTools class and displays the content of the repository (node names and attributes) - quite useful for debugging!

Download the example code


Advertisement