Skip to content

Commit

Permalink
Do something different to get the Ruby script wired in appropriately.
Browse files Browse the repository at this point in the history
The previous attempt failed because:

- Modeshape wants all Sequencers to extend the abstract class
  ...sequencer.Sequencer.
- JRuby wants all Ruby -> Java classes to extend RubyObject
- Java doesn't do multiple inheritence.

(Modeshape might be adapted to use a Sequencer interface?)

This attempt:

- Creates a Shim class that extends Sequencer
- Uses the ScriptEngineManager to parse our ruby file, and instantiate our
class
- Calls our Ruby #execute method

So, all is well in the world, I guess.
  • Loading branch information
cbeer committed Feb 10, 2013
1 parent ce8a795 commit fbea381
Show file tree
Hide file tree
Showing 13 changed files with 287 additions and 73 deletions.
29 changes: 0 additions & 29 deletions fcrepo-sequencer-ruby-example/assembly.xml

This file was deleted.

48 changes: 26 additions & 22 deletions fcrepo-sequencer-ruby-example/pom.xml
Expand Up @@ -36,30 +36,34 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>


<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>

<dependency>
<groupId>org.fcrepo</groupId>
<artifactId>fcrepo-kernel</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>de.saumya.mojo</groupId>
<artifactId>jruby-maven-plugin</artifactId>
<version>0.29.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<generateJava>true</generateJava>
<generatedJavaDirectory>${jruby.generated.sources}</generatedJavaDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>


</project>
@@ -0,0 +1,6 @@
package org.fcrepo;


public interface JrubySequencerShim {
public boolean execute(javax.jcr.Property property, javax.jcr.Node node, org.modeshape.jcr.api.sequencer.Sequencer.Context context);
}
@@ -0,0 +1,30 @@
package org.fcrepo;

import org.modeshape.jcr.api.sequencer.Sequencer;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.*;

public class JrubyShimSequencer extends Sequencer {

private String rubyFile = "/reverse_content_sequencer.rb";

@Override
public boolean execute(Property property, Node node, Context context) throws Exception {


ScriptEngine jruby = new ScriptEngineManager().getEngineByName("jruby");

InputStream in = JrubyShimSequencer.class.getResourceAsStream(rubyFile);
Reader r = new InputStreamReader(in, "UTF-8");

jruby.eval(new BufferedReader(r));

JrubySequencerShim s = (JrubySequencerShim) jruby.eval("ReverseContentSequencer.new");

return s.execute(property, node, context);
}
}
@@ -0,0 +1,19 @@
require 'java'

java_import 'org.modeshape.jcr.api.sequencer.Sequencer'
java_package 'org.fcrepo'
java_import org.modeshape.jcr.api.JcrTools


class ReverseContentSequencer
include org.fcrepo.JrubySequencerShim;

def execute property, outputNode, context

n = outputNode.addNode("reversed-content", "nt:resource")
n.setProperty("jcr:data", property.getString().reverse )

return true
end

end
16 changes: 0 additions & 16 deletions fcrepo-sequencer-ruby-example/src/main/ruby/test.rb

This file was deleted.

@@ -1,17 +1,49 @@
package org.fcrepo;

import org.junit.Test;
import org.fcrepo.FcrepoSequencerRubyExample;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static junit.framework.Assert.assertTrue;
import javax.inject.Inject;
import javax.jcr.*;

import java.io.ByteArrayInputStream;

import static java.lang.Thread.sleep;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/spring-test/master.xml"})
public class TestJrubySequencerExample {

@Inject
private Repository repository;



@Test
public void testJrubySequencerJavaClass() {
FcrepoSequencerRubyExample zz = new FcrepoSequencerRubyExample();
Boolean b = zz.execute(null, null, null);
assertTrue(b);
public void testJrubySequencerJavaClass() throws RepositoryException, InterruptedException {

Session session = repository.login();
Node root = session.getRootNode().addNode("jruby");
Node n = root.addNode("should-be-decorated.example");
n.addNode("jcr:content", "nt:resource").setProperty("jcr:data", "asdf");

session.save();
session.logout();

// HA!
sleep(10000);

session = repository.login();

Node ni = session.getRootNode().getNode("jruby").getNode("should-be-decorated.example").getNode("reversed-content");

assertEquals(ni.getProperty("jcr:data").getString(), "fdsa");



}
}
22 changes: 22 additions & 0 deletions fcrepo-sequencer-ruby-example/src/test/resources/logback-test.xml
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n</pattern>
</encoder>
</appender>

<logger name="org.fcrepo" additivity="false" level="DEBUG">
<appender-ref ref="STDOUT"/>
</logger>
<logger name="org.modeshape" additivity="false" level="INFO">
<appender-ref ref="STDOUT"/>
</logger>
<logger name="org.apache.cxf" additivity="false" level="INFO">
<appender-ref ref="STDOUT"/>
</logger>
<root additivity="false" level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:annotation-config/>

</beans>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!-- Master context for the test application. -->

<import resource="classpath:/spring-test/repo.xml"/>
<import resource="classpath:/spring-test/jruby-shim.xml"/>

</beans>
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- Context that supports the actual ModeShape JCR itself -->

<context:annotation-config/>

<bean name="modeshapeRepofactory"
class="org.fcrepo.spring.ModeShapeRepositoryFactoryBean"/>

<bean class="org.modeshape.jcr.JcrRepositoryFactory"/>

<bean class="org.springframework.core.io.ClassPathResource">
<qualifier type="ModeShapeRepositoryConfiguration"/>
<constructor-arg type="String" value="test_repository.json"/>
</bean>


</beans>
@@ -0,0 +1,60 @@
<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.1 http://www.infinispan.org/schemas/infinispan-config-5.1.xsd"
xmlns="urn:infinispan:config:5.1">

<global>
<!-- Defines the global settings shared by all caches -->
</global>

<default>
<!--
Defines the default behavior for all caches, including those created dynamically (e.g., when a
repository uses a cache that doesn't exist in this configuration).
-->
</default>

<namedCache name="FedoraRepository">
<!--
Our Infinispan cache needs to be transactional. However, we'll also configure it to
use pessimistic locking, which is required whenever applications will be concurrently
updating nodes within the same process. If you're not sure, use pessimistic locking.
-->
<transaction
transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
transactionMode="TRANSACTIONAL" lockingMode="PESSIMISTIC"/>
<!--
Define the cache loaders (i.e., cache stores). Passivation is false because we want *all*
data to be persisted, not just what doesn't fit into memory. Shared is false because there
are no other caches sharing this file store. We set preload to false for lazy loading;
may be improved by preloading and configuring eviction.
We can have multiple cache loaders, which get chained. But we'll define just one.
-->
<loaders passivation="false" shared="false" preload="true">

<!--
The 'fetchPersistentState' attribute applies when this cache joins the cluster; the value doesn't
really matter to us in this case. See the documentation for more options.
-->
<loader class="org.infinispan.loaders.file.FileCacheStore" fetchPersistentState="false"
purgeOnStartup="true">
<!-- See the documentation for more configuration examples and flags. -->
<properties>
<!-- We have to set the location where we want to store the data. -->
<property name="location" value="target/FedoraRepository/storage"/>
</properties>
<!-- This repository isn't clustered, so we could set up the SingletonStore.
singletonStore enabled="true" pushStateWhenCoordinator="true" pushStateTimeout="20000"/>
-->
<!--
We could use "write-behind", which actually writes to the file system asynchronously,
which can improve performance as seen by the JCR client.
Plus changes are coalesced, meaning that if multiple changes are enqueued for the
same node, only the last one is written. (This is good much of the time, but not
always.)
<async enabled="true" flushLockTimeout="15000" threadPoolSize="5"/>
-->
</loader>
</loaders>
</namedCache>
</infinispan>
@@ -0,0 +1,39 @@
{
"name" : "repo",
"jndiName" : "",
"workspaces" : {
"predefined" : ["fedora"],
"default" : "fedora",
"allowCreation" : true
},
"storage" : {
"cacheName" : "FedoraRepository",
"cacheConfiguration" : "test_infinispan_configuration.xml",
"binaryStorage" : {
"type" : "cache",
"dataCacheName" : "FedoraRepository",
"metadataCacheName" : "FedoraRepository"
}
},
"security" : {
"anonymous" : {
"roles" : ["readonly","readwrite","admin"],
"useOnFailedLogin" : false
},
"providers" : [
{ "classname" : "servlet" }
]
},
"sequencing" : {
"removeDerivedContentWithOriginal" : true,

"sequencers" : {
"JRuby Visitor" : {
"description" : "Example fcrepo sequencer in JRuby'",
"classname" : "org.fcrepo.JrubyShimSequencer",
"pathExpressions" : ["fedora:/jruby/(.*)[jcr:content/@jcr:data] => fedora:/jruby/$1"]
}
}
},
"node-types" : ["fedora-node-types.cnd"]
}

0 comments on commit fbea381

Please sign in to comment.