001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.jdbc; 017 018import java.sql.DriverManager; 019import java.sql.SQLException; 020import javax.jcr.Repository; 021import org.modeshape.jdbc.delegate.HttpRepositoryDelegate; 022 023/** 024 * A JDBC driver implementation that is able to access a JCR repository to query its contents using JCR-SQL2. <h3>Connection URLs</h3> 025 * <p> 026 * The driver accepts several URL formats based on how the repository is configured: 027 * <ol> 028 * <li>configured for <i>local</i> access using JNDI 029 * 030 * <pre> 031 * jdbc:jcr:jndi:{jndiName} 032 * </pre> 033 * 034 * or 035 * 036 * <pre> 037 * jdbc:jcr:jndi:{jndiName}?{firstProperty}&{secondProperty}&... 038 * </pre> 039 * 040 * where 041 * <ul> 042 * <li><strong>{jndiName}</strong> is the JNDI name where the {@link Repository} or {@literal org.modeshape.jcr.api.Repositories} 043 * instance can be found;</li> 044 * <li><strong>{firstProperty}</strong> consists of the first property name followed by '=' followed by the property's value;</li> 045 * <li><strong>{secondProperty}</strong> consists of the second property name followed by '=' followed by the property's value;</li> 046 * </ul> 047 * Note that any use of URL encoding ('%' followed by a two-digit hexadecimal value) will be decoded before being used. 048 * </p> 049 * <p> 050 * Here's an example of a URL that defines a {@link Repository} instance located at "<code>jcr/local</code>" with a repository 051 * name of "repository" and a user, password of "secret", and workspace name of "My Workspace": 052 * 053 * <pre> 054 * jdbc:jcr:jndi:jcr/local?repositoryName=repository&user=jsmith&password=secret&workspace=My%20Workspace 055 * </pre> 056 * 057 * The "repository" property is required only if the object in JNDI is a {@literal org.modeshape.jcr.api.Repositories} object. <br /> 058 * <br /> 059 * </p> 060 * <li>configured for <i>remote</i> access using REST interface. 061 * 062 * <pre> 063 * jdbc:jcr:http://{hostname}:{port}?{firstProperty}&{secondProperty}&... 064 * </pre> 065 * 066 * where 067 * <ul> 068 * <li><strong>{hostname}</strong> is the host name where the {@link Repository} or {@literal org.modeshape.jcr.api.Repositories} 069 * instance can be found;</li> 070 * <li><strong>{port}</strong> is the port to access the {@link Repository} or {@literal org.modeshape.jcr.api.Repositories} on 071 * the specified <i>hostname</i>;</li> 072 * <li><strong>{firstProperty}</strong> consists of the first property name followed by '=' followed by the property's value;</li> 073 * <li><strong>{secondProperty}</strong> consists of the second property name followed by '=' followed by the property's value;</li> 074 * </ul> 075 * <p> 076 * Note that any use of URL encoding ('%' followed by a two-digit hexadecimal value) will be decoded before being used. 077 * </p> 078 * </ol> 079 */ 080 081public class JcrDriver extends LocalJcrDriver { 082 083 /* URL Prefix used for remote access */ 084 public static final String HTTP_URL_PREFIX = "jdbc:jcr:http://"; 085 086 static { 087 try { 088 DriverManager.registerDriver(new JcrDriver(null)); 089 } catch (SQLException e) { 090 logger.error(JdbcI18n.driverErrorRegistering, e.getMessage()); 091 } 092 } 093 094 /** 095 * No-arg constructor, required by the {@link DriverManager}. 096 */ 097 public JcrDriver() { 098 this(null); 099 } 100 101 /** 102 * Create an instance of this driver using the supplied JNDI naming context factory. This is useful for testing, but is 103 * otherwise not generally recommended. 104 * 105 * @param namingContextFactory the naming context factory; may be null if one should be created automatically 106 */ 107 protected JcrDriver( JcrContextFactory namingContextFactory ) { 108 super(HttpRepositoryDelegate.FACTORY, new DriverInfo(JdbcI18n.driverName.text(), JdbcI18n.driverVendor.text(), 109 JdbcI18n.driverVendorUrl.text(), JdbcI18n.driverVersion.text()), 110 namingContextFactory); 111 } 112}