JackRabbit On WebLogic
Applies to versions
WebLogic 8.1 SP4
Oracle 9i
Setting up JNDI in JackRabbit
<FileSystem class="org.apache.jackrabbit.core.fs.db.JNDIOracleDatabaseFileSystem">
<param name="path" value="${rep.home}"/>
<param name="dataSourceLocation" value="jdbc/jcr"/>
<param name="checkValidConnectionSQL" value="select 0 from dual" />
<param name="schemaObjectPrefix" value="default"/>
<param name="schema" value="oracle" />
</FileSystem>
<PersistenceManager class="org.apache.jackrabbit.core.state.db.JNDIOracleDatabasePersistenceManager">
<param name="path" value="${wsp.home}/db"/>
<param name="dataSourceLocation" value="jdbc/jcr"/>
<param name="checkValidConnectionSQL" value="select 0 from dual" />
<param name="schemaObjectPrefix" value="pm_def"/>
<param name="schema" value="oracle" />
<param name="externalBLOBs" value="false"/>
</PersistenceManager>
With Oracle you need an OracleConnection to be able to use Oracle extensions such as BLOB, Struct etc.
For Oracle support with JNDI a new classes are implemented: JNDIOracleDatabaseFileSystem and JNDIOracleDatabasePersistenceManager. The code for these classes stored on the ExamplesPage -> see the patch included on that page.
Configuring WebLogic
Use the default Oracle driver
Configure a datasource
create a JNDI name
now webLogic will return a wrapper DataSource for Oracle from which Jackrabbit can use Oracle extensions
Using WebDAV
No special configuration is needed for using WebDAV
jackrabbit on WLP
Download Jackrabbit JCA Resource Adapter (e.g. jackrabbit-jca-1.3.1.rar ) from -
http://jackrabbit.apache.org/downloads.html Explode the rar
* put jars in system class path (this is architecturally unsound, use RMI appraoch for real world application)
* put only the MANIFEST.MF, ra.xml & weblogic-ra.xml in autodeploy/jackrabbit-jca-1.3.1/META-INF dir (WLS Console doesn't seem to work well with .rar files)
modify ra.xml to point to repository directory & repository.xml (repository must be in domain root or BEA_HOME)
Sample ra.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Sample ra.xml
-->
<connector xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
version="1.5">
<display-name>Jackrabbit JCR Adapter</display-name>
<vendor-name>Apache.org</vendor-name>
<eis-type>JCR Adapter</eis-type>
<resourceadapter-version>1.0</resourceadapter-version>
<resourceadapter>
<resourceadapter-class>org.apache.jackrabbit.jca.JCAResourceAdapter</resourceadapter-class>
<outbound-resourceadapter>
<connection-definition>
<managedconnectionfactory-class>org.apache.jackrabbit.jca.JCAManagedConnectionFactory</managedconnectionfactory-class>
<config-property>
<config-property-name>HomeDir</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>
@DOMAIN_HOME/jackrabbit
</config-property-value>
</config-property>
<config-property>
<config-property-name>ConfigFile</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>
@DOMAIN_HOME/jackrabbit/repository.xml
</config-property-value>
</config-property>
<connectionfactory-interface>javax.jcr.Repository</connectionfactory-interface>
<connectionfactory-impl-class>org.apache.jackrabbit.jca.JCARepositoryHandle</connectionfactory-impl-class>
<connection-interface>javax.jcr.Session</connection-interface>
<connection-impl-class>org.apache.jackrabbit.jca.JCASessionHandle</connection-impl-class>
</connection-definition>
<transaction-support>XATransaction</transaction-support>
<reauthentication-support>false</reauthentication-support>
</outbound-resourceadapter>
</resourceadapter>
</connector>
Sample weblogic-ra.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-connection-factory-dd SYSTEM "http://www.bea.com/servers/wls810/dtd/weblogic810-ra.dtd" >
<!--
Sample weblogic-ra.xml
-->
<weblogic-connection-factory-dd>
<connection-factory-name>contentRepository</connection-factory-name>
<jndi-name>repository</jndi-name>
<pool-params>
<initial-capacity>10</initial-capacity>
<max-capacity>50</max-capacity>
<capacity-increment>1</capacity-increment>
<shrinking-enabled>true</shrinking-enabled>
<connection-profiling-enabled>true</connection-profiling-enabled>
<shrink-frequency-seconds>5</shrink-frequency-seconds>
<inactive-connection-timeout-seconds>0</inactive-connection-timeout-seconds>
<highest-num-waiters>2147483647</highest-num-waiters>
<highest-num-unavailable>0</highest-num-unavailable>
<connection-creation-retry-frequency-seconds>1</connection-creation-retry-frequency-seconds>
<connection-reserve-timeout-seconds>10</connection-reserve-timeout-seconds>
<test-frequency-seconds>0</test-frequency-seconds>
<match-connections-supported>true</match-connections-supported>
</pool-params>
</weblogic-connection-factory-dd>
write scripting to map dirs to local system
add entry to content-config.xml
Sample content-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<content-config xmlns="http://www.bea.com/ns/portal/90/content-config">
<!--
Sample content-config.xml
-->
<content-store>
<!-- ... snipped for brevity ... -->
</content-store>
<content-store>
<name>Jackrabbit</name>
<description>Jackrabbit JNDI Content Repository Configuration</description>
<class-name>com.day.content.spi.jsr170.JNDIRepository</class-name>
<repository-property>
<description>JSR-170 Repository Workspace</description>
<name>jsr170.workspace</name>
<value>jackrabbit</value>
</repository-property>
<repository-property>
<description>JSR-170 Repository JNDI name</description>
<name>jsr170.jndi.name</name>
<value>repository</value>
</repository-property>
<read-only>false</read-only>
<binary-cache-max-entry-size>1024</binary-cache-max-entry-size>
<search-is-enabled>true</search-is-enabled>
<fulltext-search-is-enabled>false</fulltext-search-is-enabled>
<search-indexing-is-enabled>true</search-indexing-is-enabled>
</content-store>
</content-config>
write custom node type def file (cnd)
Sample Custom Node Type Definition File
<nt = 'http://www.jcp.org/jcr/nt/1.0'> <flix = 'http://wlp.bea.com/jcr/1.0/flix'> [flix:MEDIA] > nt:unstructured - flix:TITLE (string) primary mandatory - flix:RELEASE_DATE (long) mandatory - flix:THUMBNAIL (binary) - flix:LENGTH (long) - flix:DIRECTOR (name) mandatory - flix:CAST (name) mandatory multiple - flix:GENRE (string) mandatory multiple < 'Action', 'Comedy', 'Drama', 'Horror', 'Romance', 'Sci-Fi & Fantasy', 'Thrillers' - flix:MEDIA_TYPE (string) = 'DVD' mandatory < 'VHS', 'DVD', 'Blue-Ray', 'HD DVD', 'CD', 'PS3', 'XBOX 360', 'Wii', 'PS2' - flix:IMDB_LINK (string) - flix:QUOTES (string) multiple - flix:SYNOPSIS (string) mandatory - flix:TRAILER_CLIP (binary) - flix:STOCK_STATUS (string) = 'in stock' mandatory < 'unreleased', 'in stock', 'out of stock'
write code against jackrabbit api to create types & content
Sample Type and Node Creation Code
package com.bea.wlp.scenarios.flix.jackrabbit;
import javax.jcr.NamespaceException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.Node;
import javax.jcr.Workspace;
import javax.jcr.Repository;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.apache.jackrabbit.core.TransientRepository;
import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
import org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Iterator;
public class CustomNodeTypeLoader
{
public static final String REPO_JNDI_NAME = "repository";
public static final String CND_FILE_NAME = "/schemas/flixTypes.cnd";
public static final String FLIX_NS_PREFIX = "flix";
public static final String FLIX_NS_URI = "http://wlp.bea.com/jcr/1.0/flix";
public void loadCustomNodeTypes()
{
try
{
InitialContext ctx = new InitialContext();
Repository repository = (Repository)ctx.lookup(REPO_JNDI_NAME);
Session session = repository.login(new SimpleCredentials("weblogic", "weblogic".toCharArray()));
Workspace ws = session.getWorkspace();
NamespaceRegistry nsr = ws.getNamespaceRegistry();
try {
nsr.registerNamespace(FLIX_NS_PREFIX, FLIX_NS_URI);
} catch (NamespaceException e) {
// ignore - implies we've already registered the namespace
} catch (Exception e) {
throw new RuntimeException(e);
}
Reader cndFileReader = new InputStreamReader(this.getClass().getResourceAsStream(CND_FILE_NAME));
// Create a CompactNodeTypeDefReader
CompactNodeTypeDefReader cndReader = new CompactNodeTypeDefReader(cndFileReader, CND_FILE_NAME);
// Get the List of NodeTypeDef objects
List ntdList = cndReader.getNodeTypeDefs();
// Get the NodeTypeManager from the Workspace.
// Note that it must be cast from the generic JCR NodeTypeManager to the
// Jackrabbit-specific implementation.
NodeTypeManagerImpl ntmgr =(NodeTypeManagerImpl)ws.getNodeTypeManager();
// Acquire the NodeTypeRegistry
NodeTypeRegistry ntreg = ntmgr.getNodeTypeRegistry();
// Loop through the prepared NodeTypeDefs
for (Iterator i = ntdList.iterator(); i.hasNext();) {
// Get the NodeTypeDef...
NodeTypeDef ntd = (NodeTypeDef)i.next();
try {
// ...and register it
ntreg.registerNodeType(ntd);
} catch (InvalidNodeTypeDefException e) {
// ignore - implies we've already created the type
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Node rootNode = session.getRootNode();
Node baseNode = rootNode.addNode("Flix Media Auto", "nt:unstructured");
Calendar releaseDate = Calendar.getInstance();
releaseDate.set(2007, 8, 17);
createNode(baseNode, "Superbad", releaseDate, 114, "Greg Mottola", "Jonah Hill", "Comdey", "DVD",
"http://www.imdb.com/title/tt0829482/", "Same-sies!", "Hilarous!", "unreleased");
session.save();
} catch (InvalidNodeTypeDefException e) {
// ignore - implies we've already created everything
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void createNode(Node parentNode, String title, Calendar releaseDate, long length, String director,
String castMember, String genre, String mediaType, String imdbLink, String quote, String synopsis,
String stockStatus)
throws Exception
{
Node newNode = parentNode.addNode(title, "flix:MEDIA");
newNode.setProperty("flix:TITLE", title);
newNode.setProperty("flix:RELEASE_DATE", releaseDate);
newNode.setProperty("flix:LENGTH", length);
newNode.setProperty("flix:DIRECTOR", director);
newNode.setProperty("flix:CAST", castMember);
newNode.setProperty("flix:GENRE", genre);
newNode.setProperty("flix:MEDIA_TYPE", mediaType);
newNode.setProperty("flix:IMDB_LINK", imdbLink);
newNode.setProperty("flix:QUOTES", quote);
newNode.setProperty("flix:SYNOPSIS", synopsis);
newNode.setProperty("flix:STOCK_STATUS", stockStatus);
}
}
add app lifecycle listener or filter to call type creation code
use federated cm api to create and access content (e.g.
http://edocs/wlp/docs100/cm/index.html )
Also see:
http://edocs/wlp/docs100/pdf/day170adapter_developers_guide.pdf